koddsson / koddsson/accessibility-scanner
error-message rule should exclude elements referenced by aria-controls
- Dominant language
- TypeScript
- Stars
- 11
- Forks
- 2
- Avg merge
- 3d 6h
- Merged PRs (30d)
- 11
Description
## Description
The `error-message` rule flags elements that are clearly interactive UI widgets (disclosure panels, popup menus) as potential unassociated error messages, because it only excludes elements by tag name (`structuralSelector`) or ARIA widget roles (`widgetRoles`).
Elements that are **referenced by `aria-controls`** on a button/trigger should also be excluded, since they are interactive widget targets — not error message containers.
## Example
A disclosure button that toggles a filter panel:
```html
Filters
-
Option 1
-
Option 2
```
The `div#dropdown-menu-filters` gets flagged by the `error-message` rule because:
1. It has an `id`
2. It has text content
3. It's inside a ``
4. It doesn't match `structuralSelector` or have a widget role
5. It isn't referenced by `aria-describedby` or `aria-errormessage`
But it IS referenced by `aria-controls` on the button, which clearly indicates it's an interactive widget target.
## Suggested fix
In `findCandidateErrorElements`, also collect IDs referenced by `aria-controls` and exclude those elements:
```typescript
function collectControlledIds(container: Element): Set {
const ids = new Set();
const allElements = querySelectorAll("[aria-controls]", container);
for (const el of allElements) {
const value = el.getAttribute("aria-controls");
if (value) {
for (const token of value.split(/\s+/)) {
if (token) ids.add(token);
}
}
}
return ids;
}
```
Then in the main function, exclude candidates whose ID appears in the controlled set.
## Related
This is a follow-up to #389 which added widget role exclusions. This addresses the remaining case where the element doesn't have a widget role but is clearly an interactive target.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at findCandidateErrorElements and inspect the existing structuralSelector, widget-role, aria-describedby, and aria-errormessage exclusions. Add coverage for the provided aria-controls disclosure-panel example and verify that controlled elements are no longer reported as error-message candidates.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- accessibility, testing
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100