koddsson / koddsson/accessibility-scanner

error-message rule should exclude elements referenced by aria-controls

Open Beginner friendly
#394 0 comments 0 reactions 0 assignees View on GitHub
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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.