ENG-1744: Test 220 False Negative on A Elements with role=link

Bug (ENG-1744): Access Engine test 220 (a target="_blank" link should warn that it opens a new window) scoped its candidate set to a[data-ae_vis][data-ae_avat][data-ae_ar="null"][target="_blank"] — 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" target="_blank" role="link">Testing this out</a> was silently skipped — a false negative.

Impact: A screen reader user following an unannounced target="_blank" link lands in a new window with no back history and no announcement of the context change. Those links went unreported whenever the anchor also spelled out role="link".

Test Logic (test 220):

Common Scenarios:

Fix: Extend the candidate set with the computed-role attribute added in ENG-1730 (data-ae_computed_role, the explicit-or-implicit ARIA role):

a[data-ae_vis][data-ae_avat][data-ae_ar="null"][target="_blank"], a[data-ae_vis][data-ae_avat][data-ae_computed_role="link"][target="_blank"]

The original data-ae_ar="null" branch is retained so role-less anchors stay in scope exactly as before. The test also needed a second change to avoid trading a false negative for a false positive: accessible descriptions were only calculated for a[target='_blank']:not([data-ae_ar]), so a newly in-scope role="link" anchor would have carried no description and a warning supplied by title would have been invisible to the test. That markdown step now selects a[target='_blank']:not([data-ae_ar]), a[target='_blank'][data-ae_ar='link'], mirroring the scope already used for accessible names.
N/A — out of scope
PASS — not flagged (correct)
FAIL — flagged (correct; the role=link cases are the ENG-1744 repro, the rest are regression guards)

N/A Tests — Test 220 Does Not Apply

Anchor with role="button" and target="_blank", no warning other role

Hello

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

Anchor with role="presentation" and target="_blank", no warning other role

Hello

An explicit presentational role removes the link semantics the test is about. Out of scope, unchanged by ENG-1744. Should not be flagged.

Anchor with role="link" and no target attribute no target

Hello

No new window is opened, so there is nothing to warn about. Should not be flagged.

Anchor with role="link" and target="_blank" hidden with display:none hidden

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

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

Anchor with role="link", target="_blank" 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, Warning Present

Baseline: role-less anchor whose text carries the warning no role

Hello (new window)

The accessible name comes from the link text and contains the warning. Should not be flagged.

Anchor with role="link" whose text carries the warning role=link

Hello (new tab)

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

Anchor with role="link" warned through aria-label name

Annual report

The warning is in the accessible name. Should not be flagged.

Anchor with role="link" warned through its accessible description description

Annual report

The name is the link text and the title supplies the description, which is where the warning lives. This is the case that required the accessible-description markdown step to include role=link anchors — without that, this compliant link would have become a false positive. Should not be flagged.

FAIL Tests — Correctly Flagged

ENG-1744 repro cases — missed before the fix

Ticket repro: role="link" anchor with target="_blank" and no warning role=link

Testing this out

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

Uppercase role="LINK" anchor with target="_blank" and no warning case

Hello

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 whose aria-label omits the warning name only

Annual report

A label that renames the link but still says nothing about the new window. Pre-fix: not flagged ❌. Post-fix: flagged ✓.

role="link" anchor whose title description omits the warning description

Annual report

A description is now calculated for this anchor, and it does not mention a new window either. Pre-fix: not flagged ❌. Post-fix: flagged ✓. (Note the test matches the bare substring tab, so a description wording such as "Portable document format" would suppress the finding — avoid words containing tab when adding cases here.)

Regression guard — flagged before and after the fix

Role-less anchor with target="_blank" and no warning no role

Hello

The original test 220 case. Must stay flagged ✓.

Real-World Scenarios

Policy link opening a PDF in a new tab role=link

View our accessibility policy

The most common form: an external or document link that changes context without saying so. Pre-fix: not flagged ❌. Post-fix: flagged ✓.

Social icon link named only by the network role=link

★

Icon links are labelled with the destination name and rarely mention the new window. Pre-fix: not flagged ❌. Post-fix: flagged ✓.