diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:14:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:14:29 +0000 |
commit | fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 (patch) | |
tree | 4c1ccaf5486d4f2009f9a338a98a83e886e29c97 /accessible/tests | |
parent | Releasing progress-linux version 124.0.1-1~progress7.99u1. (diff) | |
download | firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.tar.xz firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.zip |
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'accessible/tests')
98 files changed, 1426 insertions, 594 deletions
diff --git a/accessible/tests/browser/atk/browser_role.js b/accessible/tests/browser/atk/browser_role.js index 7b870b3337..47cc5ef28f 100644 --- a/accessible/tests/browser/atk/browser_role.js +++ b/accessible/tests/browser/atk/browser_role.js @@ -11,7 +11,7 @@ addAccessibleTask( ` <p id="p">p</p> `, - async function (browser, docAcc) { + async function () { let role = await runPython(` global doc doc = getDoc() diff --git a/accessible/tests/browser/atk/browser_table.js b/accessible/tests/browser/atk/browser_table.js index 98b3270465..55452709e8 100644 --- a/accessible/tests/browser/atk/browser_table.js +++ b/accessible/tests/browser/atk/browser_table.js @@ -20,7 +20,7 @@ addAccessibleTask( </tr> </table> `, - async function (browser, docAcc) { + async function () { let result = await runPython(` global doc doc = getDoc() diff --git a/accessible/tests/browser/bounds/browser_accessible_moved.js b/accessible/tests/browser/bounds/browser_accessible_moved.js index 307c680000..a62f7ad8d0 100644 --- a/accessible/tests/browser/bounds/browser_accessible_moved.js +++ b/accessible/tests/browser/bounds/browser_accessible_moved.js @@ -12,10 +12,10 @@ function assertBoundsNonZero(acc) { let width = {}; let height = {}; acc.getBounds(x, y, width, height); - ok(x.value > 0, "x is non-0"); - ok(y.value > 0, "y is non-0"); - ok(width.value > 0, "width is non-0"); - ok(height.value > 0, "height is non-0"); + Assert.greater(x.value, 0, "x is non-0"); + Assert.greater(y.value, 0, "y is non-0"); + Assert.greater(width.value, 0, "width is non-0"); + Assert.greater(height.value, 0, "height is non-0"); } /** diff --git a/accessible/tests/browser/bounds/browser_caret_rect.js b/accessible/tests/browser/bounds/browser_caret_rect.js index ac0ee3aa50..9f5cac33a5 100644 --- a/accessible/tests/browser/bounds/browser_caret_rect.js +++ b/accessible/tests/browser/bounds/browser_caret_rect.js @@ -46,7 +46,7 @@ async function testCaretRect(browser, docAcc, id, offset) { ); const [caretX, caretY, caretW, caretH] = await getCaretRect(browser, id); if (atEnd) { - ok(caretX > charX.value, "Caret x after last character x"); + Assert.greater(caretX, charX.value, "Caret x after last character x"); } else { is(caretX, charX.value, "Caret x same as character x"); } diff --git a/accessible/tests/browser/bounds/browser_test_display_contents.js b/accessible/tests/browser/bounds/browser_test_display_contents.js index db1bfce178..4111ac5a81 100644 --- a/accessible/tests/browser/bounds/browser_test_display_contents.js +++ b/accessible/tests/browser/bounds/browser_test_display_contents.js @@ -16,7 +16,11 @@ async function testContentBounds(browser, acc) { is(x, expectedX, "Wrong x coordinate of " + prettyAccName); is(y, expectedY, "Wrong y coordinate of " + prettyAccName); is(width, expectedWidth, "Wrong width of " + prettyAccName); - ok(height >= expectedHeight, "Wrong height of " + prettyAccName); + Assert.greaterOrEqual( + height, + expectedHeight, + "Wrong height of " + prettyAccName + ); } async function runTests(browser, accDoc) { diff --git a/accessible/tests/browser/bounds/browser_test_iframe_transform.js b/accessible/tests/browser/bounds/browser_test_iframe_transform.js index a44ab75faf..015d466da9 100644 --- a/accessible/tests/browser/bounds/browser_test_iframe_transform.js +++ b/accessible/tests/browser/bounds/browser_test_iframe_transform.js @@ -68,7 +68,7 @@ function testBoundsWithOffset(browser, iframeDocAcc, id, domElmBounds, offset) { addAccessibleTask( `<div id='${ELEM_ID}'>hello world</div>`, - async function (browser, iframeDocAcc, contentDocAcc) { + async function (browser, iframeDocAcc) { ok(iframeDocAcc, "IFRAME document accessible is present"); await testBoundsWithContent(iframeDocAcc, ELEM_ID, browser); @@ -143,7 +143,7 @@ addAccessibleTask( */ addAccessibleTask( `<div id="div" style="width: 30px; height: 30px"></div>`, - async function (browser, accDoc, foo) { + async function (browser, accDoc) { const docWidth = () => { let width = {}; accDoc.getBounds({}, {}, width, {}); diff --git a/accessible/tests/browser/bounds/browser_test_simple_transform.js b/accessible/tests/browser/bounds/browser_test_simple_transform.js index 7197968b40..b5cb983e72 100644 --- a/accessible/tests/browser/bounds/browser_test_simple_transform.js +++ b/accessible/tests/browser/bounds/browser_test_simple_transform.js @@ -9,7 +9,7 @@ loadScripts({ name: "role.js", dir: MOCHITESTS_DIR }); // test basic translation addAccessibleTask( `<p id="translate">hello world</p>`, - async function (browser, iframeDocAcc, contentDocAcc) { + async function (browser, iframeDocAcc) { ok(iframeDocAcc, "IFRAME document accessible is present"); await testBoundsWithContent(iframeDocAcc, "translate", browser); @@ -42,7 +42,7 @@ addAccessibleTask( // test basic rotation addAccessibleTask( `<p id="rotate">hello world</p>`, - async function (browser, iframeDocAcc, contentDocAcc) { + async function (browser, iframeDocAcc) { ok(iframeDocAcc, "IFRAME document accessible is present"); await testBoundsWithContent(iframeDocAcc, "rotate", browser); @@ -60,7 +60,7 @@ addAccessibleTask( // test basic scale addAccessibleTask( `<p id="scale">hello world</p>`, - async function (browser, iframeDocAcc, contentDocAcc) { + async function (browser, iframeDocAcc) { ok(iframeDocAcc, "IFRAME document accessible is present"); await testBoundsWithContent(iframeDocAcc, "scale", browser); diff --git a/accessible/tests/browser/bounds/browser_test_zoom.js b/accessible/tests/browser/bounds/browser_test_zoom.js index ac84e485a4..1af84d61d8 100644 --- a/accessible/tests/browser/bounds/browser_test_zoom.js +++ b/accessible/tests/browser/bounds/browser_test_zoom.js @@ -16,7 +16,11 @@ async function testContentBounds(browser, acc) { is(x, expectedX, "Wrong x coordinate of " + prettyAccName); is(y, expectedY, "Wrong y coordinate of " + prettyAccName); is(width, expectedWidth, "Wrong width of " + prettyAccName); - ok(height >= expectedHeight, "Wrong height of " + prettyAccName); + Assert.greaterOrEqual( + height, + expectedHeight, + "Wrong height of " + prettyAccName + ); } async function runTests(browser, accDoc) { diff --git a/accessible/tests/browser/bounds/browser_zero_area.js b/accessible/tests/browser/bounds/browser_zero_area.js index c0f9db2673..80954fbd1a 100644 --- a/accessible/tests/browser/bounds/browser_zero_area.js +++ b/accessible/tests/browser/bounds/browser_zero_area.js @@ -67,10 +67,10 @@ addAccessibleTask( const radio = findAccessibleChildByID(accDoc, "radio"); const contentDPR = await getContentDPR(browser); const [x, y, width, height] = getBounds(radio, contentDPR); - ok(x < 0, "X coordinate should be negative"); - ok(y > 0, "Y coordinate should be positive"); - ok(width > 0, "Width should be positive"); - ok(height > 0, "Height should be positive"); + Assert.less(x, 0, "X coordinate should be negative"); + Assert.greater(y, 0, "Y coordinate should be positive"); + Assert.greater(width, 0, "Width should be positive"); + Assert.greater(height, 0, "Height should be positive"); // Note: the exact values of x, y, width, and height // are inconsistent with the DOM element values of those // fields, so we don't check our bounds against them with diff --git a/accessible/tests/browser/browser_shutdown_acc_reference.js b/accessible/tests/browser/browser_shutdown_acc_reference.js index 1768095f94..975eab55a0 100644 --- a/accessible/tests/browser/browser_shutdown_acc_reference.js +++ b/accessible/tests/browser/browser_shutdown_acc_reference.js @@ -36,7 +36,7 @@ add_task(async function () { const [a11yShutdownObserver, a11yShutdownPromise] = shutdownAccService(); await a11yShutdownObserver; const a11yShutdown = new Promise((resolve, reject) => - a11yShutdownPromise.then(flag => + a11yShutdownPromise.then(() => canShutdown ? resolve() : reject("Accessible service was shut down incorrectly") diff --git a/accessible/tests/browser/browser_shutdown_doc_acc_reference.js b/accessible/tests/browser/browser_shutdown_doc_acc_reference.js index 8f7bf6d423..7d999d7d13 100644 --- a/accessible/tests/browser/browser_shutdown_doc_acc_reference.js +++ b/accessible/tests/browser/browser_shutdown_doc_acc_reference.js @@ -28,7 +28,7 @@ add_task(async function () { const [a11yShutdownObserver, a11yShutdownPromise] = shutdownAccService(); await a11yShutdownObserver; const a11yShutdown = new Promise((resolve, reject) => - a11yShutdownPromise.then(flag => + a11yShutdownPromise.then(() => canShutdown ? resolve() : reject("Accessible service was shut down incorrectly") diff --git a/accessible/tests/browser/browser_shutdown_multi_acc_reference_doc.js b/accessible/tests/browser/browser_shutdown_multi_acc_reference_doc.js index 273fc7175d..1200e02116 100644 --- a/accessible/tests/browser/browser_shutdown_multi_acc_reference_doc.js +++ b/accessible/tests/browser/browser_shutdown_multi_acc_reference_doc.js @@ -39,7 +39,7 @@ add_task(async function () { const [a11yShutdownObserver, a11yShutdownPromise] = shutdownAccService(); await a11yShutdownObserver; const a11yShutdown = new Promise((resolve, reject) => - a11yShutdownPromise.then(flag => + a11yShutdownPromise.then(() => canShutdown ? resolve() : reject("Accessible service was shut down incorrectly") diff --git a/accessible/tests/browser/browser_shutdown_multi_acc_reference_obj.js b/accessible/tests/browser/browser_shutdown_multi_acc_reference_obj.js index af21b3dc4c..346aa9b6c4 100644 --- a/accessible/tests/browser/browser_shutdown_multi_acc_reference_obj.js +++ b/accessible/tests/browser/browser_shutdown_multi_acc_reference_obj.js @@ -39,7 +39,7 @@ add_task(async function () { const [a11yShutdownObserver, a11yShutdownPromise] = shutdownAccService(); await a11yShutdownObserver; const a11yShutdown = new Promise((resolve, reject) => - a11yShutdownPromise.then(flag => + a11yShutdownPromise.then(() => canShutdown ? resolve() : reject("Accessible service was shut down incorrectly") diff --git a/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_doc.js b/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_doc.js index e4091c5216..84429cf077 100644 --- a/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_doc.js +++ b/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_doc.js @@ -30,7 +30,7 @@ add_task(async function () { <body id="body"><div id="div"></div></body> </html>`, }, - async function (browser) { + async function () { let docLoadedEvent = await docLoaded; let docAcc = docLoadedEvent.accessibleDocument; ok(docAcc, "Accessible document proxy is created"); @@ -46,7 +46,7 @@ add_task(async function () { const [a11yShutdownObserver, a11yShutdownPromise] = shutdownAccService(); await a11yShutdownObserver; const a11yShutdown = new Promise((resolve, reject) => - a11yShutdownPromise.then(flag => + a11yShutdownPromise.then(() => canShutdown ? resolve() : reject("Accessible service was shut down incorrectly") diff --git a/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_obj.js b/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_obj.js index f6eca362b0..b7356f3e6f 100644 --- a/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_obj.js +++ b/accessible/tests/browser/browser_shutdown_multi_proxy_acc_reference_obj.js @@ -30,7 +30,7 @@ add_task(async function () { <body id="body"><div id="div"></div></body> </html>`, }, - async function (browser) { + async function () { let docLoadedEvent = await docLoaded; let docAcc = docLoadedEvent.accessibleDocument; ok(docAcc, "Accessible document proxy is created"); @@ -46,7 +46,7 @@ add_task(async function () { const [a11yShutdownObserver, a11yShutdownPromise] = shutdownAccService(); await a11yShutdownObserver; const a11yShutdown = new Promise((resolve, reject) => - a11yShutdownPromise.then(flag => + a11yShutdownPromise.then(() => canShutdown ? resolve() : reject("Accessible service was shut down incorrectly") diff --git a/accessible/tests/browser/browser_shutdown_multi_reference.js b/accessible/tests/browser/browser_shutdown_multi_reference.js index a92f6faf61..49ee822afa 100644 --- a/accessible/tests/browser/browser_shutdown_multi_reference.js +++ b/accessible/tests/browser/browser_shutdown_multi_reference.js @@ -31,7 +31,7 @@ add_task(async function () { const [a11yShutdownObserver, a11yShutdownPromise] = shutdownAccService(); await a11yShutdownObserver; const a11yShutdown = new Promise((resolve, reject) => - a11yShutdownPromise.then(flag => + a11yShutdownPromise.then(() => canShutdown ? resolve() : reject("Accessible service was shut down incorrectly") diff --git a/accessible/tests/browser/browser_shutdown_parent_own_reference.js b/accessible/tests/browser/browser_shutdown_parent_own_reference.js index 472e977626..ffbe33f137 100644 --- a/accessible/tests/browser/browser_shutdown_parent_own_reference.js +++ b/accessible/tests/browser/browser_shutdown_parent_own_reference.js @@ -61,7 +61,7 @@ add_task(async function () { shutdownAccService(browser); await contentA11yShutdownObserver; const contentA11yShutdown = new Promise((resolve, reject) => - contentA11yShutdownPromise.then(flag => + contentA11yShutdownPromise.then(() => contentCanShutdown ? resolve() : reject("Accessible service was shut down incorrectly") diff --git a/accessible/tests/browser/browser_shutdown_proxy_acc_reference.js b/accessible/tests/browser/browser_shutdown_proxy_acc_reference.js index 7144cff019..47fa47da53 100644 --- a/accessible/tests/browser/browser_shutdown_proxy_acc_reference.js +++ b/accessible/tests/browser/browser_shutdown_proxy_acc_reference.js @@ -41,7 +41,7 @@ add_task(async function () { const [a11yShutdownObserver, a11yShutdownPromise] = shutdownAccService(); await a11yShutdownObserver; const a11yShutdown = new Promise((resolve, reject) => - a11yShutdownPromise.then(flag => + a11yShutdownPromise.then(() => canShutdown ? resolve() : reject("Accessible service was shut down incorrectly") diff --git a/accessible/tests/browser/browser_shutdown_proxy_doc_acc_reference.js b/accessible/tests/browser/browser_shutdown_proxy_doc_acc_reference.js index 6d4ad71f1e..72a424b21f 100644 --- a/accessible/tests/browser/browser_shutdown_proxy_doc_acc_reference.js +++ b/accessible/tests/browser/browser_shutdown_proxy_doc_acc_reference.js @@ -30,7 +30,7 @@ add_task(async function () { <body id="body"></body> </html>`, }, - async function (browser) { + async function () { let docLoadedEvent = await docLoaded; let docAcc = docLoadedEvent.accessibleDocument; ok(docAcc, "Accessible document proxy is created"); @@ -43,7 +43,7 @@ add_task(async function () { const [a11yShutdownObserver, a11yShutdownPromise] = shutdownAccService(); await a11yShutdownObserver; const a11yShutdown = new Promise((resolve, reject) => - a11yShutdownPromise.then(flag => + a11yShutdownPromise.then(() => canShutdown ? resolve() : reject("Accessible service was shut down incorrectly") diff --git a/accessible/tests/browser/browser_shutdown_remote_own_reference.js b/accessible/tests/browser/browser_shutdown_remote_own_reference.js index a30d191b53..83c68689b7 100644 --- a/accessible/tests/browser/browser_shutdown_remote_own_reference.js +++ b/accessible/tests/browser/browser_shutdown_remote_own_reference.js @@ -108,7 +108,7 @@ add_task(async function () { const [contentA11yShutdownObserver, contentA11yShutdownPromise] = shutdownAccService(browser); const contentA11yShutdown = new Promise((resolve, reject) => - contentA11yShutdownPromise.then(flag => + contentA11yShutdownPromise.then(() => contentCanShutdown ? resolve() : reject("Accessible service was shut down incorrectly") diff --git a/accessible/tests/browser/e10s/browser.toml b/accessible/tests/browser/e10s/browser.toml index dfac6b5219..914f839993 100644 --- a/accessible/tests/browser/e10s/browser.toml +++ b/accessible/tests/browser/e10s/browser.toml @@ -18,9 +18,12 @@ support-files = [ ] prefs = [ "javascript.options.asyncstack_capture_debuggee_only=false", - "dom.element.popover.enabled=true" + "dom.element.popover.enabled=true", + "accessibility.ARIAElementReflection.enabled=true" ] +["browser_aria_activedescendant.js"] + # Caching tests ["browser_caching_actions.js"] diff --git a/accessible/tests/browser/e10s/browser_aria_activedescendant.js b/accessible/tests/browser/e10s/browser_aria_activedescendant.js new file mode 100644 index 0000000000..f58c5aab39 --- /dev/null +++ b/accessible/tests/browser/e10s/browser_aria_activedescendant.js @@ -0,0 +1,485 @@ +/* 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/role.js */ +/* import-globals-from ../../mochitest/states.js */ +loadScripts( + { name: "role.js", dir: MOCHITESTS_DIR }, + { name: "states.js", dir: MOCHITESTS_DIR } +); + +async function synthFocus(browser, container, item) { + let focusPromise = waitForEvent(EVENT_FOCUS, item); + await invokeContentTask(browser, [container], _container => { + let elm = ( + content.document._testGetElementById || content.document.getElementById + ).bind(content.document)(_container); + elm.focus(); + }); + await focusPromise; +} + +async function changeARIAActiveDescendant( + browser, + container, + itemId, + prevItemId, + elementReflection +) { + let expectedEvents = [[EVENT_FOCUS, itemId]]; + + if (prevItemId) { + info("A state change of the previous item precedes the new one."); + expectedEvents.push( + stateChangeEventArgs(prevItemId, EXT_STATE_ACTIVE, false, true) + ); + } + + expectedEvents.push( + stateChangeEventArgs(itemId, EXT_STATE_ACTIVE, true, true) + ); + + let expectedPromise = waitForEvents(expectedEvents); + await invokeContentTask( + browser, + [container, itemId, elementReflection], + (_container, _itemId, _elementReflection) => { + let getElm = ( + content.document._testGetElementById || content.document.getElementById + ).bind(content.document); + let elm = getElm(_container); + if (_elementReflection) { + elm.ariaActiveDescendantElement = getElm(_itemId); + } else { + elm.setAttribute("aria-activedescendant", _itemId); + } + } + ); + + await expectedPromise; +} + +async function clearARIAActiveDescendant( + browser, + container, + prevItemId, + defaultId, + elementReflection +) { + let expectedEvents = [[EVENT_FOCUS, defaultId || container]]; + if (prevItemId) { + expectedEvents.push( + stateChangeEventArgs(prevItemId, EXT_STATE_ACTIVE, false, true) + ); + } + + if (defaultId) { + expectedEvents.push( + stateChangeEventArgs(defaultId, EXT_STATE_ACTIVE, true, true) + ); + } + + let expectedPromise = waitForEvents(expectedEvents); + await invokeContentTask( + browser, + [container, elementReflection], + (_container, _elementReflection) => { + let elm = ( + content.document._testGetElementById || content.document.getElementById + ).bind(content.document)(_container); + if (_elementReflection) { + elm.ariaActiveDescendantElement = null; + } else { + elm.removeAttribute("aria-activedescendant"); + } + } + ); + + await expectedPromise; +} + +async function insertItemNFocus( + browser, + container, + newItemID, + prevItemId, + elementReflection +) { + let expectedEvents = [ + [EVENT_SHOW, newItemID], + [EVENT_FOCUS, newItemID], + ]; + + if (prevItemId) { + info("A state change of the previous item precedes the new one."); + expectedEvents.push( + stateChangeEventArgs(prevItemId, EXT_STATE_ACTIVE, false, true) + ); + } + + expectedEvents.push( + stateChangeEventArgs(newItemID, EXT_STATE_ACTIVE, true, true) + ); + + let expectedPromise = waitForEvents(expectedEvents); + + await invokeContentTask( + browser, + [container, newItemID, elementReflection], + (_container, _newItemID, _elementReflection) => { + let elm = ( + content.document._testGetElementById || content.document.getElementById + ).bind(content.document)(_container); + let itemElm = content.document.createElement("div"); + itemElm.setAttribute("id", _newItemID); + itemElm.setAttribute("role", "listitem"); + itemElm.textContent = _newItemID; + elm.appendChild(itemElm); + if (_elementReflection) { + elm.ariaActiveDescendantElement = itemElm; + } else { + elm.setAttribute("aria-activedescendant", _newItemID); + } + } + ); + + await expectedPromise; +} + +async function moveARIAActiveDescendantID(browser, fromID, toID) { + let expectedEvents = [ + [EVENT_FOCUS, toID], + stateChangeEventArgs(toID, EXT_STATE_ACTIVE, true, true), + ]; + + let expectedPromise = waitForEvents(expectedEvents); + await invokeContentTask(browser, [fromID, toID], (_fromID, _toID) => { + let orig = ( + content.document._testGetElementById || content.document.getElementById + ).bind(content.document)(_toID); + if (orig) { + orig.id = ""; + } + ( + content.document._testGetElementById || content.document.getElementById + ).bind(content.document)(_fromID).id = _toID; + }); + await expectedPromise; +} + +async function changeARIAActiveDescendantInvalid( + browser, + container, + invalidID = "invalid", + prevItemId = null +) { + let expectedEvents = [[EVENT_FOCUS, container]]; + if (prevItemId) { + expectedEvents.push( + stateChangeEventArgs(prevItemId, EXT_STATE_ACTIVE, false, true) + ); + } + + let expectedPromise = waitForEvents(expectedEvents); + await invokeContentTask( + browser, + [container, invalidID], + (_container, _invalidID) => { + let elm = ( + content.document._testGetElementById || content.document.getElementById + ).bind(content.document)(_container); + elm.setAttribute("aria-activedescendant", _invalidID); + } + ); + + await expectedPromise; +} + +const LISTBOX_MARKUP = ` +<div role="listbox" aria-activedescendant="item1" id="listbox" tabindex="1" +aria-owns="item3"> +<div role="listitem" id="item1">item1</div> +<div role="listitem" id="item2">item2</div> +<div role="listitem" id="roaming" data-id="roaming">roaming</div> +<div role="listitem" id="roaming2" data-id="roaming2">roaming2</div> +</div> +<div role="listitem" id="item3">item3</div> +<div role="combobox" id="combobox"> +<input id="combobox_entry"> +<ul> + <li role="option" id="combobox_option1">option1</li> + <li role="option" id="combobox_option2">option2</li> +</ul> +</div>`; + +async function basicListboxTest(browser, elementReflection) { + await synthFocus(browser, "listbox", "item1"); + await changeARIAActiveDescendant( + browser, + "listbox", + "item2", + "item1", + elementReflection + ); + await changeARIAActiveDescendant( + browser, + "listbox", + "item3", + "item2", + elementReflection + ); + + info("Focus out of listbox"); + await synthFocus(browser, "combobox_entry", "combobox_entry"); + await changeARIAActiveDescendant( + browser, + "combobox", + "combobox_option2", + null, + elementReflection + ); + await changeARIAActiveDescendant( + browser, + "combobox", + "combobox_option1", + null, + elementReflection + ); + + info("Focus back in listbox"); + await synthFocus(browser, "listbox", "item3"); + await insertItemNFocus( + browser, + "listbox", + "item4", + "item3", + elementReflection + ); + + await clearARIAActiveDescendant( + browser, + "listbox", + "item4", + null, + elementReflection + ); + await changeARIAActiveDescendant( + browser, + "listbox", + "item1", + null, + elementReflection + ); +} + +addAccessibleTask( + LISTBOX_MARKUP, + async function (browser, docAcc) { + info("Test aria-activedescendant content attribute"); + await basicListboxTest(browser, false); + + await changeARIAActiveDescendantInvalid( + browser, + "listbox", + "invalid", + "item1" + ); + + await changeARIAActiveDescendant(browser, "listbox", "roaming"); + await moveARIAActiveDescendantID(browser, "roaming2", "roaming"); + await changeARIAActiveDescendantInvalid( + browser, + "listbox", + "roaming3", + "roaming" + ); + await moveARIAActiveDescendantID(browser, "roaming", "roaming3"); + }, + { topLevel: true, chrome: true } +); + +addAccessibleTask( + LISTBOX_MARKUP, + async function (browser, docAcc) { + info("Test ariaActiveDescendantElement element reflection"); + await basicListboxTest(browser, true); + }, + { topLevel: true, chrome: true } +); + +addAccessibleTask( + ` +<input id="activedesc_nondesc_input" aria-activedescendant="activedesc_nondesc_option"> +<div role="listbox"> + <div role="option" id="activedesc_nondesc_option">option</div> +</div>`, + async function (browser, docAcc) { + info("Test aria-activedescendant non-descendant"); + await synthFocus( + browser, + "activedesc_nondesc_input", + "activedesc_nondesc_option" + ); + }, + { topLevel: true, chrome: true } +); + +addAccessibleTask( + ` +<div id="shadow"></div> +<script> + let host = document.getElementById("shadow"); + let shadow = host.attachShadow({mode: "open"}); + let listbox = document.createElement("div"); + listbox.id = "shadowListbox"; + listbox.setAttribute("role", "listbox"); + listbox.setAttribute("tabindex", "0"); + shadow.appendChild(listbox); + let item = document.createElement("div"); + item.id = "shadowItem1"; + item.setAttribute("role", "option"); + listbox.appendChild(item); + listbox.setAttribute("aria-activedescendant", "shadowItem1"); + item = document.createElement("div"); + item.id = "shadowItem2"; + item.setAttribute("role", "option"); + listbox.appendChild(item); +</script>`, + async function (browser, docAcc) { + info("Test aria-activedescendant in shadow root"); + // We want to retrieve elements using their IDs inside the shadow root, so + // we define a custom get element by ID method that our utility functions + // above call into if it exists. + await invokeContentTask(browser, [], () => { + content.document._testGetElementById = id => + content.document.getElementById("shadow").shadowRoot.getElementById(id); + }); + + await synthFocus(browser, "shadowListbox", "shadowItem1"); + await changeARIAActiveDescendant( + browser, + "shadowListbox", + "shadowItem2", + "shadowItem1" + ); + info("Do it again with element reflection"); + await changeARIAActiveDescendant( + browser, + "shadowListbox", + "shadowItem1", + "shadowItem2", + true + ); + }, + { topLevel: true, chrome: true } +); + +addAccessibleTask( + ` +<div id="comboboxWithHiddenList" tabindex="0" role="combobox" aria-owns="hiddenList"> +</div> +<div id="hiddenList" hidden role="listbox"> + <div id="hiddenListOption" role="option"></div> +</div>`, + async function (browser, docAcc) { + info("Test simultaneous insertion, relocation and aria-activedescendant"); + await synthFocus( + browser, + "comboboxWithHiddenList", + "comboboxWithHiddenList" + ); + + testStates( + findAccessibleChildByID(docAcc, "comboboxWithHiddenList"), + STATE_FOCUSED + ); + let evtProm = Promise.all([ + waitForEvent(EVENT_FOCUS, "hiddenListOption"), + waitForStateChange("hiddenListOption", EXT_STATE_ACTIVE, true, true), + ]); + await invokeContentTask(browser, [], () => { + info("hiddenList is owned, so unhiding causes insertion and relocation."); + ( + content.document._testGetElementById || content.document.getElementById + ).bind(content.document)("hiddenList").hidden = false; + content.document + .getElementById("comboboxWithHiddenList") + .setAttribute("aria-activedescendant", "hiddenListOption"); + }); + await evtProm; + testStates( + findAccessibleChildByID(docAcc, "hiddenListOption"), + STATE_FOCUSED + ); + }, + { topLevel: true, chrome: true } +); + +addAccessibleTask( + ` +<custom-listbox id="custom-listbox1"> + <div role="listitem" id="l1_1"></div> + <div role="listitem" id="l1_2"></div> + <div role="listitem" id="l1_3"></div> +</custom-listbox> + +<custom-listbox id="custom-listbox2" aria-activedescendant="l2_1"> + <div role="listitem" id="l2_1"></div> + <div role="listitem" id="l2_2"></div> + <div role="listitem" id="l2_3"></div> +</custom-listbox> + +<script> +customElements.define("custom-listbox", + class extends HTMLElement { + constructor() { + super(); + this.tabIndex = "0" + this._internals = this.attachInternals(); + this._internals.role = "listbox"; + this._internals.ariaActiveDescendantElement = this.lastElementChild; + } + get internals() { + return this._internals; + } + } +); +</script>`, + async function (browser, docAcc) { + await synthFocus(browser, "custom-listbox1", "l1_3"); + + let evtProm = Promise.all([ + waitForEvent(EVENT_FOCUS, "l1_2"), + waitForStateChange("l1_3", EXT_STATE_ACTIVE, false, true), + waitForStateChange("l1_2", EXT_STATE_ACTIVE, true, true), + ]); + + await invokeContentTask(browser, [], () => { + content.document.getElementById( + "custom-listbox1" + ).internals.ariaActiveDescendantElement = + content.document.getElementById("l1_2"); + }); + + await evtProm; + + evtProm = Promise.all([ + waitForEvent(EVENT_FOCUS, "custom-listbox1"), + waitForStateChange("l1_2", EXT_STATE_ACTIVE, false, true), + ]); + + await invokeContentTask(browser, [], () => { + content.document.getElementById( + "custom-listbox1" + ).internals.ariaActiveDescendantElement = null; + }); + + await evtProm; + + await synthFocus(browser, "custom-listbox2", "l2_1"); + await clearARIAActiveDescendant(browser, "custom-listbox2", "l2_1", "l2_3"); + } +); diff --git a/accessible/tests/browser/e10s/browser_caching_attributes.js b/accessible/tests/browser/e10s/browser_caching_attributes.js index 139015061f..7a1f90ec13 100644 --- a/accessible/tests/browser/e10s/browser_caching_attributes.js +++ b/accessible/tests/browser/e10s/browser_caching_attributes.js @@ -733,7 +733,7 @@ addAccessibleTask( */ addAccessibleTask( `<div id="popover" popover>popover</div>`, - async function testIspopup(browser, docAcc) { + async function testIspopup(browser) { info("Showing popover"); let shown = waitForEvent(EVENT_SHOW, "popover"); await invokeContentTask(browser, [], () => { diff --git a/accessible/tests/browser/e10s/browser_caching_large_update.js b/accessible/tests/browser/e10s/browser_caching_large_update.js index ccf8a86921..9a36ac7326 100644 --- a/accessible/tests/browser/e10s/browser_caching_large_update.js +++ b/accessible/tests/browser/e10s/browser_caching_large_update.js @@ -8,59 +8,56 @@ * Test a large update which adds many thousands of Accessibles with a * lot of content in each. */ -addAccessibleTask( - `<main id="main" hidden></main>`, - async function (browser, docAcc) { - let shown = waitForEvent(EVENT_SHOW, "main"); - await invokeContentTask(browser, [], () => { - // Make a long string. - let text = ""; - for (let i = 0; i < 100; ++i) { - text += "a"; - } - // Create lots of nodes which include the long string. - const contMain = content.document.getElementById("main"); - // 15000 children of main. - for (let w = 0; w < 15000; ++w) { - // Each of those goes 9 deep. - let parent = contMain; - for (let d = 0; d < 10; ++d) { - const div = content.document.createElement("div"); - div.setAttribute("aria-label", `${w} ${d} ${text}`); - parent.append(div); - parent = div; - } - } - contMain.hidden = false; - }); - const main = (await shown).accessible; - is(main.childCount, 15000, "main has correct number of children"); - - // We don't want to output passes for every check, since that would output - // hundreds of thousands of lines, which slows the test to a crawl. Instead, - // output any failures and keep track of overall success/failure. - let treeOk = true; - function check(val, msg) { - if (!val) { - ok(false, msg); - treeOk = false; - } +addAccessibleTask(`<main id="main" hidden></main>`, async function (browser) { + let shown = waitForEvent(EVENT_SHOW, "main"); + await invokeContentTask(browser, [], () => { + // Make a long string. + let text = ""; + for (let i = 0; i < 100; ++i) { + text += "a"; } - - info("Checking tree"); + // Create lots of nodes which include the long string. + const contMain = content.document.getElementById("main"); + // 15000 children of main. for (let w = 0; w < 15000; ++w) { - let acc = main.getChildAt(w); - let parent = main; + // Each of those goes 9 deep. + let parent = contMain; for (let d = 0; d < 10; ++d) { - check(acc, `Got child ${w} depth ${d}`); - const name = `${w} ${d}`; - check(acc.name.startsWith(name + " "), `${name}: correct name`); - check(acc.parent == parent, `${name}: correct parent`); - parent = acc; - acc = acc.firstChild; + const div = content.document.createElement("div"); + div.setAttribute("aria-label", `${w} ${d} ${text}`); + parent.append(div); + parent = div; } } - // check() sets treeOk to false for any failure. - ok(treeOk, "Tree is correct"); + contMain.hidden = false; + }); + const main = (await shown).accessible; + is(main.childCount, 15000, "main has correct number of children"); + + // We don't want to output passes for every check, since that would output + // hundreds of thousands of lines, which slows the test to a crawl. Instead, + // output any failures and keep track of overall success/failure. + let treeOk = true; + function check(val, msg) { + if (!val) { + ok(false, msg); + treeOk = false; + } + } + + info("Checking tree"); + for (let w = 0; w < 15000; ++w) { + let acc = main.getChildAt(w); + let parent = main; + for (let d = 0; d < 10; ++d) { + check(acc, `Got child ${w} depth ${d}`); + const name = `${w} ${d}`; + check(acc.name.startsWith(name + " "), `${name}: correct name`); + check(acc.parent == parent, `${name}: correct parent`); + parent = acc; + acc = acc.firstChild; + } } -); + // check() sets treeOk to false for any failure. + ok(treeOk, "Tree is correct"); +}); diff --git a/accessible/tests/browser/e10s/browser_caching_name.js b/accessible/tests/browser/e10s/browser_caching_name.js index 55f506b85a..383d268d7d 100644 --- a/accessible/tests/browser/e10s/browser_caching_name.js +++ b/accessible/tests/browser/e10s/browser_caching_name.js @@ -477,7 +477,7 @@ markupTests.forEach(({ id, ruleset, markup, expected }) => markup, async function (browser, accDoc) { const observer = { - observe(subject, topic, data) { + observe(subject) { const event = subject.QueryInterface(nsIAccessibleEvent); console.log(eventToString(event)); }, diff --git a/accessible/tests/browser/e10s/browser_caching_relations_002.js b/accessible/tests/browser/e10s/browser_caching_relations_002.js index 072656eb5e..61d92ba4ac 100644 --- a/accessible/tests/browser/e10s/browser_caching_relations_002.js +++ b/accessible/tests/browser/e10s/browser_caching_relations_002.js @@ -293,7 +293,7 @@ addAccessibleTask( ); /** - * Test details relations on popovers and their invokers. + * Test details relations for the popovertarget content attribute. */ addAccessibleTask( ` @@ -304,7 +304,7 @@ addAccessibleTask( <div id="popover" popover>popover</div> <div id="details">details</div> `, - async function testPopover(browser, docAcc) { + async function testPopoverContent(browser, docAcc) { // The popover is hidden, so nothing should be referring to it. const hide = findAccessibleChildByID(docAcc, "hide"); await testCachedRelation(hide, RELATION_DETAILS, []); @@ -330,7 +330,7 @@ addAccessibleTask( await testCachedRelation(toggleSibling, RELATION_DETAILS, []); await testCachedRelation(popover, RELATION_DETAILS_FOR, toggle1); - info("Setting toggle2 popovertargetaction"); + info("Setting toggle2 popovertarget"); await invokeSetAttribute(browser, "toggle2", "popovertarget", "popover"); await testCachedRelation(toggle2, RELATION_DETAILS, popover); await testCachedRelation(popover, RELATION_DETAILS_FOR, [toggle1, toggle2]); @@ -364,3 +364,106 @@ addAccessibleTask( }, { chrome: false, topLevel: true } ); + +/** + * Test details relations for the popoverTargetElement WebIDL attribute. + */ +addAccessibleTask( + ` +<button id="toggle1">toggle1</button> +<button id="toggle2">toggle2</button> +between +<div id="popover1" popover>popover1</div> +<button id="toggle3">toggle3</button> +<div id="shadowHost"><template shadowrootmode="open"> + <button id="toggle4">toggle4</button> + between + <div id="popover2" popover>popover2</div> + <button id="toggle5">toggle5</button> +</template></div> +<script> + const toggle1 = document.getElementById("toggle1"); + const popover1 = document.getElementById("popover1"); + toggle1.popoverTargetElement = popover1; + const toggle3 = document.getElementById("toggle3"); + const shadow = document.getElementById("shadowHost").shadowRoot; + const toggle4 = shadow.getElementById("toggle4"); + const popover2 = shadow.getElementById("popover2"); + toggle3.popoverTargetElement = popover2; + toggle4.popoverTargetElement = popover2; + const toggle5 = shadow.getElementById("toggle5"); + toggle5.popoverTargetElement = popover1; +</script> + `, + async function testPopoverIdl(browser, docAcc) { + // No popover is showing, so there shouldn't be any details relations. + const toggle1 = findAccessibleChildByID(docAcc, "toggle1"); + await testCachedRelation(toggle1, RELATION_DETAILS, []); + const toggle2 = findAccessibleChildByID(docAcc, "toggle2"); + await testCachedRelation(toggle2, RELATION_DETAILS, []); + const toggle3 = findAccessibleChildByID(docAcc, "toggle3"); + await testCachedRelation(toggle3, RELATION_DETAILS, []); + const toggle4 = findAccessibleChildByID(docAcc, "toggle4"); + await testCachedRelation(toggle4, RELATION_DETAILS, []); + const toggle5 = findAccessibleChildByID(docAcc, "toggle5"); + await testCachedRelation(toggle5, RELATION_DETAILS, []); + + info("Showing popover1"); + let shown = waitForEvent(EVENT_SHOW, "popover1"); + toggle1.doAction(0); + const popover1 = (await shown).accessible; + await testCachedRelation(toggle1, RELATION_DETAILS, popover1); + // toggle5 is inside the shadow DOM and popover1 is outside, so the target + // is valid. + await testCachedRelation(toggle5, RELATION_DETAILS, popover1); + await testCachedRelation(popover1, RELATION_DETAILS_FOR, [ + toggle1, + toggle5, + ]); + info("Setting toggle2's popover target to popover1"); + await invokeContentTask(browser, [], () => { + const toggle2Dom = content.document.getElementById("toggle2"); + const popover1Dom = content.document.getElementById("popover1"); + toggle2Dom.popoverTargetElement = popover1Dom; + }); + await testCachedRelation(toggle2, RELATION_DETAILS, popover1); + await testCachedRelation(popover1, RELATION_DETAILS_FOR, [ + toggle1, + toggle2, + toggle5, + ]); + info("Clearing toggle2's popover target"); + await invokeContentTask(browser, [], () => { + const toggle2Dom = content.document.getElementById("toggle2"); + toggle2Dom.popoverTargetElement = null; + }); + await testCachedRelation(toggle2, RELATION_DETAILS, []); + await testCachedRelation(popover1, RELATION_DETAILS_FOR, [ + toggle1, + toggle5, + ]); + info("Hiding popover1"); + let hidden = waitForEvent(EVENT_HIDE, popover1); + toggle1.doAction(0); + await hidden; + await testCachedRelation(toggle1, RELATION_DETAILS, []); + await testCachedRelation(toggle2, RELATION_DETAILS, []); + await testCachedRelation(toggle5, RELATION_DETAILS, []); + + info("Showing popover2"); + shown = waitForEvent(EVENT_SHOW, "popover2"); + toggle4.doAction(0); + const popover2 = (await shown).accessible; + // toggle4 is in the same shadow DOM as popover2. + await testCachedRelation(toggle4, RELATION_DETAILS, popover2); + // toggle3 is outside popover2's shadow DOM, so the target isn't valid. + await testCachedRelation(toggle3, RELATION_DETAILS, []); + await testCachedRelation(popover2, RELATION_DETAILS_FOR, [toggle4]); + info("Hiding popover2"); + hidden = waitForEvent(EVENT_HIDE, popover2); + toggle4.doAction(0); + await hidden; + await testCachedRelation(toggle4, RELATION_DETAILS, []); + }, + { chrome: true, topLevel: true } +); diff --git a/accessible/tests/browser/e10s/browser_caching_states.js b/accessible/tests/browser/e10s/browser_caching_states.js index 37f8c46966..7292228f25 100644 --- a/accessible/tests/browser/e10s/browser_caching_states.js +++ b/accessible/tests/browser/e10s/browser_caching_states.js @@ -3,6 +3,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ "use strict"; +requestLongerTimeout(2); /* import-globals-from ../../mochitest/role.js */ /* import-globals-from ../../mochitest/states.js */ @@ -484,7 +485,7 @@ addAccessibleTask( ); /** - * Test caching of the expanded state for popover target element. + * Test caching of the expanded state for the popovertarget content attribute. */ addAccessibleTask( ` @@ -550,3 +551,157 @@ addAccessibleTask( }, { chrome: true, topLevel: true, remoteIframe: true } ); + +/** + * Test caching of the expanded state for the popoverTargetElement WebIDL + * attribute. + */ +addAccessibleTask( + ` +<button id="toggle1">toggle</button> +<div id="popover1" popover>popover1</div> +<button id="toggle2">toggle2</button> +<button id="toggle3">toggle3</button> +<div id="shadowHost"><template shadowrootmode="open"> + <button id="toggle4">toggle4</button> + <div id="popover2" popover>popover2</div> + <button id="toggle5">toggle5</button> +</template></div> +<script> + const toggle1 = document.getElementById("toggle1"); + const popover1 = document.getElementById("popover1"); + toggle1.popoverTargetElement = popover1; + const toggle3 = document.getElementById("toggle3"); + const shadow = document.getElementById("shadowHost").shadowRoot; + const toggle4 = shadow.getElementById("toggle4"); + const popover2 = shadow.getElementById("popover2"); + toggle3.popoverTargetElement = popover2; + toggle4.popoverTargetElement = popover2; + const toggle5 = shadow.getElementById("toggle5"); + toggle5.popoverTargetElement = popover1; +</script> + `, + async function (browser, docAcc) { + const toggle1 = findAccessibleChildByID(docAcc, "toggle1"); + // toggle1's popover target is set and connected to the document. + testStates(toggle1, STATE_COLLAPSED); + + const toggle2 = findAccessibleChildByID(docAcc, "toggle2"); + // toggle2's popover target isn't set yet. + testStates( + toggle2, + 0, + 0, + STATE_EXPANDED | STATE_COLLAPSED, + EXT_STATE_EXPANDABLE + ); + info("Setting toggle2's popoverTargetElement"); + let changed = waitForStateChange(toggle2, EXT_STATE_EXPANDABLE, true, true); + await invokeContentTask(browser, [], () => { + const toggle2Dom = content.document.getElementById("toggle2"); + const popover1 = content.document.getElementById("popover1"); + toggle2Dom.popoverTargetElement = popover1; + }); + await changed; + testStates(toggle2, STATE_COLLAPSED); + + const toggle5 = findAccessibleChildByID(docAcc, "toggle5"); + // toggle5 is inside the shadow DOM and popover1 is outside, so the target + // is valid. + testStates(toggle5, STATE_COLLAPSED); + + // Changes to the popover should fire events on all invokers. + const changeEvents = [ + [EVENT_STATE_CHANGE, toggle1], + [EVENT_STATE_CHANGE, toggle2], + [EVENT_STATE_CHANGE, toggle5], + ]; + info("Showing popover1"); + changed = waitForEvents(changeEvents); + toggle1.doAction(0); + await changed; + testStates(toggle1, STATE_EXPANDED); + testStates(toggle2, STATE_EXPANDED); + + info("Hiding popover1"); + changed = waitForEvents(changeEvents); + toggle1.doAction(0); + await changed; + testStates(toggle1, STATE_COLLAPSED); + testStates(toggle2, STATE_COLLAPSED); + + info("Clearing toggle1's popover target"); + changed = waitForStateChange(toggle1, EXT_STATE_EXPANDABLE, false, true); + await invokeContentTask(browser, [], () => { + const toggle1Dom = content.document.getElementById("toggle1"); + toggle1Dom.popoverTargetElement = null; + }); + await changed; + testStates( + toggle1, + 0, + 0, + STATE_EXPANDED | STATE_COLLAPSED, + EXT_STATE_EXPANDABLE + ); + + info("Setting toggle2's popover target to a disconnected node"); + changed = waitForStateChange(toggle2, EXT_STATE_EXPANDABLE, false, true); + await invokeContentTask(browser, [], () => { + const toggle2Dom = content.document.getElementById("toggle2"); + const popover3 = content.document.createElement("div"); + popover3.popover = "auto"; + popover3.textContent = "popover3"; + // We don't append popover3 anywhere, so it is disconnected. + toggle2Dom.popoverTargetElement = popover3; + }); + await changed; + testStates( + toggle2, + 0, + 0, + STATE_EXPANDED | STATE_COLLAPSED, + EXT_STATE_EXPANDABLE + ); + + const toggle3 = findAccessibleChildByID(docAcc, "toggle3"); + // toggle3 is outside popover2's shadow DOM, so the target isn't valid. + testStates( + toggle3, + 0, + 0, + STATE_EXPANDED | STATE_COLLAPSED, + EXT_STATE_EXPANDABLE + ); + const toggle4 = findAccessibleChildByID(docAcc, "toggle4"); + // toggle4 is in the same shadow DOM as popover2. + testStates(toggle4, STATE_COLLAPSED); + }, + { chrome: true, topLevel: true } +); + +/** + * Test the mixed state of indeterminate HTML checkboxes. + */ +addAccessibleTask( + `<input type="checkbox" id="checkbox">`, + async function testHTMLCheckboxMixed(browser, docAcc) { + const checkbox = findAccessibleChildByID(docAcc, "checkbox"); + testStates(checkbox, 0, 0, STATE_MIXED); + info("Setting indeterminate on checkbox"); + let changed = waitForStateChange(checkbox, STATE_MIXED, true); + await invokeContentTask(browser, [], () => { + content.document.getElementById("checkbox").indeterminate = true; + }); + await changed; + testStates(checkbox, STATE_MIXED); + info("Clearing indeterminate on checkbox"); + changed = waitForStateChange(checkbox, STATE_MIXED, false); + await invokeContentTask(browser, [], () => { + content.document.getElementById("checkbox").indeterminate = false; + }); + await changed; + testStates(checkbox, 0, 0, STATE_MIXED); + }, + { chrome: true, topLevel: true, iframe: true, remoteIframe: true } +); diff --git a/accessible/tests/browser/e10s/browser_caching_table.js b/accessible/tests/browser/e10s/browser_caching_table.js index 9c8bcb9616..0329e6411b 100644 --- a/accessible/tests/browser/e10s/browser_caching_table.js +++ b/accessible/tests/browser/e10s/browser_caching_table.js @@ -482,7 +482,7 @@ addAccessibleTask( */ addAccessibleTask( `<table><tr id="tr"></tr></table>`, - async function (browser, docAcc) { + async function (browser) { let reordered = waitForEvent(EVENT_REORDER, "tr"); await invokeContentTask(browser, [], () => { const iframe = content.document.createElement("iframe"); diff --git a/accessible/tests/browser/e10s/browser_caching_text_bounds.js b/accessible/tests/browser/e10s/browser_caching_text_bounds.js index 3e37bf7490..486e28df53 100644 --- a/accessible/tests/browser/e10s/browser_caching_text_bounds.js +++ b/accessible/tests/browser/e10s/browser_caching_text_bounds.js @@ -138,9 +138,13 @@ async function testLineWithNonRenderedSpace(docAcc, browser, id, length) { const w = {}; const h = {}; acc.getCharacterExtents(offset, x, y, w, h, COORDTYPE_SCREEN_RELATIVE); - ok(x.value > prevX, `${id}: offset ${offset} x is larger (${x.value})`); + Assert.greater( + x.value, + prevX, + `${id}: offset ${offset} x is larger (${x.value})` + ); prevX = x.value; - ok(w.value > 0, `${id}: offset ${offset} width > 0`); + Assert.greater(w.value, 0, `${id}: offset ${offset} width > 0`); } } @@ -566,7 +570,11 @@ c</textarea> {}, COORDTYPE_SCREEN_RELATIVE ); - ok(newY.value < oldY.value, "y coordinate smaller after scrolling down"); + Assert.less( + newY.value, + oldY.value, + "y coordinate smaller after scrolling down" + ); }, { chrome: true, topLevel: true, iframe: !true } ); diff --git a/accessible/tests/browser/e10s/browser_file_input.js b/accessible/tests/browser/e10s/browser_file_input.js index 238e48740e..4c68e8e6da 100644 --- a/accessible/tests/browser/e10s/browser_file_input.js +++ b/accessible/tests/browser/e10s/browser_file_input.js @@ -34,7 +34,7 @@ addAccessibleTask( function chooseFile(id) { return invokeContentTask(browser, [id], contentId => { const MockFilePicker = content.SpecialPowers.MockFilePicker; - MockFilePicker.init(content); + MockFilePicker.init(content.browsingContext); MockFilePicker.useBlobFile(); MockFilePicker.returnValue = MockFilePicker.returnOK; const input = content.document.getElementById(contentId); diff --git a/accessible/tests/browser/e10s/browser_treeupdate_select_dropdown.js b/accessible/tests/browser/e10s/browser_treeupdate_select_dropdown.js index a82fc4c04d..8ccbe58751 100644 --- a/accessible/tests/browser/e10s/browser_treeupdate_select_dropdown.js +++ b/accessible/tests/browser/e10s/browser_treeupdate_select_dropdown.js @@ -24,7 +24,7 @@ const snippet = ` addAccessibleTask( snippet, - async function (browser, accDoc) { + async function (browser) { await invokeFocus(browser, "select"); // Expand the select. A dropdown item should get focus. // Note that the dropdown is rendered in the parent process. diff --git a/accessible/tests/browser/events/browser_test_docload.js b/accessible/tests/browser/events/browser_test_docload.js index 78ac77fd8c..12076b3002 100644 --- a/accessible/tests/browser/events/browser_test_docload.js +++ b/accessible/tests/browser/events/browser_test_docload.js @@ -30,7 +30,7 @@ function urlChecker(url) { }; } -async function runTests(browser, accDoc) { +async function runTests(browser) { let onLoadEvents = waitForEvents({ expected: [ [EVENT_REORDER, getAccessible(browser)], diff --git a/accessible/tests/browser/events/browser_test_focus_browserui.js b/accessible/tests/browser/events/browser_test_focus_browserui.js index 969d336c74..2f67cb3681 100644 --- a/accessible/tests/browser/events/browser_test_focus_browserui.js +++ b/accessible/tests/browser/events/browser_test_focus_browserui.js @@ -11,7 +11,7 @@ loadScripts( { name: "role.js", dir: MOCHITESTS_DIR } ); -async function runTests(browser, accDoc) { +async function runTests(browser) { await SpecialPowers.pushPrefEnv({ // If Fission is disabled, the pref is no-op. set: [["fission.bfcacheInParent", true]], diff --git a/accessible/tests/browser/events/browser_test_focus_dialog.js b/accessible/tests/browser/events/browser_test_focus_dialog.js index 71485a678d..03a1b82dc1 100644 --- a/accessible/tests/browser/events/browser_test_focus_dialog.js +++ b/accessible/tests/browser/events/browser_test_focus_dialog.js @@ -11,7 +11,7 @@ loadScripts( { name: "role.js", dir: MOCHITESTS_DIR } ); -async function runTests(browser, accDoc) { +async function runTests(browser) { let onFocus = waitForEvent(EVENT_FOCUS, "button"); await SpecialPowers.spawn(browser, [], () => { content.document.getElementById("button").focus(); diff --git a/accessible/tests/browser/events/browser_test_focus_urlbar.js b/accessible/tests/browser/events/browser_test_focus_urlbar.js index 68b2b07f3c..647b837e9f 100644 --- a/accessible/tests/browser/events/browser_test_focus_urlbar.js +++ b/accessible/tests/browser/events/browser_test_focus_urlbar.js @@ -68,10 +68,10 @@ class TipTestProvider extends UrlbarProvider { get type() { return UrlbarUtils.PROVIDER_TYPE.PROFILE; } - isActive(context) { + isActive() { return true; } - isRestricting(context) { + isRestricting() { return true; } async startQuery(context, addCallback) { diff --git a/accessible/tests/browser/events/browser_test_scrolling.js b/accessible/tests/browser/events/browser_test_scrolling.js index 9678ee767b..d9425721bf 100644 --- a/accessible/tests/browser/events/browser_test_scrolling.js +++ b/accessible/tests/browser/events/browser_test_scrolling.js @@ -25,13 +25,15 @@ c</textarea> }); let [scrollEvent1, scrollEndEvent1] = await onScrolling; scrollEvent1.QueryInterface(nsIAccessibleScrollingEvent); - ok( - scrollEvent1.maxScrollY >= scrollEvent1.scrollY, + Assert.greaterOrEqual( + scrollEvent1.maxScrollY, + scrollEvent1.scrollY, "scrollY is within max" ); scrollEndEvent1.QueryInterface(nsIAccessibleScrollingEvent); - ok( - scrollEndEvent1.maxScrollY >= scrollEndEvent1.scrollY, + Assert.greaterOrEqual( + scrollEndEvent1.maxScrollY, + scrollEndEvent1.scrollY, "scrollY is within max" ); @@ -44,13 +46,15 @@ c</textarea> }); let [scrollEvent2, scrollEndEvent2] = await onScrolling; scrollEvent2.QueryInterface(nsIAccessibleScrollingEvent); - ok( - scrollEvent2.scrollY > scrollEvent1.scrollY, + Assert.greater( + scrollEvent2.scrollY, + scrollEvent1.scrollY, `${scrollEvent2.scrollY} > ${scrollEvent1.scrollY}` ); scrollEndEvent2.QueryInterface(nsIAccessibleScrollingEvent); - ok( - scrollEndEvent2.maxScrollY >= scrollEndEvent2.scrollY, + Assert.greaterOrEqual( + scrollEndEvent2.maxScrollY, + scrollEndEvent2.scrollY, "scrollY is within max" ); @@ -63,17 +67,20 @@ c</textarea> }); let [scrollEvent3, scrollEndEvent3] = await onScrolling; scrollEvent3.QueryInterface(nsIAccessibleScrollingEvent); - ok( - scrollEvent3.maxScrollX >= scrollEvent3.scrollX, + Assert.greaterOrEqual( + scrollEvent3.maxScrollX, + scrollEvent3.scrollX, "scrollX is within max" ); scrollEndEvent3.QueryInterface(nsIAccessibleScrollingEvent); - ok( - scrollEndEvent3.maxScrollX >= scrollEndEvent3.scrollX, + Assert.greaterOrEqual( + scrollEndEvent3.maxScrollX, + scrollEndEvent3.scrollX, "scrollY is within max" ); - ok( - scrollEvent3.scrollX > scrollEvent2.scrollX, + Assert.greater( + scrollEvent3.scrollX, + scrollEvent2.scrollX, `${scrollEvent3.scrollX} > ${scrollEvent2.scrollX}` ); @@ -87,13 +94,15 @@ c</textarea> }); let [scrollEvent4, scrollEndEvent4] = await onScrolling; scrollEvent4.QueryInterface(nsIAccessibleScrollingEvent); - ok( - scrollEvent4.maxScrollY >= scrollEvent4.scrollY, + Assert.greaterOrEqual( + scrollEvent4.maxScrollY, + scrollEvent4.scrollY, "scrollY is within max" ); scrollEndEvent4.QueryInterface(nsIAccessibleScrollingEvent); - ok( - scrollEndEvent4.maxScrollY >= scrollEndEvent4.scrollY, + Assert.greaterOrEqual( + scrollEndEvent4.maxScrollY, + scrollEndEvent4.scrollY, "scrollY is within max" ); @@ -119,7 +128,7 @@ addAccessibleTask( <p>b</p> <p id="c">c</p> `, - async function (browser, accDoc) { + async function (browser) { let onScrollingStart = waitForEvent(EVENT_SCROLLING_START, "c"); await SpecialPowers.spawn(browser, [], () => { content.location.hash = "#c"; @@ -137,7 +146,7 @@ addAccessibleTask( <h1 style="height: 300%;" id="inside-scrollable">test</h1> </div> `, - async function (browser, accDoc) { + async function (browser) { let onScrollingStart = waitForEvent( EVENT_SCROLLING_START, "inside-scrollable" diff --git a/accessible/tests/browser/mac/browser_app.js b/accessible/tests/browser/mac/browser_app.js index bedefae440..e7e18b5ddd 100644 --- a/accessible/tests/browser/mac/browser_app.js +++ b/accessible/tests/browser/mac/browser_app.js @@ -138,7 +138,7 @@ add_task(async () => { gBrowser, url: "about:license", }, - async browser => { + async () => { let root = await getMacAccessible(document); let rootChildCount = () => root.getAttributeValue("AXChildren").length; @@ -206,8 +206,10 @@ add_task(async () => { is(rootChildCount(), baseRootChildCount + 1, "Root has another child"); // Close popup + let hide = waitForMacEvent("AXUIElementDestroyed"); EventUtils.synthesizeKey("KEY_Escape"); await BrowserTestUtils.waitForPopupEvent(identityPopup, "hidden"); + await hide; // We're back to the base child count is(rootChildCount(), baseRootChildCount, "Root has the base child count"); @@ -225,7 +227,7 @@ add_task(async () => { // eslint-disable-next-line @microsoft/sdl/no-insecure-url url: "http://example.com", }, - async browser => { + async () => { let input = await getMacAccessible("urlbar-input"); is( input.getAttributeValue("AXValue"), @@ -238,6 +240,38 @@ add_task(async () => { }); /** + * Tests attributed text in nav bar has no invisible AXAttachments + */ +add_task(async () => { + await BrowserTestUtils.withNewTab( + { + gBrowser, + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + url: "http://example.com", + }, + async () => { + let root = await getMacAccessible(document); + let navBar = await getMacAccessible("nav-bar"); + let elemRange = root.getParameterizedAttributeValue( + "AXTextMarkerRangeForUIElement", + navBar + ); + let attributedString = root.getParameterizedAttributeValue( + "AXAttributedStringForTextMarkerRange", + elemRange + ); + let attachmentRoles = attributedString.map(s => + s.AXAttachment ? s.AXAttachment.getAttributeValue("AXRole") : null + ); + ok( + !attachmentRoles.includes("AXMenu"), + "Collapsed menu should be embedded in attributed text" + ); + } + ); +}); + +/** * Test context menu */ add_task(async () => { diff --git a/accessible/tests/browser/mac/browser_bounds.js b/accessible/tests/browser/mac/browser_bounds.js index 09343d7c9d..bc7939cfe0 100644 --- a/accessible/tests/browser/mac/browser_bounds.js +++ b/accessible/tests/browser/mac/browser_bounds.js @@ -21,22 +21,26 @@ addAccessibleTask( // test them here instead of calling AXFrame directly. const [helloWidth, helloHeight] = hello.getAttributeValue("AXSize"); const [worldWidth, worldHeight] = world.getAttributeValue("AXSize"); - ok(helloWidth > 0, "Hello has a positive width"); - ok(helloHeight > 0, "Hello has a positive height"); - ok(worldWidth > 0, "World has a positive width"); - ok(worldHeight > 0, "World has a positive height"); - ok(helloHeight < worldHeight, "Hello has a smaller height than world"); - ok(helloWidth < worldWidth, "Hello has a smaller width than world"); + Assert.greater(helloWidth, 0, "Hello has a positive width"); + Assert.greater(helloHeight, 0, "Hello has a positive height"); + Assert.greater(worldWidth, 0, "World has a positive width"); + Assert.greater(worldHeight, 0, "World has a positive height"); + Assert.less( + helloHeight, + worldHeight, + "Hello has a smaller height than world" + ); + Assert.less(helloWidth, worldWidth, "Hello has a smaller width than world"); // Note: these are mac screen coords, so our origin is bottom left const [helloX, helloY] = hello.getAttributeValue("AXPosition"); const [worldX, worldY] = world.getAttributeValue("AXPosition"); - ok(helloX > 0, "Hello has a positive X"); - ok(helloY > 0, "Hello has a positive Y"); - ok(worldX > 0, "World has a positive X"); - ok(worldY > 0, "World has a positive Y"); - ok(helloY > worldY, "Hello has a larger Y than world"); - ok(helloX == worldX, "Hello and world have the same X"); + Assert.greater(helloX, 0, "Hello has a positive X"); + Assert.greater(helloY, 0, "Hello has a positive Y"); + Assert.greater(worldX, 0, "World has a positive X"); + Assert.greater(worldY, 0, "World has a positive Y"); + Assert.greater(helloY, worldY, "Hello has a larger Y than world"); + Assert.equal(helloX, worldX, "Hello and world have the same X"); } ); @@ -57,21 +61,25 @@ addAccessibleTask( // test them here instead of calling AXFrame directly. const [helloWidth, helloHeight] = hello.getAttributeValue("AXSize"); const [worldWidth, worldHeight] = world.getAttributeValue("AXSize"); - ok(helloWidth > 0, "Hello has a positive width"); - ok(helloHeight > 0, "Hello has a positive height"); - ok(worldWidth > 0, "World has a positive width"); - ok(worldHeight > 0, "World has a positive height"); - ok(helloHeight < worldHeight, "Hello has a smaller height than world"); - ok(helloWidth < worldWidth, "Hello has a smaller width than world"); + Assert.greater(helloWidth, 0, "Hello has a positive width"); + Assert.greater(helloHeight, 0, "Hello has a positive height"); + Assert.greater(worldWidth, 0, "World has a positive width"); + Assert.greater(worldHeight, 0, "World has a positive height"); + Assert.less( + helloHeight, + worldHeight, + "Hello has a smaller height than world" + ); + Assert.less(helloWidth, worldWidth, "Hello has a smaller width than world"); // Note: these are mac screen coords, so our origin is bottom left const [helloX, helloY] = hello.getAttributeValue("AXPosition"); const [worldX, worldY] = world.getAttributeValue("AXPosition"); - ok(helloX < 0, "Hello has a negative X"); - ok(helloY > 0, "Hello has a positive Y"); - ok(worldX < 0, "World has a negative X"); - ok(worldY > 0, "World has a positive Y"); - ok(helloY > worldY, "Hello has a larger Y than world"); - ok(helloX == worldX, "Hello and world have the same X"); + Assert.less(helloX, 0, "Hello has a negative X"); + Assert.greater(helloY, 0, "Hello has a positive Y"); + Assert.less(worldX, 0, "World has a negative X"); + Assert.greater(worldY, 0, "World has a positive Y"); + Assert.greater(helloY, worldY, "Hello has a larger Y than world"); + Assert.equal(helloX, worldX, "Hello and world have the same X"); } ); diff --git a/accessible/tests/browser/mac/browser_live_regions.js b/accessible/tests/browser/mac/browser_live_regions.js index 10a03120f8..aa07f003df 100644 --- a/accessible/tests/browser/mac/browser_live_regions.js +++ b/accessible/tests/browser/mac/browser_live_regions.js @@ -131,7 +131,7 @@ addAccessibleTask( <button id="button" aria-label="Start"></button> </div> `, - async (browser, accDoc) => { + async browser => { let liveRegionChanged = waitForMacEvent("AXLiveRegionChanged", "live"); await SpecialPowers.spawn(browser, [], () => { content.document.getElementById("time").textContent = "4:56pm"; diff --git a/accessible/tests/browser/mac/browser_menulist.js b/accessible/tests/browser/mac/browser_menulist.js index b26a0be782..3b0fe8b210 100644 --- a/accessible/tests/browser/mac/browser_menulist.js +++ b/accessible/tests/browser/mac/browser_menulist.js @@ -74,7 +74,7 @@ addAccessibleTask( "First menu item is selected" ); // focus the second item, and verify it is selected - event = waitForMacEvent("AXFocusedUIElementChanged", (iface, data) => { + event = waitForMacEvent("AXFocusedUIElementChanged", iface => { try { return iface.getAttributeValue("AXTitle") == "100%"; } catch (e) { diff --git a/accessible/tests/browser/mac/browser_roles_elements.js b/accessible/tests/browser/mac/browser_roles_elements.js index 791598fed6..b6049e7afd 100644 --- a/accessible/tests/browser/mac/browser_roles_elements.js +++ b/accessible/tests/browser/mac/browser_roles_elements.js @@ -47,6 +47,7 @@ addAccessibleTask( <div id="complementary" role="complementary"></div> <div id="contentinfo" role="contentinfo"></div> <div id="form" role="form"></div> + <div id="form_label" aria-label="form" role="form"></div> <div id="main" role="main"></div> <div id="navigation" role="navigation"></div> <div id="search" role="search"></div> @@ -149,7 +150,8 @@ addAccessibleTask( "AXLandmarkComplementary" ); testRoleAndSubRole(accDoc, "contentinfo", null, "AXLandmarkContentInfo"); - testRoleAndSubRole(accDoc, "form", null, "AXLandmarkForm"); + testRoleAndSubRole(accDoc, "form", null, "AXApplicationGroup"); + testRoleAndSubRole(accDoc, "form_label", null, "AXLandmarkForm"); testRoleAndSubRole(accDoc, "main", null, "AXLandmarkMain"); testRoleAndSubRole(accDoc, "navigation", null, "AXLandmarkNavigation"); testRoleAndSubRole(accDoc, "search", null, "AXLandmarkSearch"); diff --git a/accessible/tests/browser/mac/browser_rotor.js b/accessible/tests/browser/mac/browser_rotor.js index 3f13506757..87ac40592d 100644 --- a/accessible/tests/browser/mac/browser_rotor.js +++ b/accessible/tests/browser/mac/browser_rotor.js @@ -269,7 +269,7 @@ addAccessibleTask( "AXUIElementCountForSearchPredicate", NSDictionary(searchPred) ); - is(4, tableCount, "Found four tables"); + is(tableCount, 3, "Found three tables"); const tables = webArea.getParameterizedAttributeValue( "AXUIElementsForSearchPredicate", @@ -278,7 +278,6 @@ addAccessibleTask( const shapes = getNativeInterface(accDoc, "shapes"); const food = getNativeInterface(accDoc, "food"); const ariaTable = getNativeInterface(accDoc, "ariaTable"); - const grid = getNativeInterface(accDoc, "grid"); is( shapes.getAttributeValue("AXColumnCount"), @@ -295,11 +294,6 @@ addAccessibleTask( tables[2].getAttributeValue("AXColumnCount"), "Found correct third table" ); - is( - grid.getAttributeValue("AXColumnCount"), - tables[3].getAttributeValue("AXColumnCount"), - "Found correct fourth table" - ); } ); diff --git a/accessible/tests/browser/mac/browser_text_leaf.js b/accessible/tests/browser/mac/browser_text_leaf.js index 21deed6212..c65e8c6ebe 100644 --- a/accessible/tests/browser/mac/browser_text_leaf.js +++ b/accessible/tests/browser/mac/browser_text_leaf.js @@ -77,7 +77,11 @@ addAccessibleTask( NSRange(3, 8) ); - ok(smallBounds.size[0] < largeBounds.size[0], "longer range is wider"); + Assert.less( + smallBounds.size[0], + largeBounds.size[0], + "longer range is wider" + ); }, { chrome: true, iframe: true, remoteIframe: true } ); diff --git a/accessible/tests/browser/mac/browser_text_selection.js b/accessible/tests/browser/mac/browser_text_selection.js index a914adba8e..7e2145631c 100644 --- a/accessible/tests/browser/mac/browser_text_selection.js +++ b/accessible/tests/browser/mac/browser_text_selection.js @@ -82,7 +82,7 @@ addAccessibleTask( Hello <a href="#" id="link">World</a>, I <a href="#" style="user-select: none;" id="unselectable_link">love</a> <button id="button">you</button></p>`, - async (browser, accDoc) => { + async browser => { // Set up an AXSelectedTextChanged listener here. It will get resolved // on the first non-root event it encounters, so if we test its data at the end // of this test it will show us the first text-selectable object that was focused, diff --git a/accessible/tests/browser/mac/browser_toggle_radio_check.js b/accessible/tests/browser/mac/browser_toggle_radio_check.js index 1695d73b0d..f9094ac3d7 100644 --- a/accessible/tests/browser/mac/browser_toggle_radio_check.js +++ b/accessible/tests/browser/mac/browser_toggle_radio_check.js @@ -128,7 +128,7 @@ addAccessibleTask( // Changing from checked to mixed fires two events. Make sure we wait until // the second so we're asserting based on the latest state. - evt = waitForMacEvent("AXValueChanged", (iface, data) => { + evt = waitForMacEvent("AXValueChanged", iface => { return ( iface.getAttributeValue("AXDOMIdentifier") == "checkbox" && iface.getAttributeValue("AXValue") == 2 diff --git a/accessible/tests/browser/mac/browser_webarea.js b/accessible/tests/browser/mac/browser_webarea.js index ac6122de14..4872c58845 100644 --- a/accessible/tests/browser/mac/browser_webarea.js +++ b/accessible/tests/browser/mac/browser_webarea.js @@ -8,8 +8,8 @@ loadScripts({ name: "role.js", dir: MOCHITESTS_DIR }); // Test web area role and AXLoadComplete event -addAccessibleTask(``, async (browser, accDoc) => { - let evt = waitForMacEvent("AXLoadComplete", (iface, data) => { +addAccessibleTask(``, async browser => { + let evt = waitForMacEvent("AXLoadComplete", iface => { return iface.getAttributeValue("AXDescription") == "webarea test"; }); await SpecialPowers.spawn(browser, [], () => { @@ -29,16 +29,16 @@ addAccessibleTask(``, async (browser, accDoc) => { }); // Test iframe web area role and AXLayoutComplete event -addAccessibleTask(`<title>webarea test</title>`, async (browser, accDoc) => { +addAccessibleTask(`<title>webarea test</title>`, async browser => { // If the iframe loads before the top level document finishes loading, we'll // get both an AXLayoutComplete event for the iframe and an AXLoadComplete // event for the document. Otherwise, if the iframe loads after the // document, we'll get one AXLoadComplete event. let eventPromise = Promise.race([ - waitForMacEvent("AXLayoutComplete", (iface, data) => { + waitForMacEvent("AXLayoutComplete", iface => { return iface.getAttributeValue("AXDescription") == "iframe document"; }), - waitForMacEvent("AXLoadComplete", (iface, data) => { + waitForMacEvent("AXLoadComplete", iface => { return iface.getAttributeValue("AXDescription") == "webarea test"; }), ]); diff --git a/accessible/tests/browser/scroll/browser_test_scroll_bounds.js b/accessible/tests/browser/scroll/browser_test_scroll_bounds.js index 31de002cda..33a99266db 100644 --- a/accessible/tests/browser/scroll/browser_test_scroll_bounds.js +++ b/accessible/tests/browser/scroll/browser_test_scroll_bounds.js @@ -238,7 +238,11 @@ addAccessibleTask( newTopBounds[0], "x of non-fixed element remains accurate." ); - ok(newTopBounds[1] < 0, "y coordinate shows item scrolled off page"); + Assert.less( + newTopBounds[1], + 0, + "y coordinate shows item scrolled off page" + ); is( origTopBounds[2], newTopBounds[2], @@ -254,7 +258,11 @@ addAccessibleTask( newDBounds[0], "x of non-fixed container element remains accurate." ); - ok(newDBounds[1] < 0, "y coordinate shows container scrolled off page"); + Assert.less( + newDBounds[1], + 0, + "y coordinate shows container scrolled off page" + ); // Removing the position styling on this acc causes it to be bound by // its parent's bounding box, which alters its width as a block element. // We don't particularly care about width in this test, so skip it. @@ -481,7 +489,7 @@ addAccessibleTask( newBounds[0], `x coord of non-sticky element remains accurate.` ); - ok(newBounds[1] < 0, "y coordinate shows item scrolled off page"); + Assert.less(newBounds[1], 0, "y coordinate shows item scrolled off page"); // Removing the position styling on this acc causes it to be bound by // its parent's bounding box, which alters its width as a block element. diff --git a/accessible/tests/browser/scroll/browser_test_scroll_substring.js b/accessible/tests/browser/scroll/browser_test_scroll_substring.js index e8426d00ca..031b8a5124 100644 --- a/accessible/tests/browser/scroll/browser_test_scroll_substring.js +++ b/accessible/tests/browser/scroll/browser_test_scroll_substring.js @@ -45,8 +45,9 @@ The only thing I found in the fridge was a dead dove in a bag. text.getCharacterExtents(7, {}, objY, {}, {}, COORDTYPE_SCREEN_RELATIVE); return objY.value; }; - ok( - containerHeight < getCharY(), + Assert.less( + containerHeight, + getCharY(), "Character is outside of container bounds" ); text.scrollSubstringTo(7, 8, SCROLL_TYPE_TOP_EDGE); diff --git a/accessible/tests/browser/selectable/browser_test_select.js b/accessible/tests/browser/selectable/browser_test_select.js index f86a371d81..6a51fd4f3b 100644 --- a/accessible/tests/browser/selectable/browser_test_select.js +++ b/accessible/tests/browser/selectable/browser_test_select.js @@ -313,7 +313,7 @@ addAccessibleTask( </select> </form> `, - async function (browser, docAcc) { + async function (browser) { let selected = waitForEvent(EVENT_SELECTION_WITHIN, "select"); await invokeContentTask(browser, [], () => { const form = content.document.getElementById("form"); diff --git a/accessible/tests/browser/shared-head.js b/accessible/tests/browser/shared-head.js index fe87a77765..c238a5a7a0 100644 --- a/accessible/tests/browser/shared-head.js +++ b/accessible/tests/browser/shared-head.js @@ -830,7 +830,7 @@ const CACHE_WAIT_TIMEOUT_MS = 5000; * be used to record a pass or fail in the test. */ function untilCacheCondition(conditionFunc, argsFunc) { - return new Promise((resolve, reject) => { + return new Promise(resolve => { let args = argsFunc(); if (conditionFunc(...args)) { resolve(args); @@ -838,7 +838,7 @@ function untilCacheCondition(conditionFunc, argsFunc) { } let cacheObserver = { - observe(subject) { + observe() { args = argsFunc(); if (conditionFunc(...args)) { clearTimeout(this.timer); @@ -945,7 +945,7 @@ function runPython(code) { "ws://mochi.test:8888/browser/accessible/tests/browser/python_runner" ); if (gPythonSocket.readyState != WebSocket.OPEN) { - gPythonSocket.onopen = evt => { + gPythonSocket.onopen = () => { gPythonSocket.send(code); gPythonSocket.onopen = null; }; diff --git a/accessible/tests/browser/text/browser_text_paragraph_boundary.js b/accessible/tests/browser/text/browser_text_paragraph_boundary.js index 04e64520e8..b206829398 100644 --- a/accessible/tests/browser/text/browser_text_paragraph_boundary.js +++ b/accessible/tests/browser/text/browser_text_paragraph_boundary.js @@ -8,7 +8,7 @@ // boundary on an Accessible which has remote ProxyAccessible descendants. addAccessibleTask( `test`, - async function testParagraphBoundaryWithRemoteDescendants(browser, accDoc) { + async function testParagraphBoundaryWithRemoteDescendants() { const root = getRootAccessible(document).QueryInterface( Ci.nsIAccessibleText ); diff --git a/accessible/tests/browser/text/head.js b/accessible/tests/browser/text/head.js index fa4b095892..72195ddbb0 100644 --- a/accessible/tests/browser/text/head.js +++ b/accessible/tests/browser/text/head.js @@ -142,7 +142,7 @@ function testBoundarySequence( // Editable text async function waitForCopy(browser) { - await BrowserTestUtils.waitForContentEvent(browser, "copy", false, evt => { + await BrowserTestUtils.waitForContentEvent(browser, "copy", false, () => { return true; }); diff --git a/accessible/tests/browser/tree/browser_aria_owns.js b/accessible/tests/browser/tree/browser_aria_owns.js index 0ca55ed357..904597cc66 100644 --- a/accessible/tests/browser/tree/browser_aria_owns.js +++ b/accessible/tests/browser/tree/browser_aria_owns.js @@ -176,7 +176,7 @@ addAccessibleTask( addAccessibleTask( ` <select id="container" aria-owns="boom" multiple></select>`, - async function (browser, accDoc) { + async function () { ok(true, "Did not crash"); } ); diff --git a/accessible/tests/browser/tree/browser_browser_element.js b/accessible/tests/browser/tree/browser_browser_element.js index 82be24d93c..d6ece6676e 100644 --- a/accessible/tests/browser/tree/browser_browser_element.js +++ b/accessible/tests/browser/tree/browser_browser_element.js @@ -8,7 +8,7 @@ loadScripts({ name: "role.js", dir: MOCHITESTS_DIR }); // Test that the tree is correct for browser elements containing remote // documents. -addAccessibleTask(`test`, async function (browser, docAcc) { +addAccessibleTask(`test`, async function (browser) { // testAccessibleTree also verifies childCount, indexInParent and parent. testAccessibleTree(browser, { INTERNAL_FRAME: [{ DOCUMENT: [{ TEXT_LEAF: [] }] }], diff --git a/accessible/tests/browser/tree/browser_lazy_tabs.js b/accessible/tests/browser/tree/browser_lazy_tabs.js index f7aa9bdeb2..46e10d0bac 100644 --- a/accessible/tests/browser/tree/browser_lazy_tabs.js +++ b/accessible/tests/browser/tree/browser_lazy_tabs.js @@ -5,7 +5,7 @@ // Test that lazy background tabs aren't unintentionally loaded when building // the a11y tree (bug 1700708). -addAccessibleTask(``, async function (browser, accDoc) { +addAccessibleTask(``, async function () { await SpecialPowers.pushPrefEnv({ set: [["browser.sessionstore.restore_on_demand", true]], }); diff --git a/accessible/tests/browser/tree/browser_test_nsIAccessibleDocument_URL.js b/accessible/tests/browser/tree/browser_test_nsIAccessibleDocument_URL.js index 623f2640f0..e6b55d0fd3 100644 --- a/accessible/tests/browser/tree/browser_test_nsIAccessibleDocument_URL.js +++ b/accessible/tests/browser/tree/browser_test_nsIAccessibleDocument_URL.js @@ -25,7 +25,7 @@ async function promiseEventDocumentLoadComplete(expectedURL) { add_task(async function testInDataURI() { const kURL = "data:text/html,Some text"; const waitForDocumentLoadComplete = promiseEventDocumentLoadComplete(""); - await BrowserTestUtils.withNewTab(kURL, async browser => { + await BrowserTestUtils.withNewTab(kURL, async () => { is( (await waitForDocumentLoadComplete).URL, "", @@ -44,7 +44,7 @@ add_task(async function testInHTTPSURIContainingPrivateThings() { "https://example.com/browser/toolkit/content/tests/browser/file_empty.html?query=some#ref"; const waitForDocumentLoadComplete = promiseEventDocumentLoadComplete(kURLWithoutUserPass); - await BrowserTestUtils.withNewTab(kURL, async browser => { + await BrowserTestUtils.withNewTab(kURL, async () => { is( (await waitForDocumentLoadComplete).URL, kURLWithoutUserPass, diff --git a/accessible/tests/browser/windows/a11y_setup.py b/accessible/tests/browser/windows/a11y_setup.py index d6dc19f0fb..726eea07a4 100644 --- a/accessible/tests/browser/windows/a11y_setup.py +++ b/accessible/tests/browser/windows/a11y_setup.py @@ -9,19 +9,28 @@ import ctypes import os from ctypes import POINTER, byref from ctypes.wintypes import BOOL, HWND, LPARAM, POINT # noqa: F401 +from dataclasses import dataclass +import comtypes.automation import comtypes.client import psutil from comtypes import COMError, IServiceProvider +CHILDID_SELF = 0 +COWAIT_DEFAULT = 0 +EVENT_OBJECT_FOCUS = 0x8005 +GA_ROOT = 2 +NAVRELATION_EMBEDS = 0x1009 +OBJID_CLIENT = -4 +RPC_S_CALLPENDING = -2147417835 +WINEVENT_OUTOFCONTEXT = 0 +WM_CLOSE = 0x0010 + user32 = ctypes.windll.user32 oleacc = ctypes.oledll.oleacc oleaccMod = comtypes.client.GetModule("oleacc.dll") IAccessible = oleaccMod.IAccessible del oleaccMod -OBJID_CLIENT = -4 -CHILDID_SELF = 0 -NAVRELATION_EMBEDS = 0x1009 # This is the path if running locally. ia2Tlb = os.path.join( os.getcwd(), @@ -65,6 +74,13 @@ def AccessibleObjectFromWindow(hwnd, objectID=OBJID_CLIENT): return p +def getWindowClass(hwnd): + MAX_CHARS = 257 + buffer = ctypes.create_unicode_buffer(MAX_CHARS) + user32.GetClassNameW(hwnd, buffer, MAX_CHARS) + return buffer.value + + def getFirefoxHwnd(): """Search all top level windows for the Firefox instance being tested. @@ -78,9 +94,7 @@ def getFirefoxHwnd(): @ctypes.WINFUNCTYPE(BOOL, HWND, LPARAM) def callback(hwnd, lParam): - name = ctypes.create_unicode_buffer(100) - user32.GetClassNameW(hwnd, name, 100) - if name.value != "MozillaWindowClass": + if getWindowClass(hwnd) != "MozillaWindowClass": return True pid = ctypes.wintypes.DWORD() user32.GetWindowThreadProcessId(hwnd, byref(pid)) @@ -127,6 +141,106 @@ def findIa2ByDomId(root, id): return descendant +@dataclass +class WinEvent: + event: int + hwnd: int + objectId: int + childId: int + + def getIa2(self): + acc = ctypes.POINTER(IAccessible)() + child = comtypes.automation.VARIANT() + ctypes.oledll.oleacc.AccessibleObjectFromEvent( + self.hwnd, + self.objectId, + self.childId, + ctypes.byref(acc), + ctypes.byref(child), + ) + if child.value != CHILDID_SELF: + # This isn't an IAccessible2 object. + return None + return toIa2(acc) + + +class WaitForWinEvent: + """Wait for a win event, usually for IAccessible2. + This should be used as follows: + 1. Create an instance to wait for the desired event. + 2. Perform the action that should fire the event. + 3. Call wait() on the instance you created in 1) to wait for the event. + """ + + def __init__(self, eventId, match): + """event is the event id to wait for. + match is either None to match any object, an str containing the DOM id + of the desired object, or a function taking a WinEvent which should + return True if this is the requested event. + """ + self._matched = None + # A kernel event used to signal when we get the desired event. + self._signal = ctypes.windll.kernel32.CreateEventW(None, True, False, None) + + # We define this as a nested function because it has to be a static + # function, but we need a reference to self. + @ctypes.WINFUNCTYPE( + None, + ctypes.wintypes.HANDLE, + ctypes.wintypes.DWORD, + ctypes.wintypes.HWND, + ctypes.wintypes.LONG, + ctypes.wintypes.LONG, + ctypes.wintypes.DWORD, + ctypes.wintypes.DWORD, + ) + def winEventProc(hook, eventId, hwnd, objectId, childId, thread, time): + event = WinEvent(eventId, hwnd, objectId, childId) + if isinstance(match, str): + try: + ia2 = event.getIa2() + if f"id:{match};" in ia2.attributes: + self._matched = event + except (comtypes.COMError, TypeError): + pass + elif callable(match): + try: + if match(event): + self._matched = event + except Exception as e: + self._matched = e + if self._matched: + ctypes.windll.kernel32.SetEvent(self._signal) + + self._hook = user32.SetWinEventHook( + eventId, eventId, None, winEventProc, 0, 0, WINEVENT_OUTOFCONTEXT + ) + # Hold a reference to winEventProc so it doesn't get destroyed. + self._proc = winEventProc + + def wait(self): + """Wait for and return the desired WinEvent.""" + # Pump Windows messages until we get the desired event, which will be + # signalled using a kernel event. + handles = (ctypes.c_void_p * 1)(self._signal) + index = ctypes.wintypes.DWORD() + TIMEOUT = 10000 + try: + ctypes.oledll.ole32.CoWaitForMultipleHandles( + COWAIT_DEFAULT, TIMEOUT, 1, handles, ctypes.byref(index) + ) + except WindowsError as e: + if e.winerror == RPC_S_CALLPENDING: + raise TimeoutError("Timeout before desired event received") + raise + finally: + user32.UnhookWinEvent(self._hook) + self._proc = None + if isinstance(self._matched, Exception): + raise self._matched from self._matched + return self._matched + + def getDocUia(): """Get the IUIAutomationElement for the document being tested.""" # We start with IAccessible2 because there's no efficient way to diff --git a/accessible/tests/browser/windows/ia2/browser.toml b/accessible/tests/browser/windows/ia2/browser.toml index d72b5f8a2d..d6226b73cc 100644 --- a/accessible/tests/browser/windows/ia2/browser.toml +++ b/accessible/tests/browser/windows/ia2/browser.toml @@ -6,4 +6,6 @@ skip-if = [ ] support-files = ["head.js"] +["browser_osPicker.js"] + ["browser_role.js"] diff --git a/accessible/tests/browser/windows/ia2/browser_osPicker.js b/accessible/tests/browser/windows/ia2/browser_osPicker.js new file mode 100644 index 0000000000..b14f2d0a5f --- /dev/null +++ b/accessible/tests/browser/windows/ia2/browser_osPicker.js @@ -0,0 +1,51 @@ +/* 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"; + +addAccessibleTask( + `<input id="file" type="file">`, + async function (browser, docAcc) { + info("Focusing file input"); + await runPython(` + global focused + focused = WaitForWinEvent(EVENT_OBJECT_FOCUS, "file") + `); + const file = findAccessibleChildByID(docAcc, "file"); + file.takeFocus(); + await runPython(` + focused.wait() + `); + ok(true, "file input got focus"); + info("Opening file picker"); + await runPython(` + global focused + focused = WaitForWinEvent( + EVENT_OBJECT_FOCUS, + lambda evt: getWindowClass(evt.hwnd) == "Edit" + ) + `); + file.doAction(0); + await runPython(` + global event + event = focused.wait() + `); + ok(true, "Picker got focus"); + info("Dismissing picker"); + await runPython(` + # If the picker is dismissed too quickly, it seems to re-enable the root + # window before we do. This sleep isn't ideal, but it's more likely to + # reproduce the case that our root window gets focus before it is enabled. + # See bug 1883568 for further details. + import time + time.sleep(1) + focused = WaitForWinEvent(EVENT_OBJECT_FOCUS, "file") + # Sending key presses to the picker is unreliable, so use WM_CLOSE. + pickerRoot = user32.GetAncestor(event.hwnd, GA_ROOT) + user32.SendMessageW(pickerRoot, WM_CLOSE, 0, 0) + focused.wait() + `); + ok(true, "file input got focus"); + } +); diff --git a/accessible/tests/browser/windows/ia2/browser_role.js b/accessible/tests/browser/windows/ia2/browser_role.js index 08e44c280f..89b560ab49 100644 --- a/accessible/tests/browser/windows/ia2/browser_role.js +++ b/accessible/tests/browser/windows/ia2/browser_role.js @@ -12,7 +12,7 @@ addAccessibleTask( ` <p id="p">p</p> `, - async function (browser, docAcc) { + async function () { let role = await runPython(` global doc doc = getDocIa2() diff --git a/accessible/tests/browser/windows/uia/browser.toml b/accessible/tests/browser/windows/uia/browser.toml index f7974d69c7..d1513c1822 100644 --- a/accessible/tests/browser/windows/uia/browser.toml +++ b/accessible/tests/browser/windows/uia/browser.toml @@ -9,3 +9,5 @@ support-files = ["head.js"] ["browser_controlType.js"] ["browser_elementFromPoint.js"] + +["browser_tree.js"] diff --git a/accessible/tests/browser/windows/uia/browser_controlType.js b/accessible/tests/browser/windows/uia/browser_controlType.js index 16db892581..3bb994f437 100644 --- a/accessible/tests/browser/windows/uia/browser_controlType.js +++ b/accessible/tests/browser/windows/uia/browser_controlType.js @@ -9,11 +9,11 @@ const UIA_ButtonControlTypeId = 50000; const UIA_DocumentControlTypeId = 50030; /* eslint-enable camelcase */ -addAccessibleTask( +addUiaTask( ` <button id="button">button</button> `, - async function (browser, docAcc) { + async function () { let controlType = await runPython(` global doc doc = getDocUia() diff --git a/accessible/tests/browser/windows/uia/browser_elementFromPoint.js b/accessible/tests/browser/windows/uia/browser_elementFromPoint.js index e2fda4ab30..acf6fe91c7 100644 --- a/accessible/tests/browser/windows/uia/browser_elementFromPoint.js +++ b/accessible/tests/browser/windows/uia/browser_elementFromPoint.js @@ -4,12 +4,12 @@ "use strict"; -addAccessibleTask( +addUiaTask( ` <button id="button">button</p> <a id="a" href="#">a</a> `, - async function (browser, docAcc) { + async function () { ok( await runPython(` global doc diff --git a/accessible/tests/browser/windows/uia/browser_tree.js b/accessible/tests/browser/windows/uia/browser_tree.js new file mode 100644 index 0000000000..778609bedb --- /dev/null +++ b/accessible/tests/browser/windows/uia/browser_tree.js @@ -0,0 +1,104 @@ +/* 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"; + +async function testIsControl(pyVar, isControl) { + const result = await runPython(`bool(${pyVar}.CurrentIsControlElement)`); + if (isControl) { + ok(result, `${pyVar} is a control element`); + } else { + ok(!result, `${pyVar} isn't a control element`); + } +} + +/** + * Define a global Python variable and assign it to a given Python expression. + */ +function definePyVar(varName, expression) { + return runPython(` + global ${varName} + ${varName} = ${expression} + `); +} + +/** + * Get the UIA element with the given id and assign it to a global Python + * variable using the id as the variable name. + */ +function assignPyVarToUiaWithId(id) { + return definePyVar(id, `findUiaByDomId(doc, "${id}")`); +} + +addUiaTask( + ` +<p id="p">paragraph</p> +<div id="div">div</div> +<!-- The spans are because the UIA -> IA2 proxy seems to remove a single text + leaf child from even the raw tree. + --> +<a id="link" href="#">link<span> </span>></a> +<h1 id="h1">h1<span> </span></h1> +<h1 id="h1WithDiv"><div>h1 with div<span> </span></div></h1> +<input id="range" type="range"> +<div onclick=";" id="clickable">clickable</div> +<div id="editable" contenteditable>editable</div> +<table id="table"><tr><th>th</th></tr></table> + `, + async function (browser, docAcc) { + await definePyVar("doc", `getDocUia()`); + await assignPyVarToUiaWithId("p"); + await testIsControl("p", false); + await definePyVar( + "pTextLeaf", + `uiaClient.RawViewWalker.GetFirstChildElement(p)` + ); + await testIsControl("pTextLeaf", true); + await assignPyVarToUiaWithId("div"); + await testIsControl("div", false); + await definePyVar( + "divTextLeaf", + `uiaClient.RawViewWalker.GetFirstChildElement(div)` + ); + await testIsControl("divTextLeaf", true); + await assignPyVarToUiaWithId("link"); + await testIsControl("link", true); + await assignPyVarToUiaWithId("range"); + await testIsControl("range", true); + await assignPyVarToUiaWithId("editable"); + await testIsControl("editable", true); + await assignPyVarToUiaWithId("table"); + await testIsControl("table", true); + if (!gIsUiaEnabled) { + // The remaining tests are broken with the UIA -> IA2 proxy. + return; + } + await definePyVar( + "linkTextLeaf", + `uiaClient.RawViewWalker.GetFirstChildElement(link)` + ); + await testIsControl("linkTextLeaf", false); + await assignPyVarToUiaWithId("h1"); + await testIsControl("h1", true); + await definePyVar( + "h1TextLeaf", + `uiaClient.RawViewWalker.GetFirstChildElement(h1)` + ); + await testIsControl("h1TextLeaf", false); + await assignPyVarToUiaWithId("h1WithDiv"); + await testIsControl("h1WithDiv", true); + // h1WithDiv's text leaf is its grandchild. + await definePyVar( + "h1WithDivTextLeaf", + `uiaClient.RawViewWalker.GetFirstChildElement( + uiaClient.RawViewWalker.GetFirstChildElement( + h1WithDiv + ) + )` + ); + await testIsControl("h1WithDivTextLeaf", false); + await assignPyVarToUiaWithId("clickable"); + await testIsControl("clickable", true); + } +); diff --git a/accessible/tests/browser/windows/uia/head.js b/accessible/tests/browser/windows/uia/head.js index afc50984bd..e659354c7c 100644 --- a/accessible/tests/browser/windows/uia/head.js +++ b/accessible/tests/browser/windows/uia/head.js @@ -4,6 +4,8 @@ "use strict"; +/* exported gIsUiaEnabled, addUiaTask */ + // Load the shared-head file first. Services.scriptloader.loadSubScript( "chrome://mochitests/content/browser/accessible/tests/browser/shared-head.js", @@ -16,3 +18,38 @@ loadScripts( { name: "common.js", dir: MOCHITESTS_DIR }, { name: "promisified-events.js", dir: MOCHITESTS_DIR } ); + +let gIsUiaEnabled = false; + +/** + * This is like addAccessibleTask, but takes two additional boolean options: + * - uiaEnabled: Whether to run a variation of this test with Gecko UIA enabled. + * - uiaDisabled: Whether to run a variation of this test with UIA disabled. In + * this case, UIA will rely entirely on the IA2 -> UIA proxy. + * If both are set, the test will be run twice with different configurations. + * You can determine which variant is currently running using the gIsUiaEnabled + * variable. This is useful for conditional tests; e.g. if Gecko UIA supports + * something that the IA2 -> UIA proxy doesn't support. + */ +function addUiaTask(doc, task, options = {}) { + const { uiaEnabled = true, uiaDisabled = true } = options; + + function addTask(shouldEnable) { + async function uiaTask(browser, docAcc, topDocAcc) { + await SpecialPowers.pushPrefEnv({ + set: [["accessibility.uia.enable", shouldEnable]], + }); + gIsUiaEnabled = shouldEnable; + info(shouldEnable ? "Gecko UIA enabled" : "Gecko UIA disabled"); + await task(browser, docAcc, topDocAcc); + } + addAccessibleTask(doc, uiaTask, options); + } + + if (uiaEnabled) { + addTask(true); + } + if (uiaDisabled) { + addTask(false); + } +} diff --git a/accessible/tests/crashtests/crashtests.list b/accessible/tests/crashtests/crashtests.list index 2f628ddfe2..4787e09163 100644 --- a/accessible/tests/crashtests/crashtests.list +++ b/accessible/tests/crashtests/crashtests.list @@ -1,5 +1,5 @@ load 448064.xhtml # This test instantiates a11y, so be careful about adding tests before it -asserts-if(!browserIsRemote,2) load 884202.html +load 884202.html load 1572811.html load 1578282.html load 890760.html diff --git a/accessible/tests/mochitest/actions/test_media.html b/accessible/tests/mochitest/actions/test_media.html index 5327901e56..99393b984b 100644 --- a/accessible/tests/mochitest/actions/test_media.html +++ b/accessible/tests/mochitest/actions/test_media.html @@ -32,7 +32,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=483573 this.getID = function focusChecker_getID() { return "focus handling"; }; - this.check = function focusChecker_check(aEvent) { + this.check = function focusChecker_check() { testStates(this.target, STATE_FOCUSED); }; } diff --git a/accessible/tests/mochitest/actions/test_tree.xhtml b/accessible/tests/mochitest/actions/test_tree.xhtml index 17710cbdce..3279ac74ee 100644 --- a/accessible/tests/mochitest/actions/test_tree.xhtml +++ b/accessible/tests/mochitest/actions/test_tree.xhtml @@ -31,7 +31,7 @@ { this.__proto__ = new focusChecker(aAcc); - this.check = function focusChecker_check(aEvent) + this.check = function focusChecker_check() { var states = aStates ? aStates : 0; testStates(this.target, STATE_FOCUSED | STATE_SELECTED | states); @@ -71,7 +71,7 @@ actionIndex: 1, events: CLICK_EVENTS, targetID: treeBodyNode, - checkOnClickEvent: function check(aEvent) + checkOnClickEvent: function check() { testStates(this.ID, STATE_EXPANDED); } @@ -82,7 +82,7 @@ actionIndex: 1, events: CLICK_EVENTS, targetID: treeBodyNode, - checkOnClickEvent: function check(aEvent) + checkOnClickEvent: function check() { testStates(this.ID, STATE_COLLAPSED); } diff --git a/accessible/tests/mochitest/actions/test_treegrid.xhtml b/accessible/tests/mochitest/actions/test_treegrid.xhtml index 1c6e1bb8aa..985018418b 100644 --- a/accessible/tests/mochitest/actions/test_treegrid.xhtml +++ b/accessible/tests/mochitest/actions/test_treegrid.xhtml @@ -37,7 +37,7 @@ { return "focus handling"; } - this.check = function focusChecker_check(aEvent) + this.check = function focusChecker_check() { var states = aStates ? aStates : 0; testStates(this.target, STATE_FOCUSED | STATE_SELECTED | states); @@ -52,7 +52,7 @@ { return "state change handling"; } - this.check = function stateChangeChecker_check(aEvent) + this.check = function stateChangeChecker_check() { if (aIsEnabled) testStates(this.target, STATE_CHECKED); @@ -95,7 +95,7 @@ actionIndex: 1, events: CLICK_EVENTS, targetID: treeBodyNode, - check: function check(aEvent) + check: function check() { testStates(this.ID, STATE_EXPANDED); } @@ -106,7 +106,7 @@ actionIndex: 1, events: CLICK_EVENTS, targetID: treeBodyNode, - check: function check(aEvent) + check: function check() { testStates(this.ID, STATE_COLLAPSED); } diff --git a/accessible/tests/mochitest/autocomplete.js b/accessible/tests/mochitest/autocomplete.js index bd5458c51d..baf9529473 100644 --- a/accessible/tests/mochitest/autocomplete.js +++ b/accessible/tests/mochitest/autocomplete.js @@ -171,11 +171,11 @@ AutoCompleteResult.prototype = { return this.comments[aIndex]; }, - getStyleAt(aIndex) { + getStyleAt() { return null; }, - getImageAt(aIndex) { + getImageAt() { return ""; }, @@ -183,11 +183,11 @@ AutoCompleteResult.prototype = { return this.getValueAt(aIndex); }, - isRemovableAt(aRowIndex) { + isRemovableAt() { return true; }, - removeValueAt(aRowIndex) {}, + removeValueAt() {}, // nsISupports implementation QueryInterface: ChromeUtils.generateQI(["nsIAutoCompleteResult"]), diff --git a/accessible/tests/mochitest/common.js b/accessible/tests/mochitest/common.js index f0ee117452..7f40c33bff 100644 --- a/accessible/tests/mochitest/common.js +++ b/accessible/tests/mochitest/common.js @@ -976,7 +976,7 @@ function prettyName(aIdentifier) { * @param aString the string to shorten. * @returns the shortened string. */ -function shortenString(aString, aMaxLength) { +function shortenString(aString) { if (aString.length <= MAX_TRIM_LENGTH) { return aString; } diff --git a/accessible/tests/mochitest/events.js b/accessible/tests/mochitest/events.js index a6c216e01d..d4e3221f95 100644 --- a/accessible/tests/mochitest/events.js +++ b/accessible/tests/mochitest/events.js @@ -928,10 +928,7 @@ function eventQueue(aEventType) { return invoker.getID(); }; - this.setInvokerStatus = function eventQueue_setInvokerStatus( - aStatus, - aLogMsg - ) { + this.setInvokerStatus = function eventQueue_setInvokerStatus(aStatus) { this.mNextInvokerStatus = aStatus; // Uncomment it to debug invoker processing logic. @@ -2348,7 +2345,7 @@ var gA11yEventApplicantsCount = 0; var gA11yEventObserver = { // eslint-disable-next-line complexity - observe: function observe(aSubject, aTopic, aData) { + observe: function observe(aSubject, aTopic) { if (aTopic != "accessible-event") { return; } diff --git a/accessible/tests/mochitest/events/a11y.toml b/accessible/tests/mochitest/events/a11y.toml index 501b59f7b7..81f9fab3d9 100644 --- a/accessible/tests/mochitest/events/a11y.toml +++ b/accessible/tests/mochitest/events/a11y.toml @@ -40,8 +40,6 @@ support-files = [ ["test_flush.html"] -["test_focus_aria_activedescendant.html"] - ["test_focus_autocomplete.html"] ["test_focus_autocomplete.xhtml"] diff --git a/accessible/tests/mochitest/events/test_contextmenu.html b/accessible/tests/mochitest/events/test_contextmenu.html index 6200efc00d..3047b4d46c 100644 --- a/accessible/tests/mochitest/events/test_contextmenu.html +++ b/accessible/tests/mochitest/events/test_contextmenu.html @@ -52,7 +52,7 @@ }; } - function closeContextMenu(aID) { + function closeContextMenu() { this.eventSeq = [ new invokerChecker(EVENT_MENUPOPUP_END, getAccessible(getContextMenuNode())), diff --git a/accessible/tests/mochitest/events/test_focus_aria_activedescendant.html b/accessible/tests/mochitest/events/test_focus_aria_activedescendant.html deleted file mode 100644 index 661284619a..0000000000 --- a/accessible/tests/mochitest/events/test_focus_aria_activedescendant.html +++ /dev/null @@ -1,327 +0,0 @@ -<!DOCTYPE html> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=429547 ---> -<head> - <title>aria-activedescendant focus tests</title> - <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> - - <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - - <script type="application/javascript" - src="../common.js"></script> - <script type="application/javascript" - src="../role.js"></script> - <script type="application/javascript" - src="../states.js"></script> - <script type="application/javascript" - src="../events.js"></script> - - <script type="application/javascript"> - let PromEvents = {}; - Services.scriptloader.loadSubScript( - "chrome://mochitests/content/a11y/accessible/tests/mochitest/promisified-events.js", - PromEvents); - // gA11yEventDumpToConsole = true; // debugging - - function changeARIAActiveDescendant(aContainer, aItem, aPrevItemId) { - let itemID = Node.isInstance(aItem) ? aItem.id : aItem; - this.eventSeq = [new focusChecker(aItem)]; - - if (aPrevItemId) { - this.eventSeq.push( - new stateChangeChecker(EXT_STATE_ACTIVE, true, false, aPrevItemId) - ); - } - - this.eventSeq.push( - new stateChangeChecker(EXT_STATE_ACTIVE, true, true, aItem) - ); - - this.invoke = function changeARIAActiveDescendant_invoke() { - getNode(aContainer).setAttribute("aria-activedescendant", itemID); - }; - - this.getID = function changeARIAActiveDescendant_getID() { - return "change aria-activedescendant on " + itemID; - }; - } - - function clearARIAActiveDescendant(aID, aPrevItemId) { - this.eventSeq = [ - new focusChecker(aID), - ]; - - if (aPrevItemId) { - this.eventSeq.push( - new stateChangeChecker(EXT_STATE_ACTIVE, true, false, aPrevItemId) - ); - } - - this.invoke = function clearARIAActiveDescendant_invoke() { - getNode(aID).removeAttribute("aria-activedescendant"); - }; - - this.getID = function clearARIAActiveDescendant_getID() { - return "clear aria-activedescendant on container " + aID; - }; - } - - /** - * Change aria-activedescendant to an invalid (non-existent) id. - * Ensure that focus is fired on the element itself. - */ - function changeARIAActiveDescendantInvalid(aID, aInvalidID, aPrevItemId) { - if (!aInvalidID) { - aInvalidID = "invalid"; - } - - this.eventSeq = [ - new focusChecker(aID), - ]; - - if (aPrevItemId) { - this.eventSeq.push( - new stateChangeChecker(EXT_STATE_ACTIVE, true, false, aPrevItemId) - ); - } - - this.invoke = function changeARIAActiveDescendant_invoke() { - getNode(aID).setAttribute("aria-activedescendant", aInvalidID); - }; - - this.getID = function changeARIAActiveDescendant_getID() { - return "change aria-activedescendant to invalid id"; - }; - } - - function insertItemNFocus(aID, aNewItemID, aPrevItemId) { - this.eventSeq = [ - new invokerChecker(EVENT_SHOW, aNewItemID), - new focusChecker(aNewItemID), - ]; - - if (aPrevItemId) { - this.eventSeq.push( - new stateChangeChecker(EXT_STATE_ACTIVE, true, false, aPrevItemId) - ); - } - - this.eventSeq.push( - new stateChangeChecker(EXT_STATE_ACTIVE, true, true, aNewItemID) - ); - - this.invoke = function insertItemNFocus_invoke() { - var container = getNode(aID); - - var itemNode = document.createElement("div"); - itemNode.setAttribute("id", aNewItemID); - itemNode.setAttribute("role", "listitem"); - itemNode.textContent = aNewItemID; - container.appendChild(itemNode); - - container.setAttribute("aria-activedescendant", aNewItemID); - }; - - this.getID = function insertItemNFocus_getID() { - return "insert new node and focus it with ID: " + aNewItemID; - }; - } - - /** - * Change the id of an element to another id which is the target of - * aria-activedescendant. - * If another element already has the desired id, remove it from that - * element first. - * Ensure that focus is fired on the target element which was given the - * desired id. - * @param aFromID The existing id of the target element. - * @param aToID The desired id to be given to the target element. - */ - function moveARIAActiveDescendantID(aFromID, aToID) { - this.eventSeq = [ - new focusChecker(aToID), - new stateChangeChecker(EXT_STATE_ACTIVE, true, true, aToID), - ]; - - this.invoke = function moveARIAActiveDescendantID_invoke() { - let orig = document.getElementById(aToID); - if (orig) { - orig.id = ""; - } - document.getElementById(aFromID).id = aToID; - }; - - this.getID = function moveARIAActiveDescendantID_getID() { - return "move aria-activedescendant id " + aToID; - }; - } - - var gQueue = null; - async function doTest() { - gQueue = new eventQueue(); - // Later tests use await. - let queueFinished = new Promise(resolve => { - gQueue.onFinish = function() { - resolve(); - return DO_NOT_FINISH_TEST; - }; - }); - - gQueue.push(new synthFocus("listbox", new focusChecker("item1"))); - gQueue.push(new changeARIAActiveDescendant("listbox", "item2", "item1")); - gQueue.push(new changeARIAActiveDescendant("listbox", "item3", "item2")); - - gQueue.push(new synthFocus("combobox_entry", new focusChecker("combobox_entry"))); - gQueue.push(new changeARIAActiveDescendant("combobox", "combobox_option2")); - - gQueue.push(new synthFocus("listbox", new focusChecker("item3"))); - gQueue.push(new insertItemNFocus("listbox", "item4", "item3")); - - gQueue.push(new clearARIAActiveDescendant("listbox", "item4")); - gQueue.push(new changeARIAActiveDescendant("listbox", "item1")); - gQueue.push(new changeARIAActiveDescendantInvalid("listbox", "invalid", "item1")); - - gQueue.push(new changeARIAActiveDescendant("listbox", "roaming")); - gQueue.push(new moveARIAActiveDescendantID("roaming2", "roaming")); - gQueue.push(new changeARIAActiveDescendantInvalid("listbox", "roaming3", "roaming")); - gQueue.push(new moveARIAActiveDescendantID("roaming", "roaming3")); - - gQueue.push(new synthFocus("activedesc_nondesc_input", - new focusChecker("activedesc_nondesc_option"))); - - let shadowRoot = document.getElementById("shadow").shadowRoot; - let shadowListbox = shadowRoot.getElementById("shadowListbox"); - let shadowItem1 = shadowRoot.getElementById("shadowItem1"); - let shadowItem2 = shadowRoot.getElementById("shadowItem2"); - gQueue.push(new synthFocus(shadowListbox, new focusChecker(shadowItem1))); - gQueue.push(new changeARIAActiveDescendant(shadowListbox, shadowItem2)); - - gQueue.invoke(); - await queueFinished; - // Tests beyond this point use await rather than eventQueue. - - info("Testing simultaneous insertion, relocation and aria-activedescendant"); - let comboboxWithHiddenList = getNode("comboboxWithHiddenList"); - let evtProm = PromEvents.waitForEvent(EVENT_FOCUS, comboboxWithHiddenList); - comboboxWithHiddenList.focus(); - await evtProm; - testStates(comboboxWithHiddenList, STATE_FOCUSED); - // hiddenList is owned, so unhiding causes insertion and relocation. - getNode("hiddenList").hidden = false; - evtProm = Promise.all([ - PromEvents.waitForEvent(EVENT_FOCUS, "hiddenListOption"), - PromEvents.waitForStateChange("hiddenListOption", EXT_STATE_ACTIVE, true, true), - ]); - comboboxWithHiddenList.setAttribute("aria-activedescendant", "hiddenListOption"); - await evtProm; - testStates("hiddenListOption", STATE_FOCUSED); - - info("Testing active state changes when not focused"); - testStates("listbox", 0, 0, STATE_FOCUSED); - evtProm = Promise.all([ - PromEvents.waitForStateChange("roaming3", EXT_STATE_ACTIVE, false, true), - PromEvents.waitForStateChange("item1", EXT_STATE_ACTIVE, true, true), - ]); - getNode("listbox").setAttribute("aria-activedescendant", "item1"); - await evtProm; - - info("Testing that focus is always fired first"); - const listbox = getNode("listbox"); - evtProm = PromEvents.waitForEvent(EVENT_FOCUS, "item1"); - listbox.focus(); - await evtProm; - const item1 = getNode("item1"); - evtProm = PromEvents.waitForOrderedEvents([ - [EVENT_FOCUS, "item2"], - [EVENT_NAME_CHANGE, item1], - ], "Focus then name change"); - item1.setAttribute("aria-label", "changed"); - listbox.setAttribute("aria-activedescendant", "item2"); - await evtProm; - - info("Setting aria-activedescendant to invalid id on non-focused node"); - const combobox_entry = getNode("combobox_entry"); - evtProm = PromEvents.waitForEvents({ - expected: [[EVENT_FOCUS, combobox_entry]], - unexpected: [[EVENT_FOCUS, listbox]], - }); - combobox_entry.focus(); - listbox.setAttribute("aria-activedescendant", "invalid"); - await evtProm; - - SimpleTest.finish(); - } - - SimpleTest.waitForExplicitFinish(); - addA11yLoadEvent(doTest); - </script> -</head> -<body> - - <a target="_blank" - href="https://bugzilla.mozilla.org/show_bug.cgi?id=429547" - title="Support aria-activedescendant usage in nsIAccesible::TakeFocus()"> - Mozilla Bug 429547 - </a> - <a target="_blank" - href="https://bugzilla.mozilla.org/show_bug.cgi?id=761102" - title="Focus may be missed when ARIA active-descendant is changed on active composite widget"> - Mozilla Bug 761102 - </a> - <p id="display"></p> - <div id="content" style="display: none"></div> - <pre id="test"> - </pre> - - <div role="listbox" aria-activedescendant="item1" id="listbox" tabindex="1" - aria-owns="item3"> - <div role="listitem" id="item1">item1</div> - <div role="listitem" id="item2">item2</div> - <div role="listitem" id="roaming">roaming</div> - <div role="listitem" id="roaming2">roaming2</div> - </div> - <div role="listitem" id="item3">item3</div> - - <div role="combobox" id="combobox"> - <input id="combobox_entry"> - <ul> - <li role="option" id="combobox_option1">option1</li> - <li role="option" id="combobox_option2">option2</li> - </ul> - </div> - - <!-- aria-activedescendant targeting a non-descendant --> - <input id="activedesc_nondesc_input" aria-activedescendant="activedesc_nondesc_option"> - <div role="listbox"> - <div role="option" id="activedesc_nondesc_option">option</div> - </div> - - <div id="shadow"></div> - <script> - let host = document.getElementById("shadow"); - let shadow = host.attachShadow({mode: "open"}); - let listbox = document.createElement("div"); - listbox.id = "shadowListbox"; - listbox.setAttribute("role", "listbox"); - listbox.setAttribute("tabindex", "0"); - shadow.appendChild(listbox); - let item = document.createElement("div"); - item.id = "shadowItem1"; - item.setAttribute("role", "option"); - listbox.appendChild(item); - listbox.setAttribute("aria-activedescendant", "shadowItem1"); - item = document.createElement("div"); - item.id = "shadowItem2"; - item.setAttribute("role", "option"); - listbox.appendChild(item); - </script> - - <div id="comboboxWithHiddenList" tabindex="0" role="combobox" aria-owns="hiddenList"> - </div> - <div id="hiddenList" hidden role="listbox"> - <div id="hiddenListOption" role="option"></div> - </div> -</body> -</html> diff --git a/accessible/tests/mochitest/events/test_focus_doc.html b/accessible/tests/mochitest/events/test_focus_doc.html index a35fc06ed0..bfb43895bd 100644 --- a/accessible/tests/mochitest/events/test_focus_doc.html +++ b/accessible/tests/mochitest/events/test_focus_doc.html @@ -47,7 +47,17 @@ // focus on not editable document gQueue.push(new synthFocus(frame2InputAcc)); - gQueue.push(new synthShiftTab(frame2DocAcc, new focusChecker(frame2DocAcc))); + var canTabMoveFocusToRootElement = + !SpecialPowers.getBoolPref("dom.disable_tab_focus_to_root_element"); + if (canTabMoveFocusToRootElement) { + // Moves the focus to the root element + gQueue.push(new synthShiftTab(frame2DocAcc, new focusChecker(frame2DocAcc))); + } else { + // Skips the root element, so the focus got moved to buttonAcc2. + var buttonAcc2 = getAccessible("b2"); + gQueue.push(new synthShiftTab(buttonAcc2, new focusChecker(buttonAcc2))); + } + gQueue.invoke(); // Will call SimpleTest.finish(); } diff --git a/accessible/tests/mochitest/events/test_label.xhtml b/accessible/tests/mochitest/events/test_label.xhtml index 5780629dc6..2f207eba65 100644 --- a/accessible/tests/mochitest/events/test_label.xhtml +++ b/accessible/tests/mochitest/events/test_label.xhtml @@ -93,7 +93,7 @@ /** * Change @crop attribute. */ - function setCrop(aID, aCropValue, aRemovedText, aInsertedText) + function setCrop(aID, aCropValue) { this.labelNode = getNode(aID); this.width = this.labelNode.getBoundingClientRect().width; diff --git a/accessible/tests/mochitest/events/test_statechange.html b/accessible/tests/mochitest/events/test_statechange.html index 0642851408..0ecf54b0d1 100644 --- a/accessible/tests/mochitest/events/test_statechange.html +++ b/accessible/tests/mochitest/events/test_statechange.html @@ -28,7 +28,7 @@ await p; } - async function makeEditableDoc(aDocNode, aIsEnabled) { + async function makeEditableDoc(aDocNode) { let p = waitForStateChange(aDocNode, EXT_STATE_EDITABLE, true, true); aDocNode.designMode = "on"; await p; diff --git a/accessible/tests/mochitest/name/markup.js b/accessible/tests/mochitest/name/markup.js index a267bd4f7b..4ad478482b 100644 --- a/accessible/tests/mochitest/name/markup.js +++ b/accessible/tests/mochitest/name/markup.js @@ -335,7 +335,7 @@ function testNameForElmRule(aElm, aRule) { parentNode.removeChild(labelElm); } -function testNameForSubtreeRule(aElm, aRule) { +function testNameForSubtreeRule(aElm) { var msg = "From subtree test (" + gTestIterator.testID + ")."; testName(aElm, aElm.getAttribute("textequiv"), msg); testAbsentAttrs(aElm, { "explicit-name": "true" }); diff --git a/accessible/tests/mochitest/name/test_tree.xhtml b/accessible/tests/mochitest/name/test_tree.xhtml index 3564481d00..282e4ea118 100644 --- a/accessible/tests/mochitest/name/test_tree.xhtml +++ b/accessible/tests/mochitest/name/test_tree.xhtml @@ -31,7 +31,7 @@ this.DOMNode.view = new nsTreeTreeView(); } - this.check = function treeTester_check(aEvent) + this.check = function treeTester_check() { var tree = { role: ROLE_OUTLINE, @@ -89,7 +89,7 @@ this.DOMNode.view = new nsTableTreeView(2); } - this.check = function tableTester_check(aEvent) + this.check = function tableTester_check() { var tree = { role: aIsTable ? ROLE_TABLE : ROLE_TREE_TABLE, diff --git a/accessible/tests/mochitest/promisified-events.js b/accessible/tests/mochitest/promisified-events.js index c58466dcf1..223be16147 100644 --- a/accessible/tests/mochitest/promisified-events.js +++ b/accessible/tests/mochitest/promisified-events.js @@ -141,7 +141,7 @@ function matchEvent(event, matchCriteria) { function waitForEvent(eventType, matchCriteria, message) { return new Promise(resolve => { let eventObserver = { - observe(subject, topic, data) { + observe(subject, topic) { if (topic !== "accessible-event") { return; } @@ -185,7 +185,7 @@ class UnexpectedEvents { } } - observe(subject, topic, data) { + observe(subject, topic) { if (topic !== "accessible-event") { return; } diff --git a/accessible/tests/mochitest/relations/test_tabbrowser.xhtml b/accessible/tests/mochitest/relations/test_tabbrowser.xhtml index 3356bc6140..4820419c1e 100644 --- a/accessible/tests/mochitest/relations/test_tabbrowser.xhtml +++ b/accessible/tests/mochitest/relations/test_tabbrowser.xhtml @@ -43,7 +43,7 @@ browserDocument().documentElement.getBoundingClientRect(); } - this.finalCheck = function testTabRelations_finalCheck(aEvent) + this.finalCheck = function testTabRelations_finalCheck() { //////////////////////////////////////////////////////////////////////// // 'labelled by'/'label for' relations for xul:tab and xul:tabpanel diff --git a/accessible/tests/mochitest/role.js b/accessible/tests/mochitest/role.js index 07b820c2ac..66cb6de4d2 100644 --- a/accessible/tests/mochitest/role.js +++ b/accessible/tests/mochitest/role.js @@ -40,6 +40,7 @@ const ROLE_FLAT_EQUATION = nsIAccessibleRole.ROLE_FLAT_EQUATION; const ROLE_FORM = nsIAccessibleRole.ROLE_FORM; const ROLE_FORM_LANDMARK = nsIAccessibleRole.ROLE_FORM_LANDMARK; const ROLE_GRAPHIC = nsIAccessibleRole.ROLE_GRAPHIC; +const ROLE_GRID = nsIAccessibleRole.ROLE_GRID; const ROLE_GRID_CELL = nsIAccessibleRole.ROLE_GRID_CELL; const ROLE_GROUPING = nsIAccessibleRole.ROLE_GROUPING; const ROLE_HEADING = nsIAccessibleRole.ROLE_HEADING; diff --git a/accessible/tests/mochitest/role/test_aria.html b/accessible/tests/mochitest/role/test_aria.html index bd7ffd27fb..0e7873c485 100644 --- a/accessible/tests/mochitest/role/test_aria.html +++ b/accessible/tests/mochitest/role/test_aria.html @@ -56,16 +56,16 @@ testRole("aria_directory_mixed", ROLE_LIST); testRole("aria_document", ROLE_NON_NATIVE_DOCUMENT); testRole("aria_document_mixed", ROLE_NON_NATIVE_DOCUMENT); - testRole("aria_form", ROLE_FORM); - testRole("aria_form_mixed", ROLE_FORM); + testRole("aria_form", ROLE_TEXT); + testRole("aria_form_mixed", ROLE_TEXT); testRole("aria_form_with_label", ROLE_FORM); testRole("aria_form_with_label_mixed", ROLE_FORM); testRole("aria_feed", ROLE_GROUPING); testRole("aria_feed_mixed", ROLE_GROUPING); testRole("aria_figure", ROLE_FIGURE); testRole("aria_figure_mixed", ROLE_FIGURE); - testRole("aria_grid", ROLE_TABLE); - testRole("aria_grid_mixed", ROLE_TABLE); + testRole("aria_grid", ROLE_GRID); + testRole("aria_grid_mixed", ROLE_GRID); testRole("aria_gridcell", ROLE_GRID_CELL); testRole("aria_gridcell_mixed", ROLE_GRID_CELL); testRole("aria_group", ROLE_GROUPING); @@ -184,8 +184,10 @@ testRole("articlemain", ROLE_LANDMARK); testRole("articlemain_mixed", ROLE_LANDMARK); - testRole("articleform", ROLE_FORM); - testRole("articleform_mixed", ROLE_FORM); + testRole("articleform", ROLE_ARTICLE); + testRole("articleform_mixed", ROLE_ARTICLE); + testRole("articleform_label", ROLE_FORM); + testRole("articleform_label_mixed", ROLE_FORM); // Test article exposed as article testRole("testArticle", ROLE_ARTICLE); @@ -204,8 +206,10 @@ // strong landmark testRole("application", ROLE_APPLICATION); testRole("application_mixed", ROLE_APPLICATION); - testRole("form", ROLE_FORM); - testRole("form_mixed", ROLE_FORM); + testRole("form", ROLE_SECTION); + testRole("form_mixed", ROLE_SECTION); + testRole("form_label", ROLE_FORM); + testRole("form_label_mixed", ROLE_FORM); testRole("application_table", ROLE_APPLICATION); testRole("application_table_mixed", ROLE_APPLICATION); @@ -535,6 +539,8 @@ <article id="articlemain_mixed" role="mAIn">a main area</article> <article id="articleform" role="form">a form area</article> <article id="articleform_mixed" role="fORm">a form area</article> + <article id="articleform_label" aria-label="form" role="form">a form area</article> + <article id="articleform_label_mixed" aria-label="form" role="fORm">a form area</article> <div id="testArticle" role="article" title="Test article"> <p>This is a paragraph inside the article.</p> @@ -561,6 +567,8 @@ <div role="aPPLICATIOn" id="application_mixed">application</div> <div role="form" id="form">form</div> <div role="fORm" id="form_mixed">form</div> + <div role="form" id="form_label" aria-label="form">form</div> + <div role="fORm" id="form_label_mixed" aria-label="form">form</div> <!-- weak landmarks --> <div role="banner" id="banner">banner</div> diff --git a/accessible/tests/mochitest/role/test_general.html b/accessible/tests/mochitest/role/test_general.html index 38dde3325a..c0afd39360 100644 --- a/accessible/tests/mochitest/role/test_general.html +++ b/accessible/tests/mochitest/role/test_general.html @@ -161,7 +161,7 @@ id="nav_overflow">overflow nav</nav> <header style="overflow: hidden;" id="header_overflow">overflow header</header> - <aside style="overflow: hidden;" + <aside style="overflow: hidden;" aria-label="aside" id="aside_overflow">overflow aside</aside> <footer style="overflow: hidden;" id="footer_overflow">overflow footer</footer> diff --git a/accessible/tests/mochitest/states/test_aria_widgetitems.html b/accessible/tests/mochitest/states/test_aria_widgetitems.html index c2d546ba01..d17f110c22 100644 --- a/accessible/tests/mochitest/states/test_aria_widgetitems.html +++ b/accessible/tests/mochitest/states/test_aria_widgetitems.html @@ -26,7 +26,7 @@ this.DOMNode.focus(); }; - this.check = function focusARIAItem_check(aEvent) { + this.check = function focusARIAItem_check() { testStates(this.DOMNode, aIsSelected ? STATE_SELECTED : 0, 0, aIsSelected ? 0 : STATE_SELECTED); }; @@ -47,7 +47,7 @@ this.widgetDOMNode.focus(); }; - this.check = function focusActiveDescendantItem_check(aEvent) { + this.check = function focusActiveDescendantItem_check() { testStates(this.DOMNode, aIsSelected ? STATE_SELECTED : 0, 0, aIsSelected ? 0 : STATE_SELECTED); }; diff --git a/accessible/tests/mochitest/test_bug420863.html b/accessible/tests/mochitest/test_bug420863.html index 4f3a608fe1..9d515ab3c6 100644 --- a/accessible/tests/mochitest/test_bug420863.html +++ b/accessible/tests/mochitest/test_bug420863.html @@ -40,7 +40,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=420863 // register 'click' event handler gClickHandler = { - handleEvent: function handleEvent(aEvent) { + handleEvent: function handleEvent() { }, }; td3Node.addEventListener("click", gClickHandler); @@ -58,7 +58,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=420863 actionName: "click", actionIndex: 0, events: CLICK_EVENTS, - checkOnClickEvent: function check(aEvent) { + checkOnClickEvent: function check() { // unregister click event handler this.ID.removeEventListener("click", gClickHandler); diff --git a/accessible/tests/mochitest/text.js b/accessible/tests/mochitest/text.js index 21392336a1..6fe2a00b83 100644 --- a/accessible/tests/mochitest/text.js +++ b/accessible/tests/mochitest/text.js @@ -197,9 +197,17 @@ function testTextAfterOffset( aBoundaryType, aText, aStartOffset, - aEndOffset + aEndOffset, + ...aArgs ) { - testTextSuperHelper("getTextAfterOffset", arguments); + testTextSuperHelper("getTextAfterOffset", [ + aOffset, + aBoundaryType, + aText, + aStartOffset, + aEndOffset, + ...aArgs, + ]); } /** @@ -261,9 +269,17 @@ function testTextBeforeOffset( aBoundaryType, aText, aStartOffset, - aEndOffset + aEndOffset, + ...aArgs ) { - testTextSuperHelper("getTextBeforeOffset", arguments); + testTextSuperHelper("getTextBeforeOffset", [ + aOffset, + aBoundaryType, + aText, + aStartOffset, + aEndOffset, + ...aArgs, + ]); } /** diff --git a/accessible/tests/mochitest/tree/test_aria_display_contents.html b/accessible/tests/mochitest/tree/test_aria_display_contents.html index 5c6f7f20fb..454e4e46e1 100644 --- a/accessible/tests/mochitest/tree/test_aria_display_contents.html +++ b/accessible/tests/mochitest/tree/test_aria_display_contents.html @@ -17,7 +17,7 @@ // Test ARIA grids that have display: contents; on different elements. // They should all have equivalent trees. var accTree = - { TABLE: [ + { GRID: [ { ROW: [ { role: ROLE_COLUMNHEADER, children: [ { TEXT_LEAF: [ ] }, ] diff --git a/accessible/tests/mochitest/tree/test_aria_grid.html b/accessible/tests/mochitest/tree/test_aria_grid.html index 80ff97095b..4dd30e4183 100644 --- a/accessible/tests/mochitest/tree/test_aria_grid.html +++ b/accessible/tests/mochitest/tree/test_aria_grid.html @@ -18,7 +18,7 @@ // grid having rowgroups var accTree = - { TABLE: [ + { GRID: [ { GROUPING: [ { ROW: [ { GRID_CELL: [ @@ -34,7 +34,7 @@ // strange grids (mix of ARIA and HTML tables) accTree = { - role: ROLE_TABLE, + role: ROLE_GRID, children: [ { // div@role="row" role: ROLE_ROW, @@ -67,7 +67,7 @@ testAccessibleTree("strange_grid1", accTree); accTree = { - role: ROLE_TABLE, + role: ROLE_GRID, children: [ { // tr@role="row" role: ROLE_ROW, @@ -95,7 +95,7 @@ testAccessibleTree("strange_grid2", accTree); accTree = { - role: ROLE_TABLE, + role: ROLE_GRID, children: [ { // div@role="row" role: ROLE_ROW, @@ -122,7 +122,7 @@ testAccessibleTree("strange_grid3", accTree); accTree = { - role: ROLE_TABLE, + role: ROLE_GRID, children: [ { // div@role="row" role: ROLE_ROW, @@ -192,7 +192,7 @@ // grids that could contain text container accessibles but shouldn't. accTree = - { TABLE: [ + { GRID: [ { ROW: [ { GRID_CELL: [ { TEXT_LEAF: [ ] }, diff --git a/accessible/tests/mochitest/tree/test_aria_owns.html b/accessible/tests/mochitest/tree/test_aria_owns.html index a01968521b..760cf7565b 100644 --- a/accessible/tests/mochitest/tree/test_aria_owns.html +++ b/accessible/tests/mochitest/tree/test_aria_owns.html @@ -96,7 +96,7 @@ testAccessibleTree("ariaowns_container", tree); tree = - { TABLE: [ + { GRID: [ { ROW: [ { GRID_CELL: [ { TEXT_LEAF: [] }, @@ -160,7 +160,7 @@ <!-- natural and aria-owns hierarchy --> <div id="t5_2" role="note"><div aria-owns="t5_3" role="heading"></div></div> <div id="t5_1"><div aria-owns="t5_2" role="group"></div></div> - <div id="t5_3" role="form"><div aria-owns="t5_1" role="tooltip"></div></div> + <div id="t5_3" aria-label="form" role="form"><div aria-owns="t5_1" role="tooltip"></div></div> <!-- rearrange children --> <div id="t6_1" aria-owns="t6_3 t6_2"> diff --git a/accessible/tests/mochitest/tree/test_tabbrowser.xhtml b/accessible/tests/mochitest/tree/test_tabbrowser.xhtml index 401ea1a2b1..3ccf83e4dc 100644 --- a/accessible/tests/mochitest/tree/test_tabbrowser.xhtml +++ b/accessible/tests/mochitest/tree/test_tabbrowser.xhtml @@ -42,7 +42,7 @@ browserDocument().documentElement.getBoundingClientRect(); } - this.finalCheck = function testTabHierarchy_finalCheck(aEvent) + this.finalCheck = function testTabHierarchy_finalCheck() { //////////////////// // Tab bar diff --git a/accessible/tests/mochitest/tree/test_tree.xhtml b/accessible/tests/mochitest/tree/test_tree.xhtml index e22b3faa9d..e70ef134e9 100644 --- a/accessible/tests/mochitest/tree/test_tree.xhtml +++ b/accessible/tests/mochitest/tree/test_tree.xhtml @@ -97,7 +97,7 @@ { this.DOMNode.view = aView; } - this.check = function check(aEvent) + this.check = function check() { testAccessibleTreeFor(this.DOMNode, aRole); } diff --git a/accessible/tests/mochitest/treeupdate/test_contextmenu.xhtml b/accessible/tests/mochitest/treeupdate/test_contextmenu.xhtml index f81d77332d..9edac19af6 100644 --- a/accessible/tests/mochitest/treeupdate/test_contextmenu.xhtml +++ b/accessible/tests/mochitest/treeupdate/test_contextmenu.xhtml @@ -31,7 +31,7 @@ getNode(aID).openPopup(button, "after_start", 0, 0, true, false); } - this.finalCheck = function openMenu_finalCheck(aEvent) + this.finalCheck = function openMenu_finalCheck() { testAccessibleTree(aID, aTree); } @@ -70,7 +70,7 @@ synthesizeKey("KEY_Enter"); } - this.finalCheck = function openSubMenu_finalCheck(aEvent) + this.finalCheck = function openSubMenu_finalCheck() { testAccessibleTree(aMenuID, aTree); } diff --git a/accessible/tests/mochitest/treeupdate/test_delayed_removal.html b/accessible/tests/mochitest/treeupdate/test_delayed_removal.html index 3f421f0c5b..2ba1e31203 100644 --- a/accessible/tests/mochitest/treeupdate/test_delayed_removal.html +++ b/accessible/tests/mochitest/treeupdate/test_delayed_removal.html @@ -218,7 +218,7 @@ } // Check to see that a reframed body gets its children pruned correctly. - async function bodyReframe(argument) { + async function bodyReframe() { // Load sub-document in iframe. let event = waitForEvent(EVENT_REORDER, "iframe", "bodyReframe"); getNode("iframe").src = diff --git a/accessible/tests/mochitest/treeupdate/test_shadow_slots.html b/accessible/tests/mochitest/treeupdate/test_shadow_slots.html index 27baef0e4a..6680971401 100644 --- a/accessible/tests/mochitest/treeupdate/test_shadow_slots.html +++ b/accessible/tests/mochitest/treeupdate/test_shadow_slots.html @@ -55,7 +55,7 @@ async function changeSlotFlat() { await _dynamicShadowTest("changeSlotFlat", - (container, host) => { + (container) => { container.querySelector('.red').removeAttribute('slot'); container.querySelector('.green').setAttribute('slot', 'myslot'); }, { SECTION: [{ SECTION: [{ name: "green"} ] }] }); @@ -63,7 +63,7 @@ async function changeSlotOneDeep() { await _dynamicShadowTest("changeSlotOneDeep", - (container, host) => { + (container) => { container.querySelector('.red').removeAttribute('slot'); container.querySelector('.green').setAttribute('slot', 'myslot'); }, { SECTION: [{ SECTION: [{ SECTION: [{ name: "green"} ] }] }] }, ["shadowdiv"]); @@ -72,7 +72,7 @@ // Nested roots and slots async function changeSlotNested() { await _dynamicShadowTest("changeSlotNested", - (container, host) => { + (container) => { testAccessibleTree(getNode("changeSlotNested"), { SECTION: [{ SECTION: [{ SECTION: [{ name: "red"} ] }] }] }); container.querySelector('.red').removeAttribute('slot'); @@ -82,14 +82,14 @@ async function changeSlotSingleChild() { await _dynamicShadowTest("changeSlotSingleChild", - (container, host) => { + (container) => { container.querySelector('.red').setAttribute('slot', 'invalid'); }, { SECTION: [{ SECTION: [] }] }); } async function changeSlotNoShadow() { await _dynamicShadowTest("changeSlotNoShadow", - (container, host) => { + (container) => { // Make sure changing the slot attribute doesn't remove an element // even when it remains in the flat tree. container.querySelector('.red').setAttribute('slot', 'invalid'); diff --git a/accessible/tests/mochitest/treeupdate/test_shutdown.xhtml b/accessible/tests/mochitest/treeupdate/test_shutdown.xhtml index ad8aebf812..9be24cb6f4 100644 --- a/accessible/tests/mochitest/treeupdate/test_shutdown.xhtml +++ b/accessible/tests/mochitest/treeupdate/test_shutdown.xhtml @@ -57,7 +57,7 @@ getNode(aID).remove(); }; - this.check = function check(aEvent) + this.check = function check() { testIsDefunct(this.tree, aID); testIsDefunct(this.lastItem, "last item of " + aID); diff --git a/accessible/tests/mochitest/treeview.js b/accessible/tests/mochitest/treeview.js index 5dc3b595d8..6b50e5fecc 100644 --- a/accessible/tests/mochitest/treeview.js +++ b/accessible/tests/mochitest/treeview.js @@ -91,11 +91,11 @@ nsTreeView.prototype = { return data.text + aCol.id; }, - getCellValue: function getCellValue(aRow, aCol) { + getCellValue: function getCellValue(aRow) { var data = this.getDataForIndex(aRow); return data.value; }, - getRowProperties: function getRowProperties(aIndex) { + getRowProperties: function getRowProperties() { return ""; }, getCellProperties: function getCellProperties(aIndex, aCol) { @@ -106,19 +106,19 @@ nsTreeView.prototype = { var data = this.getDataForIndex(aIndex); return this.mCyclerStates[data.cyclerState]; }, - getColumnProperties: function getColumnProperties(aCol) { + getColumnProperties: function getColumnProperties() { return ""; }, getParentIndex: function getParentIndex(aRowIndex) { var info = this.getInfoByIndex(aRowIndex); return info.parentIndex; }, - hasNextSibling: function hasNextSibling(aRowIndex, aAfterIndex) {}, + hasNextSibling: function hasNextSibling() {}, getLevel: function getLevel(aIndex) { var info = this.getInfoByIndex(aIndex); return info.level; }, - getImageSrc: function getImageSrc(aRow, aCol) {}, + getImageSrc: function getImageSrc() {}, isContainer: function isContainer(aIndex) { var data = this.getDataForIndex(aIndex); return data.open != undefined; @@ -131,7 +131,7 @@ nsTreeView.prototype = { var data = this.getDataForIndex(aIndex); return data.open == undefined; }, - isSeparator: function isSeparator(aIndex) {}, + isSeparator: function isSeparator() {}, isSorted: function isSorted() {}, toggleOpenState: function toggleOpenState(aIndex) { var data = this.getDataForIndex(aIndex); @@ -146,14 +146,14 @@ nsTreeView.prototype = { } }, selectionChanged: function selectionChanged() {}, - cycleHeader: function cycleHeader(aCol) {}, + cycleHeader: function cycleHeader() {}, cycleCell: function cycleCell(aRow, aCol) { var data = this.getDataForIndex(aRow); data.cyclerState = (data.cyclerState + 1) % 3; this.mTree.invalidateCell(aRow, aCol); }, - isEditable: function isEditable(aRow, aCol) { + isEditable: function isEditable() { return true; }, setCellText: function setCellText(aRow, aCol, aValue) { |