ENG-1726: Test 1297 — aria-multiselectable Selectable-Descendant Counting

Where the fix lives. The aria-multiselectable best practice (BP 1626) is enforced by several separate Access Engine automatic tests. They do different jobs and only some were touched by ENG-1726:

TestWhat it flagsTouched by ENG-1726?
261aria-multiselectable on an element whose explicit role is not grid/listbox/tablist/tree/treegrid ("attribute not allowed on this element").No — unchanged.
1296aria-multiselectable="false" element with more than one child carrying aria-selected="true" or aria-checked="true".Yes — shares the descendant-counting util.
1297Element with an aria-multiselectable attribute that has zero children whose role supports an aria-selected/aria-checked attribute they carry.Yes — this is the ENG-1726 fix.
1298aria-multiselectable="true" element with fewer than two such children.Yes — shares the descendant-counting util.

Two things this page keeps separate: (1) whether aria-multiselectable belongs on the element at all (its container role) is the job of test 261, which ENG-1726 did not change; (2) tests 1296/1297/1298 only count selectable descendants. Test 1297 asks: does this aria-multiselectable element have at least one descendant carrying aria-selected/aria-checked on a role that actually supports it?

Bug (ENG-1726):

The shared helper getMultiselectableDescendantsCount counted a descendant only if its data-ae_ar matched a whitelisted role. But data-ae_ar is recorded only from an explicit role attribute (the markup stage does not compute implicit ARIA roles), so a descendant relying on an implicit role — a <tr> (row) or <td> (gridcell) inside a role="grid", a native <option> (option), a native <input type="checkbox">/radio — had data-ae_ar="null" and was invisible to the whitelist. A correctly-built widget could be counted as having zero selectable children → false-positive 1297 (and 1298).

Fix (ENG-1726):

The helper now resolves implicit ARIA roles for a known set of native elements, but only when the element carries no explicit role (data-ae_ar="null"), and it keeps the explicit-role whitelist unchanged. Roles that do not support the attribute (e.g. role="button", or a no-role <span>/<div>/<li>) are still not counted, so the result stays ARIA-spec compliant:

Source: src/Tests/TestUtils/testUtil_ariaMultiselectable.js. The container-role question remains entirely with test 261; ownership of a descendant is attributed to its nearest aria-multiselectable ancestor, so nested multiselect containers each get their own count.

N/A — no aria-multiselectable attribute / not rendered
PASS 1297 — ≥1 supported selectable descendant
FAIL 1297 — zero supported selectable descendants
BUG — pre-fix false positive (implicit role), now passes
explicit role   implicit role   also test 261

N/A — Not Evaluated by Test 1297

Hidden container with aria-multiselectable (display:none) — not rendered

The container is not rendered (display:none), so it does not get data-ae_vis and is not in 1297's candidate set (which requires [data-ae_vis][data-ae_avat]). Should not be flagged.

Container WITHOUT aria-multiselectable — attribute absent

1297's applicability keys off the presence of the aria-multiselectable attribute. With no such attribute the element never enters scope. Should not be flagged.

Single-select native <select> (no multiple, no aria-multiselectable)

No aria-multiselectable attribute is present, so 1297 does not apply. Should not be flagged.

Native <select multiple> with <option selected> — no aria-multiselectable attribute

A native <select multiple> conveys multi-selectability natively and carries no aria-multiselectable attribute, so 1297 (which keys off that attribute) does not evaluate it. Note also: the HTML selected attribute is not an aria-selected DOM attribute, which is what the engine's selector matches. Should not be flagged.

PASS Test 1297 — Explicit Whitelisted Roles (counted pre- and post-fix)

These containers have selectable children whose explicit role was already on the whitelist, so they passed 1297 before and after ENG-1726 — controls confirming the fix did not regress the explicit path. (They also pass test 261: their role is listbox/grid/tree.)

ARIA listbox of <li role="option" aria-selected> explicit role

Explicit role="option" (data-ae_ar="option", whitelisted) + aria-selected → counted. 1297 count ≥ 1. Should not be flagged.

<table role="grid"> with <td role="gridcell" aria-selected> explicit role

A1 (selected) B1
A2 (selected) B2

Explicit role="gridcell" + aria-selected → counted. 1297 count ≥ 1. Should not be flagged.

role="tree" with <li role="treeitem" aria-selected> explicit role

Explicit role="treeitem" + aria-selected → counted. 1297 count ≥ 1. Should not be flagged.

Grid with <tr role="row" aria-selected> explicit role

NameSize
report.pdf1.2 MB
notes.txt4 KB

Explicit role="row" + aria-selected → counted. 1297 count ≥ 1. Should not be flagged.

Real-world data grid — explicit grid/row/gridcell explicit role

Invoice Amount Status
INV-1001 $240.00 Paid
INV-1002 $80.00 Pending

Selection on rows and cells with explicit roles → counted. 1297 count ≥ 1. Should not be flagged.

Real-world ARIA listbox — explicit role="option" items explicit role

IMG_0001.jpg
IMG_0002.jpg
IMG_0003.jpg
IMG_0004.jpg

Fully explicit ARIA listbox. 1297 count ≥ 1. Should not be flagged.

BUG Reproduction — Implicit-Role Descendants (Pre-Fix False Positives, Now Pass)

In each case the selectable descendants carry no explicit role (data-ae_ar="null") but their implicit role supports the attribute. Pre-fix they were invisible to the explicit-role whitelist → 1297 reported "zero selectable children" (false positive). Post-fix the helper resolves the implicit role for these native elements → counted → 1297 passes. Each mirrors a regression unit test added in the engine PR.

