role=linkBug (ENG-1743): Access Engine test 242 (links sharing an accessible name should go to the same place) scoped its candidate set to a[href]:not([href=""])[data-ae_ar="null"][data-ae_vis][data-ae_avat][data-ae_an] — anchors with no ARIA role at all. Any role attribute took the anchor out of scope, including role="link", which does not change what the element is. A pair such as
<a href="foo" role="link">Go to the page</a> and <a href="bar" role="link">Go to the page</a>
was silently skipped and the test reported N/A — a false negative.
Impact: A screen reader user pulling up a list of links sees the same name twice with no way to tell the destinations apart. A redundant role="link" on an anchor is poor practice but not a WCAG failure in itself, and it should not stop the element being tested as the link it is.
A elements with a non-empty href, without an ARIA-assigned role or with role=link, not intentionally hidden in the DOM, available to assistive technologies, with a calculated accessible name./news and https://example.com/news/ count as the same destination.role="button", role="presentation", …) remain out of scope — they are no longer being exposed as links.A with an href carrying a role attribute) on every role="link" case, and test 241 (a suspicious accessible name on a role=link element) on the "Read more" and "View" scenarios.role="link" alongside href, hiding all of the above from the test.data-ae_computed_role, the explicit-or-implicit ARIA role) instead of on the absence of a role:
a[href]:not([href=""])[data-ae_computed_role="link"][data-ae_vis][data-ae_avat][data-ae_an]
href, and an A with an href and no other role already has the implicit role link — so this single selector covers everything the old data-ae_ar="null" selector did, plus an explicit role="link" in any letter case. Nothing else in the test changes: grouping by accessible name and the base-URL href resolution are untouched.
Note: test 242 compares links across the whole page, so each case below uses its own accessible name. Two cases that happened to share a name would form a group of their own and change each other's outcome.
role="button" sharing a name, different hrefs other roleThese are exposed as buttons, not links, so test 242 does not apply. Only role=link (or no role) is in scope. Should not be flagged.
role="link" sharing a name, hidden with display:none hiddenTest 242 only evaluates elements that are not intentionally hidden: the selector requires [data-ae_vis]. Should not be flagged.
role="link" sharing a name, aria-hidden="true" not exposedNot available to assistive technologies, so the selector's [data-ae_avat] requirement excludes them. Should not be flagged.
Same name, same destination — duplication that tells the truth. Should not be flagged.
role="link" sharing a name and an href role=linkNewly in scope after ENG-1743, and compliant. Should not be flagged.
role="link" with distinct names role=linkDifferent destinations, different names. Should not be flagged.
role="link" sharing a name, one relative and one absolute href for the same page url formsThe hrefs resolve to the same URL once the base URL is applied and the trailing slash is ignored (ENG-1729), so the shared name is accurate. Should not be flagged.
role="link" anchors sharing a name, different hrefs role=linkThe markup from ENG-1743: same name, two destinations. Pre-fix: N/A, nothing flagged ❌. Post-fix: both flagged ✓.
role="link" anchor sharing a name, different hrefs mixedPre-fix the role="link" half was invisible, so the remaining link looked unique and neither was reported. Post-fix both are grouped and flagged ✓.
role="LINK" anchors sharing a name, different hrefs caseARIA role tokens are case-insensitive and the computed role is normalised to lower case. Pre-fix: not flagged ❌. Post-fix: flagged ✓.
role="link" anchors sharing a name, different hrefs groupEvery member of a suspicious group is reported, not just the duplicates after the first. Pre-fix: not flagged ❌. Post-fix: all three flagged ✓.
The original test 242 case: an A with an href and no role already has the implicit role link, so the computed-role selector still covers it. Must stay flagged ✓.
The classic case: identical link names, different destinations, no context in the name itself. Pre-fix: not flagged ❌. Post-fix: both flagged ✓.