diff options
Diffstat (limited to 'accessible/tests/browser/windows/uia/browser_selectionPatterns.js')
-rw-r--r-- | accessible/tests/browser/windows/uia/browser_selectionPatterns.js | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/accessible/tests/browser/windows/uia/browser_selectionPatterns.js b/accessible/tests/browser/windows/uia/browser_selectionPatterns.js new file mode 100644 index 0000000000..a1f70b886a --- /dev/null +++ b/accessible/tests/browser/windows/uia/browser_selectionPatterns.js @@ -0,0 +1,226 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +"use strict"; + +const SNIPPET = ` +<select id="selectList" size="2"> + <option id="sl1" selected>sl1</option> + <option id="sl2">sl2</option> +</select> +<select id="selectRequired" size="2" required> + <option id="sr1">sr1</option> +</select> +<select id="selectMulti" size="2" multiple> + <option id="sm1" selected>sm1</option> + <option id="sm2">sm2</option> + <option id="sm3" selected>sm3</option> + <option id="sm4">sm4</option> + <option id="sm5">sm5</option> + <option id="sm6">sm6</option> +</select> +<select id="selectCombo" size="1"> + <option>sc1</option> +</select> +<div id="ariaListbox" role="listbox"> + <div id="al1" role="option" aria-selected="true">al1</div> + <div id="al2" role="option">al2</div> +</div> +<div id="tablist" role="tablist"> + <div id="t1" role="tab">t1</div> + <div id="t2" role="tab" aria-selected="true">t2</div> +</div> +<table id="grid" role="grid" aria-multiselectable="true"> + <tr> + <td id="g1">g1</td> + <td id="g2" role="gridcell" aria-selected="true">g2</td> + </tr> + <tr> + <td id="g3">g3</td> + <td id="g4" role="gridcell" aria-selected="true">g4</td> + </tr> +</table> +<div id="radiogroup" role="radiogroup"> + <label><input id="r1" type="radio" name="r" checked>r1</label> + <label><input id="r2" type="radio" name="r">r2</label> +</div> +<div id="menu" role="menu"> + <div id="m1" role="menuitem">m1</div> + <div id="m2" role="menuitemradio">m2</div> + <div id="m3" role="menuitemradio" aria-checked="true">m3</div> +</div> +<button id="button">button</button> +`; + +async function testSelectionProps(id, selection, multiple, required) { + await assignPyVarToUiaWithId(id); + await definePyVar("pattern", `getUiaPattern(${id}, "Selection")`); + ok(await runPython(`bool(pattern)`), `${id} has Selection pattern`); + await isUiaElementArray( + `pattern.GetCurrentSelection()`, + selection, + `${id} has correct Selection` + ); + is( + !!(await runPython(`pattern.CurrentCanSelectMultiple`)), + multiple, + `${id} has correct CanSelectMultiple` + ); + // The IA2 -> UIA proxy doesn't reflect the required state correctly. + if (gIsUiaEnabled) { + is( + !!(await runPython(`pattern.CurrentIsSelectionRequired`)), + required, + `${id} has correct IsSelectionRequired` + ); + } +} + +async function testSelectionItemProps(id, selected, container) { + await assignPyVarToUiaWithId(id); + await definePyVar("pattern", `getUiaPattern(${id}, "SelectionItem")`); + ok(await runPython(`bool(pattern)`), `${id} has SelectionItem pattern`); + is( + !!(await runPython(`pattern.CurrentIsSelected`)), + selected, + `${id} has correct IsSelected` + ); + if (container) { + is( + await runPython(`pattern.CurrentSelectionContainer.CurrentAutomationId`), + container, + `${id} has correct SelectionContainer` + ); + } else { + ok( + !(await runPython(`bool(pattern.CurrentSelectionContainer)`)), + `${id} has no SelectionContainer` + ); + } +} + +/** + * Test the Selection pattern. + */ +addUiaTask(SNIPPET, async function testSelection(browser) { + await definePyVar("doc", `getDocUia()`); + await testSelectionProps("selectList", ["sl1"], false, false); + await testSelectionProps("selectRequired", [], false, true); + + await testSelectionProps("selectMulti", ["sm1", "sm3"], true, false); + // The Selection pattern only has an event for a complete invalidation of the + // container's selection, which only happens when there are too many selection + // events. Smaller selection changes fire events in the SelectionItem pattern. + info("Changing selectMulti selection"); + await setUpWaitForUiaEvent("Selection_Invalidated", "selectMulti"); + await invokeContentTask(browser, [], () => { + const multi = content.document.getElementById("selectMulti"); + multi[0].selected = false; + multi[1].selected = true; + multi[2].selected = false; + multi[3].selected = true; + multi[4].selected = true; + multi[5].selected = true; + }); + await waitForUiaEvent(); + ok(true, "select got Invalidated event"); + await testSelectionProps( + "selectMulti", + ["sm2", "sm4", "sm5", "sm6"], + true, + false + ); + + await testPatternAbsent("selectCombo", "Selection"); + + await testSelectionProps("ariaListbox", ["al1"], false, false); + await testSelectionProps("tablist", ["t2"], false, false); + // The IA2 -> UIA proxy doesn't expose the Selection pattern on grids. + if (gIsUiaEnabled) { + await testSelectionProps("grid", ["g2", "g4"], true, false); + } + + // radio gets the SelectionItem pattern, but radiogroup doesn't get the + // Selection pattern for now. Same for menu/menuitemradio. + await testPatternAbsent("radiogroup", "Selection"); + await testPatternAbsent("menu", "Selection"); + + await testPatternAbsent("button", "Selection"); +}); + +/** + * Test the SelectionItem pattern. + */ +addUiaTask(SNIPPET, async function testSelection() { + await definePyVar("doc", `getDocUia()`); + await testPatternAbsent("selectList", "SelectionItem"); + await testSelectionItemProps("sl1", true, "selectList"); + await testSelectionItemProps("sl2", false, "selectList"); + info("Calling Select on sl2"); + await setUpWaitForUiaEvent("SelectionItem_ElementSelected", "sl2"); + await runPython(`pattern.Select()`); + await waitForUiaEvent(); + ok(true, "sl2 got ElementSelected event"); + await testSelectionItemProps("sl1", false, "selectList"); + await testSelectionItemProps("sl2", true, "selectList"); + + await testSelectionItemProps("sr1", false, "selectRequired"); + + await testSelectionItemProps("sm1", true, "selectMulti"); + await testSelectionItemProps("sm2", false, "selectMulti"); + info("Calling AddToSelection on sm2"); + await setUpWaitForUiaEvent("SelectionItem_ElementAddedToSelection", "sm2"); + await runPython(`pattern.AddToSelection()`); + await waitForUiaEvent(); + ok(true, "sm2 got ElementAddedToSelection event"); + await testSelectionItemProps("sm2", true, "selectMulti"); + await testSelectionItemProps("sm3", true, "selectMulti"); + info("Calling RemoveFromSelection on sm3"); + await setUpWaitForUiaEvent( + "SelectionItem_ElementRemovedFromSelection", + "sm3" + ); + await runPython(`pattern.RemoveFromSelection()`); + await waitForUiaEvent(); + ok(true, "sm3 got ElementRemovedFromSelection event"); + await testSelectionItemProps("sm3", false, "selectMulti"); + + await testSelectionItemProps("t1", false, "tablist"); + await testSelectionItemProps("t2", true, "tablist"); + + // The IA2 -> UIA proxy doesn't expose the SelectionItem pattern on grid + // cells. + if (gIsUiaEnabled) { + await testSelectionItemProps("g1", false, "grid"); + await testSelectionItemProps("g2", true, "grid"); + } + + await testSelectionItemProps("r1", true, null); + await testSelectionItemProps("r2", false, null); + // The IA2 -> UIA proxy doesn't fire correct events for radio buttons. + if (gIsUiaEnabled) { + info("Calling Select on r2"); + await setUpWaitForUiaEvent("SelectionItem_ElementSelected", "r2"); + await runPython(`pattern.Select()`); + await waitForUiaEvent(); + ok(true, "r2 got ElementSelected event"); + await testSelectionItemProps("r1", false, null); + await testSelectionItemProps("r2", true, null); + info("Calling RemoveFromSelection on r2"); + await testPythonRaises( + `pattern.RemoveFromSelection()`, + "RemoveFromSelection failed on r2" + ); + } + + await testPatternAbsent("m1", "SelectionItem"); + // The IA2 -> UIA proxy doesn't expose the SelectionItem pattern for radio + // menu items. + if (gIsUiaEnabled) { + await testSelectionItemProps("m2", false, null); + await testSelectionItemProps("m3", true, null); + } + + await testPatternAbsent("button", "SelectionItem"); +}); |