What is being suppressed
e2e/accessibility.spec.ts carries three aria-allowed-attr entries for what is a single upstream defect:
const CLIENT_FORM_BASELINE = new Set([
'aria-allowed-attr|.has-value >> #ion-sel-*',
'aria-allowed-attr|.has-placeholder >> #ion-sel-*',
'aria-allowed-attr|ion-select[name="officeId"] >> #ion-sel-*',
...
plus a fourth in CREATE_OFFICE_DIALOG_BASELINE.
They read as four problems. They are one: ion-select renders its trigger inside the shadow root as a button and reflects the host's required onto it as aria-required, which ARIA does not permit on that role. Three fingerprints exist only because axe picks the shortest unique selector for the host, and the host's state classes move with its value.
Confirmed on main at 3c6d7479 with @ionic/core 8.8.19, reading the shadow root directly on /clients/create:
[
{ "name": "legalFormId", "required": true, "innerRole": "button",
"innerAriaRequired": "true", "hostClasses": "... has-value ..." },
{ "name": "officeId", "required": true, "innerRole": "button",
"innerAriaRequired": "true", "hostClasses": "... has-placeholder ..." }
]
Same element, same attribute, two different host classes — hence two different baseline keys for one bug, and a third for the state where neither class applies.
Why this is worth tracking rather than leaving
The entries are correct today: this is Ionic's markup, not ours, and there is no way to remove the attribute from a shadow root we do not own. But a suppression with no ticket behind it becomes permanent by default. Three of them for one defect also make the baseline look worse than the app is, which pushes the next person to skim the list rather than read it.
More practically: the keys are pinned to axe's selector output, which shifts with the host's state classes. A future change to when a placeholder is set — or an Ionic change to those class names — silently turns a suppression into dead weight while the violation reappears under a fourth fingerprint.
What to do
- Report it upstream against
ionic-team/ionic-framework if it is not already open, and link the issue here. The fix belongs there: either drop aria-required from the inner button, or give that element a role that permits it (combobox is what the trigger actually behaves as).
- Once it is fixed and the version is bumped, delete all four entries together and confirm the suite still passes.
Until then, collapsing the three client-form keys behind one shared constant with a single comment would at least make the count honest about how many defects there are.
Environment
main at 3c6d7479, @ionic/angular / @ionic/core 8.8.19, Chromium via Playwright, against the local docker stack.
What is being suppressed
e2e/accessibility.spec.tscarries threearia-allowed-attrentries for what is a single upstream defect:plus a fourth in
CREATE_OFFICE_DIALOG_BASELINE.They read as four problems. They are one:
ion-selectrenders its trigger inside the shadow root as abuttonand reflects the host'srequiredonto it asaria-required, which ARIA does not permit on that role. Three fingerprints exist only because axe picks the shortest unique selector for the host, and the host's state classes move with its value.Confirmed on
mainat3c6d7479with@ionic/core8.8.19, reading the shadow root directly on/clients/create:[ { "name": "legalFormId", "required": true, "innerRole": "button", "innerAriaRequired": "true", "hostClasses": "... has-value ..." }, { "name": "officeId", "required": true, "innerRole": "button", "innerAriaRequired": "true", "hostClasses": "... has-placeholder ..." } ]Same element, same attribute, two different host classes — hence two different baseline keys for one bug, and a third for the state where neither class applies.
Why this is worth tracking rather than leaving
The entries are correct today: this is Ionic's markup, not ours, and there is no way to remove the attribute from a shadow root we do not own. But a suppression with no ticket behind it becomes permanent by default. Three of them for one defect also make the baseline look worse than the app is, which pushes the next person to skim the list rather than read it.
More practically: the keys are pinned to axe's selector output, which shifts with the host's state classes. A future change to when a placeholder is set — or an Ionic change to those class names — silently turns a suppression into dead weight while the violation reappears under a fourth fingerprint.
What to do
ionic-team/ionic-frameworkif it is not already open, and link the issue here. The fix belongs there: either droparia-requiredfrom the inner button, or give that element a role that permits it (comboboxis what the trigger actually behaves as).Until then, collapsing the three client-form keys behind one shared constant with a single comment would at least make the count honest about how many defects there are.
Environment
mainat3c6d7479,@ionic/angular/@ionic/core8.8.19, Chromium via Playwright, against the local docker stack.