diff --git a/README.md b/README.md index 94d3a71..cc4ddfe 100644 --- a/README.md +++ b/README.md @@ -89,7 +89,7 @@ The tag is reserved at the pinned commit before the release is created. A failur ### Testing extensions and styles: `phpbb-test-board/` -Builds a local phpBB 3.3 board on SQLite and tests extensions on it: `smoke_test.py` checks that an extension doesn't break any page, `feature_checks.py` exercises its main feature, and `screenshots.py` takes documentation screenshots of extensions and styles. For local testing only. +Builds a local phpBB 3.3 board on SQLite and tests extensions on it: `smoke_test.py` checks that an extension doesn't break any page, `feature_checks.py` exercises its main feature, and `screenshots.py` takes documentation screenshots of extensions and styles, and `template_a11y.py` checks that icon-only links and buttons have a tooltip and screen-reader text. For local testing only. ```bash phpbb-test-board/setup-board.sh -d ~/phpbb-test-board diff --git a/phpbb-test-board/README.md b/phpbb-test-board/README.md index 6d3156b..19c34ce 100644 --- a/phpbb-test-board/README.md +++ b/phpbb-test-board/README.md @@ -89,6 +89,20 @@ phpbb-test-board/screenshots.py path/to/ProMinoDeux -o path/to/ProMinoDeux/docs/ --seed path/to/seed-forum/bin/seed-standard-fixtures.php ``` +### `template_a11y.py`: labels on icon-only links and buttons + +```bash +phpbb-test-board/template_a11y.py path/to/project [more projects...] +``` + +Scans an extension's or style's templates (`styles/`, `adm/style/`, or a style's `template/`) for links and buttons that show only an icon. Each needs a `title` for the tooltip and screen-reader text, a `` inside it or an `aria-label`, both from a language string: + +```html +{L_CHECK} +``` + +In ACP templates (`adm/style/`) use `aria-label` instead of the span: the ACP style has no `sr-only` class, so the text would show. A `title` on the icon itself, phpBB's ACP pattern, counts as the tooltip, and a link around an image with alt text passes. Problems are printed as `FILE:LINE: message`, and the exit status is 1 if there are any. It needs no board and only Python's standard library. + ## Extensions that need another extension Pass the other extension's checkout with `--with`. Repeat it for several, in the order they must be enabled: diff --git a/phpbb-test-board/template_a11y.py b/phpbb-test-board/template_a11y.py new file mode 100755 index 0000000..fac604b --- /dev/null +++ b/phpbb-test-board/template_a11y.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +""" +Check a phpBB extension's or style's templates for icon-only controls without text. + +Scans every .html template under the given checkouts (styles/ and adm/style/, +or a style's own template/ folder) for links and buttons whose only content +is an icon or image. Each such control needs: + + - a title attribute, for the tooltip sighted mouse users see, and + - screen-reader text: a inside it or an aria-label. + +In ACP templates use aria-label: the ACP style has no sr-only class, so a +span would be visible there. A title on the icon itself, phpBB's ACP +pattern, also counts as the tooltip. +A link around an image with alt text is described by that text and passes. + +Both should come from a language string, not hard-coded text. Template +syntax ({L_FOO}, {{ lang('FOO') }}, , {% if %}) counts as text, so +it works on phpBB 3.3 and Twig templates alike. Uses only the standard +library and needs no test board. + +Output: one line per problem, as FILE:LINE: message. +Exit status: 0 no problems, 1 problems found, 2 bad arguments. +""" +import argparse +import re +import sys +from html.parser import HTMLParser +from pathlib import Path + +CONTROLS = {"a", "button"} +ICON_TAGS = {"i", "img", "svg"} +VOID_TAGS = {"area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "source", "track", "wbr"} +# Template logic that prints nothing: {% ... %}, {# ... #}. +TEMPLATE_LOGIC = re.compile(r"\{%.*?%\}|\{#.*?#\}", re.S) + + +class Control: + """One or ' \ + ' {L_VISIBLE}' \ + '{L_UP}' \ + '{BANNER}' >"$tmp/a11y-good/styles/all/template/good.html" +check "template_a11y.py --help exits 0" exits_with 0 "$tools/template_a11y.py" --help +check "template_a11y.py without arguments exits 2" exits_with 2 "$tools/template_a11y.py" +check "template_a11y.py with a missing directory exits 2" exits_with 2 "$tools/template_a11y.py" "$tmp/no-such-dir" +check "template_a11y.py accepts labelled controls" exits_with 0 "$tools/template_a11y.py" "$tmp/a11y-good" +check "template_a11y.py exits 1 on unlabelled icons" exits_with 1 "$tools/template_a11y.py" "$tmp/a11y-ext" +check "template_a11y.py reports a missing screen-reader text" \ + output_has "bad.html:1: icon-only without screen-reader text" "$tools/template_a11y.py" "$tmp/a11y-ext" +check "template_a11y.py reports a missing tooltip" \ + output_has "bad.html:2: icon-only without a title (tooltip)" "$tools/template_a11y.py" "$tmp/a11y-ext" + if [ "$failures" -eq 0 ]; then echo "All tests passed." else