Aman-Mittal opened a new issue, #234:
URL: https://github.com/apache/fineract-backoffice-ui/issues/234
## Where things stand
Static accessibility linting is already in place and clean.
`eslint.config.js` extends `angular.configs.templateAccessibility`, which
enables all 11 rules (`alt-text`, `click-events-have-key-events`,
`elements-content`, `interactive-supports-focus`,
`label-has-associated-control`, `mouse-events-have-key-events`, `no-autofocus`,
`no-distracting-elements`, `role-has-required-aria`, `table-scope`,
`valid-aria`). They apply to inline templates too, via
`processInlineTemplates`. None are suppressed — `eslint-suppressions.json`
contains no template rules — and `npm run lint` passes.
So the gap is not "no accessibility linting". It is that **static rules
cannot see this application's accessibility**.
The interface is built almost entirely from Ionic web components.
`<ion-button>`, `<ion-input>` and `<ion-select>` render their real interactive
element inside shadow DOM, and their accessible name is computed at runtime
from a mix of attributes, slotted content and Ionic's own internals. A lint
rule reading the template source cannot compute that.
The proof is measurable: **38 icon-only `<ion-button>`s currently have no
accessible name at all**, and lint reports zero errors. See the companion issue
for the list.
## Business value
An accessibility rule that cannot see the components the app is actually
made of gives false assurance — a green CI check that says nothing about
whether the app is usable with a screen reader. That is worse than no check,
because it stops anyone looking.
A runtime check closes the loop: it renders real pages and inspects the
resulting accessibility tree, so it sees what a user's assistive technology
sees, shadow DOM included. It catches the things that matter here and that no
static rule can reach — missing accessible names on custom elements, colour
contrast in the theme, focus order through a dialog, form controls whose label
is not actually associated.
It also stops the problem recurring. The 38 buttons accumulated because
nothing was watching; fixing them without adding the check means they come back.
## Suggested approach
Use `@axe-core/playwright` in the existing Playwright suite. The `mocked`
project is the right place: it needs no backend, already runs on every PR, and
covers a broad set of routes.
```ts
import AxeBuilder from '@axe-core/playwright';
test('dashboard has no serious accessibility violations', async ({ page })
=> {
await login(page);
await page.goto('/dashboard');
const results = await new AxeBuilder({ page })
.withTags(['wcag2a', 'wcag2aa'])
.analyze();
expect(results.violations.filter((v) => ['serious',
'critical'].includes(v.impact ?? ''))).toEqual([]);
});
```
Worth doing:
- **Start with a baseline, not a wall.** Run it across a handful of
representative routes first and see what comes back. If there is a backlog,
record it and fail only on new violations — a check that goes red on day one
and stays red gets ignored.
- **Begin with `serious` and `critical`.** Broaden once those are clean.
- **Cover a form, a list and a dialog** at minimum. They fail in different
ways, and the dialog is where focus-management problems live.
- Attach the violation output to the run so a failure says which element and
which rule, not just a count.
## ASF compliance
This adds an **npm devDependency**, not a GitHub Action, so it does not
touch the ASF third-party Actions allowlist at all — it runs inside the
existing e2e workflow with the runner setup already there.
If a future variant of this wants a third-party action, note that on
`apache/*` repositories anything outside `apache/*`, `github/*` and `actions/*`
is blocked by default, needs an INFRA review to be allowlisted, and must be
pinned to a reviewed commit SHA. This repository already follows that:
`peter-evans/create-pull-request` and `zizmorcore/zizmor-action` are both
SHA-pinned. Sticking to an npm package avoids the question entirely.
## Verifying
```
npm run test:e2e:local -- e2e/<new-spec>.spec.ts
```
Then confirm it actually detects something: temporarily strip `appTooltip`
from an icon button and check the run goes red.
## Picking this up
No need to be assigned — assignment here is limited to committers. Comment
that you are starting, then open a PR.
This is independent of the companion issue that fixes the 38 buttons, and
the two can proceed in parallel — though it is worth agreeing on the baseline
approach before both land, so the check does not go red on work already in
flight.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]