blob: f78a063be25f56bf1fab33cf6a8cf3bf7eeb9f2a [file] [log] [blame] [edit]
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<html>
<head>
<script src="../resources/accessibility-helper.js"></script>
<script src="../resources/js-test.js"></script>
<style>
select, select::picker(select) {
appearance: base-select;
}
</style>
</head>
<body>
<select id="select">
<option id="option1">Apple</option>
<option id="option2" selected>
Banana
<button id="foo">Foo</button>
<a href="#url">Bar</a>
</option>
<option id="option3"><span>Cherry</span></option>
</select>
<script>
var output = "This test verifies that text nodes inside complex base-appearance select options are exposed as accessible elements (e.g. for VoiceOver navigation), but only when the option has non-text descendants.\n\n";
function expectMenuItem(axElement, expectedText) {
var result = "";
result += expect("(" + axElement + ").role.toLowerCase().includes('menuitem')", "true");
window._menuItemText = platformTextAlternatives(eval(axElement));
result += _menuItemText + "\n";
result += expect("_menuItemText.includes('" + expectedText + "')", "true");
return result;
}
function hasStaticTextChild(axElement, text) {
for (var i = 0; i < axElement.childrenCount; i++) {
var child = axElement.childAtIndex(i);
if (child.role.toLowerCase().includes("statictext") && child.stringValue.includes(text))
return true;
}
return false;
}
if (window.accessibilityController) {
window.jsTestIsAsync = true;
var select = accessibilityController.accessibleElementById("select");
setTimeout(async function() {
select.press();
output += await expectAsync("select.isExpanded", "true");
window.menu = select.childAtIndex(0);
output += expect("menu.role.toLowerCase().includes('menu')", "true");
output += "\n--- Simple option: text is NOT exposed as a StaticText child ---\n";
window.appleItem = menu.childAtIndex(0);
output += expectMenuItem("menu.childAtIndex(0)", "Apple");
output += expect("appleItem.childrenCount", "0");
output += "\n--- Complex option text includes all descendant text ---\n";
window.bananaItem = menu.childAtIndex(1);
output += expect("bananaItem.role.toLowerCase().includes('menuitem')", "true");
window.bananaText = platformTextAlternatives(bananaItem);
output += bananaText + "\n";
output += expect("bananaText.includes('Banana')", "true");
output += expect("bananaText.includes('Foo')", "true");
output += expect("bananaText.includes('Bar')", "true");
window.bananaHasStaticText = hasStaticTextChild(bananaItem, "Banana");
output += expect("bananaHasStaticText", "true");
output += "\n--- Option with only a span wrapper: text is NOT exposed ---\n";
window.cherryItem = menu.childAtIndex(2);
output += expectMenuItem("menu.childAtIndex(2)", "Cherry");
output += expect("cherryItem.childrenCount", "0");
// Add a button to the span-wrapped option and verify we update the accessibility tree correctly.
var option3 = document.getElementById("option3");
var button = document.createElement("button");
button.textContent = "New";
option3.appendChild(button);
document.body.offsetWidth;
await waitFor(() => {
return hasStaticTextChild(menu.childAtIndex(2), "Cherry");
});
window.cherryHasStaticTextAfterAdd = hasStaticTextChild(menu.childAtIndex(2), "Cherry");
output += expect("cherryHasStaticTextAfterAdd", "true");
output += "\n--- Dynamic: remove the button from the option ---\n";
option3.removeChild(button);
document.body.offsetWidth;
await waitFor(() => {
return !hasStaticTextChild(menu.childAtIndex(2), "Cherry");
});
window.cherryHasStaticTextAfterRemove = hasStaticTextChild(menu.childAtIndex(2), "Cherry");
output += expect("cherryHasStaticTextAfterRemove", "false");
select.press();
output += await expectAsync("select.isExpanded", "false");
debug(output);
finishJSTest();
}, 0);
}
</script>
</body>
</html>