From 36d22d82aa202bb199967e9512281e9a53db42c9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 21:33:14 +0200 Subject: Adding upstream version 115.7.0esr. Signed-off-by: Daniel Baumann --- accessible/tests/browser/selectable/browser.ini | 12 + .../browser/selectable/browser_test_aria_select.js | 164 ++++++++++ .../browser/selectable/browser_test_select.js | 329 +++++++++++++++++++++ accessible/tests/browser/selectable/head.js | 88 ++++++ 4 files changed, 593 insertions(+) create mode 100644 accessible/tests/browser/selectable/browser.ini create mode 100644 accessible/tests/browser/selectable/browser_test_aria_select.js create mode 100644 accessible/tests/browser/selectable/browser_test_select.js create mode 100644 accessible/tests/browser/selectable/head.js (limited to 'accessible/tests/browser/selectable') diff --git a/accessible/tests/browser/selectable/browser.ini b/accessible/tests/browser/selectable/browser.ini new file mode 100644 index 0000000000..45e34f82d3 --- /dev/null +++ b/accessible/tests/browser/selectable/browser.ini @@ -0,0 +1,12 @@ +[DEFAULT] +subsuite = a11y +support-files = + head.js + !/accessible/tests/browser/shared-head.js + !/accessible/tests/browser/*.jsm + !/accessible/tests/mochitest/*.js +prefs = + javascript.options.asyncstack_capture_debuggee_only=false + +[browser_test_aria_select.js] +[browser_test_select.js] diff --git a/accessible/tests/browser/selectable/browser_test_aria_select.js b/accessible/tests/browser/selectable/browser_test_aria_select.js new file mode 100644 index 0000000000..f52603d1cb --- /dev/null +++ b/accessible/tests/browser/selectable/browser_test_aria_select.js @@ -0,0 +1,164 @@ +/* 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"; + +/* import-globals-from ../../mochitest/selectable.js */ + +// //////////////////////////////////////////////////////////////////////// +// role="tablist" role="listbox" role="grid" role="tree" role="treegrid" +addAccessibleTask( + `
+
tab1
+
tab2
+
+
+
item1
+
item2
+
+
+
+ cell + cell +
+
+ cell + cell +
+
+
+
+ item1 +
+
item1.1
+
+
+
item2
+
+
+
+ cell + cell +
+
+ cell + cell +
+
+ cell + cell +
+
`, + async function (browser, docAcc) { + info( + 'role="tablist" role="listbox" role="grid" role="tree" role="treegrid"' + ); + testSelectableSelection(findAccessibleChildByID(docAcc, "tablist"), []); + testSelectableSelection(findAccessibleChildByID(docAcc, "listbox"), []); + testSelectableSelection(findAccessibleChildByID(docAcc, "grid"), []); + testSelectableSelection(findAccessibleChildByID(docAcc, "tree"), []); + testSelectableSelection(findAccessibleChildByID(docAcc, "treegrid"), []); + }, + { + chrome: true, + topLevel: true, + iframe: true, + remoteIframe: true, + } +); + +// //////////////////////////////////////////////////////////////////////// +// role="tablist" aria-multiselectable +addAccessibleTask( + `
+ + +
`, + async function (browser, docAcc) { + info('role="tablist" aria-multiselectable'); + let tablist = findAccessibleChildByID(docAcc, "tablist", [ + nsIAccessibleSelectable, + ]); + + await testMultiSelectable(tablist, ["tab_multi1", "tab_multi2"]); + }, + { + chrome: true, + topLevel: true, + iframe: true, + remoteIframe: true, + } +); + +// //////////////////////////////////////////////////////////////////////// +// role="listbox" aria-multiselectable +addAccessibleTask( + `
+
item1
+
item2
+
`, + async function (browser, docAcc) { + info('role="listbox" aria-multiselectable'); + let listbox = findAccessibleChildByID(docAcc, "listbox", [ + nsIAccessibleSelectable, + ]); + + await testMultiSelectable(listbox, ["listbox2_item1", "listbox2_item2"]); + }, + { + chrome: true, + topLevel: true, + iframe: true, + remoteIframe: true, + } +); + +// //////////////////////////////////////////////////////////////////////// +// role="grid" aria-multiselectable, selectable children in subtree +addAccessibleTask( + ` + + + + + + + + + + + + + + +
Entry #DateExpense
103/14/05Conference Fee
`, + async function (browser, docAcc) { + info('role="grid" aria-multiselectable, selectable children in subtree'); + let grid = findAccessibleChildByID(docAcc, "grid", [ + nsIAccessibleSelectable, + ]); + + await testMultiSelectable(grid, [ + "grid_colhead1", + "grid_colhead2", + "grid_colhead3", + "grid_rowhead", + "grid_cell1", + "grid_cell2", + ]); + }, + { + chrome: true, + topLevel: true, + iframe: true, + remoteIframe: true, + } +); diff --git a/accessible/tests/browser/selectable/browser_test_select.js b/accessible/tests/browser/selectable/browser_test_select.js new file mode 100644 index 0000000000..f86a371d81 --- /dev/null +++ b/accessible/tests/browser/selectable/browser_test_select.js @@ -0,0 +1,329 @@ +/* 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"; + +/* import-globals-from ../../mochitest/selectable.js */ +/* import-globals-from ../../mochitest/states.js */ + +// //////////////////////////////////////////////////////////////////////// +// select@size="1" aka combobox +addAccessibleTask( + ``, + async function (browser, docAcc) { + info("select@size='1' aka combobox"); + let combobox = findAccessibleChildByID(docAcc, "combobox"); + let comboboxList = combobox.firstChild; + ok( + isAccessible(comboboxList, [nsIAccessibleSelectable]), + "No selectable accessible for combobox" + ); + + let select = getAccessible(comboboxList, [nsIAccessibleSelectable]); + testSelectableSelection(select, ["item1"]); + + // select 2nd item + let promise = Promise.all([ + waitForStateChange("item2", STATE_SELECTED, true), + waitForStateChange("item1", STATE_SELECTED, false), + ]); + select.addItemToSelection(1); + await promise; + testSelectableSelection(select, ["item2"], "addItemToSelection(1): "); + + // unselect 2nd item, 1st item gets selected automatically + promise = Promise.all([ + waitForStateChange("item2", STATE_SELECTED, false), + waitForStateChange("item1", STATE_SELECTED, true), + ]); + select.removeItemFromSelection(1); + await promise; + testSelectableSelection(select, ["item1"], "removeItemFromSelection(1): "); + + // doesn't change selection + is(select.selectAll(), false, "No way to select all items in combobox"); + testSelectableSelection(select, ["item1"], "selectAll: "); + + // doesn't change selection + select.unselectAll(); + testSelectableSelection(select, ["item1"], "unselectAll: "); + }, + { + chrome: true, + topLevel: true, + iframe: true, + remoteIframe: true, + } +); + +// //////////////////////////////////////////////////////////////////////// +// select@size="1" with optgroups +addAccessibleTask( + ``, + async function (browser, docAcc) { + info("select@size='1' with optgroups"); + let combobox = findAccessibleChildByID(docAcc, "combobox"); + let comboboxList = combobox.firstChild; + ok( + isAccessible(comboboxList, [nsIAccessibleSelectable]), + "No selectable accessible for combobox" + ); + + let select = getAccessible(comboboxList, [nsIAccessibleSelectable]); + testSelectableSelection(select, ["item1"]); + + let promise = Promise.all([ + waitForStateChange("item2", STATE_SELECTED, true), + waitForStateChange("item1", STATE_SELECTED, false), + ]); + select.addItemToSelection(1); + await promise; + testSelectableSelection(select, ["item2"], "addItemToSelection(1): "); + + promise = Promise.all([ + waitForStateChange("item2", STATE_SELECTED, false), + waitForStateChange("item1", STATE_SELECTED, true), + ]); + select.removeItemFromSelection(1); + await promise; + testSelectableSelection(select, ["item1"], "removeItemFromSelection(1): "); + + is(select.selectAll(), false, "No way to select all items in combobox"); + testSelectableSelection(select, ["item1"]); + + select.unselectAll(); + testSelectableSelection(select, ["item1"]); + }, + { + chrome: true, + topLevel: true, + iframe: true, + remoteIframe: true, + } +); + +// //////////////////////////////////////////////////////////////////////// +// select@size="4" aka single selectable listbox +addAccessibleTask( + ``, + async function (browser, docAcc) { + info("select@size='4' aka single selectable listbox"); + let select = findAccessibleChildByID(docAcc, "listbox", [ + nsIAccessibleSelectable, + ]); + testSelectableSelection(select, []); + + // select 2nd item + let promise = waitForStateChange("item2", STATE_SELECTED, true); + select.addItemToSelection(1); + await promise; + testSelectableSelection(select, ["item2"], "addItemToSelection(1): "); + + // unselect 2nd item, 1st item gets selected automatically + promise = waitForStateChange("item2", STATE_SELECTED, false); + select.removeItemFromSelection(1); + await promise; + testSelectableSelection(select, [], "removeItemFromSelection(1): "); + + // doesn't change selection + is( + select.selectAll(), + false, + "No way to select all items in single selectable listbox" + ); + testSelectableSelection(select, [], "selectAll: "); + + // doesn't change selection + select.unselectAll(); + testSelectableSelection(select, [], "unselectAll: "); + }, + { + chrome: true, + topLevel: true, + iframe: true, + remoteIframe: true, + } +); + +// //////////////////////////////////////////////////////////////////////// +// select@size="4" with optgroups, single selectable +addAccessibleTask( + ``, + async function (browser, docAcc) { + info("select@size='4' with optgroups, single selectable"); + let select = findAccessibleChildByID(docAcc, "listbox", [ + nsIAccessibleSelectable, + ]); + testSelectableSelection(select, []); + + let promise = waitForStateChange("item2", STATE_SELECTED, true); + select.addItemToSelection(1); + await promise; + testSelectableSelection(select, ["item2"]); + + promise = waitForStateChange("item2", STATE_SELECTED, false); + select.removeItemFromSelection(1); + await promise; + testSelectableSelection(select, []); + + is( + select.selectAll(), + false, + "No way to select all items in single selectable listbox" + ); + testSelectableSelection(select, []); + + select.unselectAll(); + testSelectableSelection(select, []); + }, + { + chrome: true, + topLevel: true, + iframe: true, + remoteIframe: true, + } +); + +// //////////////////////////////////////////////////////////////////////// +// select@size="4" multiselect aka listbox +addAccessibleTask( + ``, + async function (browser, docAcc) { + info("select@size='4' multiselect aka listbox"); + let select = findAccessibleChildByID(docAcc, "listbox", [ + nsIAccessibleSelectable, + ]); + await testMultiSelectable( + select, + ["item1", "item2"], + "select@size='4' multiselect aka listbox " + ); + }, + { + chrome: true, + topLevel: true, + iframe: true, + remoteIframe: true, + } +); + +// //////////////////////////////////////////////////////////////////////// +// select@size="4" multiselect with optgroups +addAccessibleTask( + ``, + async function (browser, docAcc) { + info("select@size='4' multiselect with optgroups"); + let select = findAccessibleChildByID(docAcc, "listbox", [ + nsIAccessibleSelectable, + ]); + await testMultiSelectable( + select, + ["item1", "item2"], + "select@size='4' multiselect aka listbox " + ); + }, + { + chrome: true, + topLevel: true, + iframe: true, + remoteIframe: true, + } +); + +// //////////////////////////////////////////////////////////////////////// +// multiselect with coalesced selection event +addAccessibleTask( + ``, + async function (browser, docAcc) { + info("select@size='4' multiselect with coalesced selection event"); + let select = findAccessibleChildByID(docAcc, "listbox", [ + nsIAccessibleSelectable, + ]); + await testMultiSelectable( + select, + [ + "item1", + "item2", + "item3", + "item4", + "item5", + "item6", + "item7", + "item8", + "item9", + ], + "select@size='4' multiselect with coalesced selection event " + ); + }, + { + chrome: false, + topLevel: true, + iframe: false, + remoteIframe: false, + } +); + +/** + * Ensure that we don't assert when dealing with defunct items in selection + * events dropped due to coalescence (bug 1800755). + */ +addAccessibleTask( + ` +
+ +
+ `, + async function (browser, docAcc) { + let selected = waitForEvent(EVENT_SELECTION_WITHIN, "select"); + await invokeContentTask(browser, [], () => { + const form = content.document.getElementById("form"); + const select = content.document.getElementById("select"); + const optgroup = content.document.getElementById("optgroup"); + form.reset(); + select.selectedIndex = 1; + select.add(optgroup); + select.item(0).remove(); + }); + await selected; + } +); diff --git a/accessible/tests/browser/selectable/head.js b/accessible/tests/browser/selectable/head.js new file mode 100644 index 0000000000..ccf9e86f77 --- /dev/null +++ b/accessible/tests/browser/selectable/head.js @@ -0,0 +1,88 @@ +/* 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"; + +/* exported testMultiSelectable */ + +// Load the shared-head file first. +Services.scriptloader.loadSubScript( + "chrome://mochitests/content/browser/accessible/tests/browser/shared-head.js", + this +); + +// Loading and common.js from accessible/tests/mochitest/ for all tests, as +// well as promisified-events.js. +/* import-globals-from ../../mochitest/selectable.js */ +/* import-globals-from ../../mochitest/states.js */ +loadScripts( + { name: "common.js", dir: MOCHITESTS_DIR }, + { name: "promisified-events.js", dir: MOCHITESTS_DIR }, + { name: "selectable.js", dir: MOCHITESTS_DIR }, + { name: "states.js", dir: MOCHITESTS_DIR }, + { name: "role.js", dir: MOCHITESTS_DIR } +); + +// Handle case where multiple selection change events are coalesced into +// a SELECTION_WITHIN event. Promise resolves to true in that case. +function multipleSelectionChanged(widget, changedChildren, selected) { + return Promise.race([ + Promise.all( + changedChildren.map(id => + waitForStateChange(id, STATE_SELECTED, selected) + ) + ).then(() => false), + waitForEvent(EVENT_SELECTION_WITHIN, widget).then(() => true), + ]); +} + +async function testMultiSelectable(widget, selectableChildren, msg = "") { + let isRemote = false; + try { + widget.DOMNode; + } catch (e) { + isRemote = true; + } + + testSelectableSelection(widget, [], `${msg}: initial`); + + let promise = waitForStateChange(selectableChildren[0], STATE_SELECTED, true); + widget.addItemToSelection(0); + await promise; + testSelectableSelection( + widget, + [selectableChildren[0]], + `${msg}: addItemToSelection(0)` + ); + + promise = waitForStateChange(selectableChildren[0], STATE_SELECTED, false); + widget.removeItemFromSelection(0); + await promise; + testSelectableSelection(widget, [], `${msg}: removeItemFromSelection(0)`); + + promise = multipleSelectionChanged(widget, selectableChildren, true); + let success = widget.selectAll(); + ok(success, `${msg}: selectAll success`); + await promise; + if (isRemote) { + await untilCacheIs( + () => widget.selectedItemCount, + selectableChildren.length, + "Selection cache updated" + ); + } + testSelectableSelection(widget, selectableChildren, `${msg}: selectAll`); + + promise = multipleSelectionChanged(widget, selectableChildren, false); + widget.unselectAll(); + await promise; + if (isRemote) { + await untilCacheIs( + () => widget.selectedItemCount, + 0, + "Selection cache updated" + ); + } + testSelectableSelection(widget, [], `${msg}: selectAll`); +} -- cgit v1.2.3