ENG-1746: Test 141 False Negative on A Elements with role=link

Bug (ENG-1746): Access Engine test 141 (an A element's href must not point directly at an image file) scoped its candidate set to a[data-ae_ar='null'][data-ae_vis][data-ae_avat] — 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. Markup such as <a href="foo.jpeg" role="link">Testing this out</a> was silently skipped — a false negative.

Impact: Following such a link replaces the page with a bare image that has no accessible name, no page title and no way back other than the browser's back button. Those links went unreported whenever the anchor also spelled out role="link".

Test Logic (test 141):

Common Scenarios:

Fix: Match on the computed-role attribute added in ENG-1730 (data-ae_computed_role, the explicit-or-implicit ARIA role) instead of on the absence of a role:

a[data-ae_computed_role='link'][data-ae_vis][data-ae_avat]

Every selector in this test requires an href, and an A with an href and no other role already has the implicit role link — so the single computed-role selector covers everything the old data-ae_ar='null' selector did, plus an explicit role="link" in any letter case and role lists whose first valid token is link (role="foo link"). The per-extension selector list is now generated from the extension array rather than written out sixteen times.
N/A — out of scope
PASS — not flagged (correct)
FAIL — flagged (correct; the role=link cases are the ENG-1746 repro, the rest are regression guards)

N/A Tests — Test 141 Does Not Apply

Anchor with role="button" and an image href other role

Test

The anchor is exposed as a button, not a link, so test 141 does not apply. Only role=link (or no role) is in scope. Should not be flagged.

Anchor with role="img" and an image href other role

Test

An anchor exposed as an image is out of scope for this test, unchanged by ENG-1746. Should not be flagged.

Anchor with role="link" hidden with display:none hidden

(Anchor is present but hidden via display:none.)

Test 141 only evaluates elements that are not intentionally hidden: the selector requires [data-ae_vis]. Should not be flagged.

Anchor with role="link" and aria-hidden="true" not exposed

Not available to assistive technologies, so the selector's [data-ae_avat] requirement excludes it. Should not be flagged.

PASS Tests — In Scope, No Violation

Baseline: role-less anchor pointing at a page no role

Test

In scope, but the target is a page, not an image file. Should not be flagged.

Anchor with role="link" pointing at a page role=link

Test

Newly in scope after ENG-1746, and compliant. Should not be flagged.

Anchor with role="link" naming an image in a query string query string

Test

A viewer page that merely names an image is deliberately excluded — the selector rejects any href containing ?. Should not be flagged.

Anchor with role="link" whose path contains .htm .htm path

Test

The :not([href*='.htm']) exclusion keeps page paths that end in an image-looking segment out of the result. Should not be flagged.

FAIL Tests — Correctly Flagged

ENG-1746 repro cases — missed before the fix

Ticket repro: role="link" anchor with an href ending in .jpeg role=link

Testing this out

The markup from ENG-1746. Pre-fix: not flagged ❌. Post-fix: flagged ✓.

Uppercase role="LINK" anchor with an href ending in .gif case

Test

ARIA role tokens are case-insensitive and the computed role is normalised to lower case. Pre-fix: not flagged ❌. Post-fix: flagged ✓.

role="link" anchor with an upper case extension .PNG extension case

Test

Each extension is matched in both letter cases, as attribute value matching is case sensitive. Pre-fix: not flagged ❌. Post-fix: flagged ✓.

Multi-token role="foo link" anchor with an image href token list

Test

Browsers skip unknown tokens and use the first valid one, so this element is a link. The computed role resolves to link even though the recorded data-ae_ar is foo. Pre-fix: not flagged ❌. Post-fix: flagged ✓. (Tests 37 and 412 also flag this element for the invalid foo token — expected and unrelated to test 141.)

Regression guard — flagged before and after the fix

Role-less anchor with an image href no role

Test

The original test 141 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 ✓.

Real-World Scenarios

Gallery thumbnail linking straight to the full-size file role=link

A goat on a hillside

Following this leaves the site for a bare image with no title and no way back. Pre-fix: not flagged ❌. Post-fix: flagged ✓.

"Download the chart" link pointing at a bare .png role=link

Download the chart

A common documentation pattern where the image is the destination rather than the content of a page. Pre-fix: not flagged ❌. Post-fix: flagged ✓.