Manual Test Cases for Table Headers under role="none" - Test 387 (ENG-1742)

Test 387: One or more table elements that hold table data, without an ARIA-assigned role, not intentionally hidden in the DOM and available to assistive technologies, does not contain one or more th elements (without an ARIA-assigned role); th elements with a role set to rowheader | columnheader; or td elements with a role set to rowheader | columnheader.

The bug

The markup pipeline propagated role="none"/role="presentation" to every descendant of the presentational element. A table wrapped in <div role="none"> therefore had its th elements marked as unavailable to assistive technology, so test 387 found no headers and false-flagged the table. Reported from a client's Blazor application, where a focus-trap wrapper carries role="none" around the whole modal.

The ARIA rule

Presentational roles are inherited only by an element's required owned elements, not by arbitrary DOM descendants. A <div> has no required owned elements, so role="none" on it strips the semantics of the div and nothing else - the <table> inside starts a fresh semantic context and keeps its rows, headers and cells. Only <table role="none"> cascades, along table → rowgroup → row → columnheader. Confirmed against VoiceOver and NVDA, which both announce the headers below.

Expected after the fix: the orange Bug cases must no longer be flagged by test 387, and the red Fail cases must still be flagged - the cascade has to keep working where ARIA says it applies, so this is not a matter of exempting tables under role="none".

Bug Tests - Previously False-Flagged, Must Now Pass

Data table wrapped in a div with role="none" - the reported case

Header 1 Header 2
Data 1 Data 2
Data 3 Data 4

A div owns no required elements, so the th elements stay available to AT.

Data table wrapped in a div with role="presentation" - the alias

Header 1 Header 2
Data 1 Data 2

role="none" and role="presentation" are ARIA synonyms, so this must behave identically to the case above.

Client markup - nested role="none" wrappers around a Blazor data grid

Several levels of role="none" wrappers, none of which owns the table.

Data table nested inside a cell of a presentational layout table

Name Age
Airi Satou 33

The cascade reaches the outer table's cell and stops: a cell owns nothing, so the nested data table keeps its headers.

Fail Tests - Must Still Be Flagged

Data table with no headers at all, wrapped in a div with role="none"

Airi Satou Accountant Tokyo
Angelica Ramos Chief Executive Officer London

Regression guard: the fix must not blanket-exempt tables under role="none".

Data table whose only header row carries role="presentation"

Name Age
Airi Satou 33

A row does own its cells, so the presentational row correctly strips these th elements and the table is left with no headers available to AT.

N/A Tests - Not Evaluated by Test 387

The table itself carries role="presentation"

The table has an ARIA-assigned role and is not available to AT, so it is outside the candidate set.

The table itself carries role="none"

Header 1 Header 2
Data 1 Data 2

The symmetric case to the wrapper: when the role is on the table itself the cascade does apply, stripping the th elements. This is N/A rather than a fail, because test 387 only evaluates tables that are themselves available to AT and carry no ARIA role.

Table hidden with display:none inside a div with role="none"

Intentionally hidden in the DOM, so it is not evaluated.