Grid with bare <td aria-selected> — implicit gridcell implicit role

Cell 1 (selected)Cell 2

A bare <td> has data-ae_ar="null". Because its nearest <table> is role="grid", the fix resolves its implicit role to gridcell (whitelisted for aria-selected) → counted. Pre-fix: not matched → false-positive fail. Post-fix: 1297 passes. Container role grid → no 261 finding.

Grid with bare <tr aria-selected> rows — implicit row implicit role

IDNameAge
1John Doe30
2Jane Smith28
3Bob Johnson35

Mirrors the engine's ENG-1726 regression test. The <tr> rows have data-ae_ar="null"; the fix resolves their implicit role row → counted. Pre-fix: false-positive fail. Post-fix: 1297 passes.

Grid with bare <th scope="row" aria-selected> — implicit rowheader implicit role

Row head 1A2
Row head 2B2

A bare <th> in a grid resolves to rowheader/columnheader (whitelisted for aria-selected) → counted. Pre-fix: false-positive fail. Post-fix: 1297 passes.

Listbox with native <option aria-selected> — implicit option implicit role

Native <option> elements have data-ae_ar="null" (no explicit role) but an implicit option role → counted. Pre-fix: false-positive fail. Post-fix: 1297 passes. (Note: a no-role <li>/<span> would not count — only the specific native tags with a supporting implicit role are resolved; see the FAIL section.)

"Select all that apply" group — <input type="checkbox" aria-checked> — implicit checkbox implicit role also test 261

A native <input type="checkbox"> has data-ae_ar="null" but implicit role checkbox (whitelisted for aria-checked) → counted. Pre-fix: false-positive fail. Post-fix: 1297 passes. The aria-multiselectable on role="group" is still flagged by test 261 (group is not grid/listbox/tablist/tree/treegrid) — a separate finding, not 1297.

Container with native <input type="radio" aria-checked> — implicit radio implicit role also test 261

Native <input type="radio"> resolves to implicit role radio (whitelisted for aria-checked) → counted. Pre-fix: false-positive fail. Post-fix: 1297 passes. (Container role="group" → separate test 261 finding.)

FAIL Test 1297 — No Supported Selectable Descendant (correctly flagged)

All containers below use aria-multiselectable="true" with zero supported selectable descendants, so the engine reports 1297 (count = 0) and also 1298 (count < 2). The first two are genuinely empty; the rest are the ARIA-spec guards — descendants that carry the attribute but on a role (explicit or implicit) that does not support it.

Listbox with only <p> children — nothing carries aria-selected/aria-checked

Just a paragraph

Another paragraph

No descendant carries aria-selected/aria-checked → count = 0 → flagged. (Role listbox → no 261 finding.) Should be flagged.

Grid whose <tr> rows carry no aria-selected/aria-checked

IDNameAge
1John Doe30
2Jane Smith28

Mirrors the engine's "negative twin" test. The rows could carry an implicit row role, but none has aria-selected/aria-checked → count = 0 → flagged. Should be flagged.

role="button" descendants carrying aria-selected — button does not support it unsupported role also test 261

Button 1
Button 2

Mirrors the engine unit test. role="button" (data-ae_ar="button") is not whitelisted and is not one of the implicit-role tags, so the descendants are not counted even though they carry aria-selected → count = 0 → 1297 fails. The bare-<div> container (data-ae_ar="null") is also flagged by test 261. Should be flagged.

Listbox with no-role <span aria-selected> children — generic role does not support it no supporting role

Bogus 1 Bogus 2

A no-role <span> has data-ae_ar="null" and is not one of the resolved implicit-role tags (only <tr>/<option>/<td>/<th>/<input> are) → not counted → count = 0 → flagged. (Role listbox → no 261 finding; the bogus aria-selected on a generic element is a separate ARIA-validity concern caught elsewhere.) Should be flagged.

Plain <table aria-multiselectable> with <td aria-selected> — cell, not gridcell implicit role also test 261

A1A2

Mirrors the engine unit test. The nearest <table> has no role="grid"/treegrid", so a <td> here is an implicit cell — which does not support aria-selected — and is not counted → count = 0 → 1297 fails. The plain <table> (data-ae_ar="null") is also flagged by test 261. Should be flagged.

Grid containing a nested plain table whose <td> carries aria-selected — not promoted implicit role

Inner cell

Mirrors the engine unit test. The inner <td aria-selected>'s nearest <table> is the inner plain table, so it is a cell, not a gridcell of the outer grid → not counted. The outer grid's only candidate is rejected → count = 0 → flagged. (Note: the outer-grid <td> wrapping the inner table carries no aria-selected.) Should be flagged.

Container whose only selected descendant is aria-hidden

Plain visible option (no aria-selected)

The counter only counts data-ae_vis + data-ae_avat descendants. The single aria-selected child is aria-hidden (no data-ae_avat) → excluded; the other has no aria-selected → count = 0 → flagged. Should be flagged.

Out of Scope for Test 1297 — Handled by Other Tests

Summary

This page verifies the ENG-1726 fix to the aria-multiselectable selectable-descendant counter shared by tests 1296/1297/1298. The fix makes counting ARIA-spec compliant: a descendant counts only if it carries aria-selected/aria-checked on a role that supports it, resolved by explicit role (whitelist, unchanged) or by implicit role for a known set of native elements that carry no explicit role — <tr>, <option>, <input type="checkbox"/radio">, and <td>/<th> inside a grid/treegrid.