Source code
Revision control
Copy as Markdown
Other Tools
Test Info:
- This WPT test may be referenced by the following Test IDs:
- /html/interaction/focus/focusgroup/tentative/ax-role-inference-item-elementinternals.html - WPT Dashboard Interop Dashboard
<!DOCTYPE html>
<meta charset="utf-8">
<title>HTML Test: focusgroup - ElementInternals item role never overridden</title>
<meta name="assert" content="Author supplied ElementInternals role for a focusgroup item must never be overridden by implied item role inference, even when mismatching expected mapping.">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<!-- Scenario A: Owner implied tablist, item supplies expected mapped role 'tab'. -->
<div id="fgOwnerTablist" focusgroup="tablist">
<focusgroup-item-internals-expected id="tabItem" tabindex="0"></focusgroup-item-internals-expected>
</div>
<!-- Scenario B: Same owner type (tablist) but item supplies a different role ('button'); ensure we do NOT coerce it to tab. -->
<div id="fgOwnerTablistMismatch" focusgroup="tablist">
<focusgroup-item-internals-mismatch id="mismatchItem" tabindex="0"></focusgroup-item-internals-mismatch>
</div>
<script>
class FocusgroupItemInternalsExpected extends HTMLElement {
constructor() {
super();
this.internals_ = this.attachInternals();
// ElementInternals author supplied role should be preserved.
this.internals_.role = 'tab';
this.textContent = 'Item';
}
}
customElements.define('focusgroup-item-internals-expected', FocusgroupItemInternalsExpected);
class FocusgroupItemInternalsMismatch extends HTMLElement {
constructor() {
super();
this.internals_ = this.attachInternals();
// Deliberately provide a role that does NOT match the implied item role mapping.
this.internals_.role = 'button';
this.textContent = 'Other';
}
}
customElements.define('focusgroup-item-internals-mismatch', FocusgroupItemInternalsMismatch);
</script>
<script>
if (!window.accessibilityController) {
test(() => { assert_true(true); }, 'accessibilityController not available (noop)');
} else {
test(() => {
const ownerAX = accessibilityController.accessibleElementById('fgOwnerTablist');
assert_equals(ownerAX.role, 'AXRole: AXTabList');
}, 'Scenario A: Owner receives implied tablist role');
test(() => {
const itemAX = accessibilityController.accessibleElementById('tabItem');
assert_equals(itemAX.role, 'AXRole: AXTab');
}, 'Scenario A: Expected mapped ElementInternals role (tab) preserved');
test(() => {
const ownerAX = accessibilityController.accessibleElementById('fgOwnerTablistMismatch');
assert_equals(ownerAX.role, 'AXRole: AXTabList');
}, 'Scenario B: Owner implied tablist role still inferred with mismatched child role');
test(() => {
const itemAX = accessibilityController.accessibleElementById('mismatchItem');
// Critical assertion: we do NOT coerce to AXTab; remains AXButton per author intent.
assert_equals(itemAX.role, 'AXRole: AXButton');
}, 'Scenario B: Mismatched ElementInternals role (button) preserved (no coercion)');
}
</script>