summaryrefslogtreecommitdiffstats
path: root/accessible/tests/browser/states
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--accessible/tests/browser/states/browser.ini17
-rw-r--r--accessible/tests/browser/states/browser_deck_has_out_of_process_iframe.js133
-rw-r--r--accessible/tests/browser/states/browser_offscreen_element_in_out_of_process_iframe.js98
-rw-r--r--accessible/tests/browser/states/browser_test_link.js47
-rw-r--r--accessible/tests/browser/states/browser_test_visibility.js52
-rw-r--r--accessible/tests/browser/states/head.js81
-rw-r--r--accessible/tests/browser/states/target.html3
-rw-r--r--accessible/tests/browser/states/test_deck_has_out_of_process_iframe.xhtml10
8 files changed, 441 insertions, 0 deletions
diff --git a/accessible/tests/browser/states/browser.ini b/accessible/tests/browser/states/browser.ini
new file mode 100644
index 0000000000..726c7f4f03
--- /dev/null
+++ b/accessible/tests/browser/states/browser.ini
@@ -0,0 +1,17 @@
+[DEFAULT]
+support-files =
+ head.js
+ !/accessible/tests/browser/shared-head.js
+ !/accessible/tests/mochitest/*.js
+ !/accessible/tests/browser/*.jsm
+
+[browser_test_link.js]
+skip-if = verify
+[browser_test_visibility.js]
+[browser_deck_has_out_of_process_iframe.js]
+skip-if = (!debug && webrender && (os == 'win')) # bug 1584037
+support-files =
+ target.html
+ test_deck_has_out_of_process_iframe.xhtml
+[browser_offscreen_element_in_out_of_process_iframe.js]
+skip-if = (webrender && os == 'win') # bug 1580706
diff --git a/accessible/tests/browser/states/browser_deck_has_out_of_process_iframe.js b/accessible/tests/browser/states/browser_deck_has_out_of_process_iframe.js
new file mode 100644
index 0000000000..155ac4c954
--- /dev/null
+++ b/accessible/tests/browser/states/browser_deck_has_out_of_process_iframe.js
@@ -0,0 +1,133 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const { Preferences } = ChromeUtils.import(
+ "resource://gre/modules/Preferences.jsm"
+);
+
+const DIRPATH = getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content/",
+ ""
+);
+const parentPATH = DIRPATH + "test_deck_has_out_of_process_iframe.xhtml";
+const iframePATH = DIRPATH + "target.html";
+
+// XXX: Using external files here since using data URL breaks something, e.g. it
+// makes querying the second iframe in a hidden deck failure for some reasons.
+const parentURL = `http://example.com/${parentPATH}`;
+const iframeURL = `http://example.org/${iframePATH}`;
+
+add_task(async function() {
+ if (Preferences.locked("fission.autostart")) {
+ ok(
+ true,
+ "fission.autostart pref is locked on this channel which means " +
+ "we don't need to run the following tests"
+ );
+ return;
+ }
+
+ const win = await BrowserTestUtils.openNewBrowserWindow({
+ fission: true,
+ });
+
+ try {
+ const browser = win.gBrowser.selectedTab.linkedBrowser;
+
+ BrowserTestUtils.loadURI(browser, parentURL);
+ await BrowserTestUtils.browserLoaded(browser, false, parentURL);
+
+ async function setupIFrame(id, url) {
+ const iframe = content.document.getElementById(id);
+
+ iframe.contentWindow.location = url;
+ await new Promise(resolve => {
+ iframe.addEventListener("load", resolve, { once: true });
+ });
+
+ return iframe.browsingContext;
+ }
+
+ async function spawnSelectDeck(index) {
+ async function selectDeck(i) {
+ const deck = content.document.getElementById("deck");
+
+ deck.setAttribute("selectedIndex", i);
+ await new Promise(resolve => {
+ content.window.addEventListener("MozAfterPaint", resolve, {
+ once: true,
+ });
+ });
+ return deck.selectedIndex;
+ }
+ await SpecialPowers.spawn(browser, [index], selectDeck);
+
+ await waitForIFrameUpdates();
+ }
+
+ const firstIFrame = await SpecialPowers.spawn(
+ browser,
+ ["first", iframeURL],
+ setupIFrame
+ );
+ const secondIFrame = await SpecialPowers.spawn(
+ browser,
+ ["second", iframeURL],
+ setupIFrame
+ );
+
+ await waitForIFrameUpdates();
+
+ await spawnTestStates(
+ firstIFrame,
+ "target",
+ 0,
+ nsIAccessibleStates.STATE_OFFSCREEN
+ );
+ // Disable the check for the target element in the unselected pane of the
+ // deck, this should be fixed by bug 1578932.
+ // Note: As of now we can't use todo in the script transfered into the
+ // out-of-process.
+ //await spawnTestStates(
+ // secondIFrame,
+ // "target",
+ // nsIAccessibleStates.STATE_OFFSCREEN,
+ // nsIAccessibleStates.STATE_INVISIBLE
+ //);
+
+ // Select the second panel.
+ await spawnSelectDeck(1);
+ await spawnTestStates(
+ firstIFrame,
+ "target",
+ nsIAccessibleStates.STATE_OFFSCREEN,
+ nsIAccessibleStates.STATE_INVISIBLE
+ );
+ await spawnTestStates(
+ secondIFrame,
+ "target",
+ 0,
+ nsIAccessibleStates.STATE_OFFSCREEN
+ );
+
+ // Select the first panel again.
+ await spawnSelectDeck(0);
+ await spawnTestStates(
+ firstIFrame,
+ "target",
+ 0,
+ nsIAccessibleStates.STATE_OFFSCREEN
+ );
+ await spawnTestStates(
+ secondIFrame,
+ "target",
+ nsIAccessibleStates.STATE_OFFSCREEN,
+ nsIAccessibleStates.STATE_INVISIBLE
+ );
+ } finally {
+ await BrowserTestUtils.closeWindow(win);
+ }
+});
diff --git a/accessible/tests/browser/states/browser_offscreen_element_in_out_of_process_iframe.js b/accessible/tests/browser/states/browser_offscreen_element_in_out_of_process_iframe.js
new file mode 100644
index 0000000000..289d3fec9a
--- /dev/null
+++ b/accessible/tests/browser/states/browser_offscreen_element_in_out_of_process_iframe.js
@@ -0,0 +1,98 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+const parentURL =
+ "data:text/html;charset=utf-8," +
+ '<div id="scroller" style="width: 300px; height: 300px; overflow-y: scroll; overflow-x: hidden;">' +
+ ' <div style="width: 100%; height: 1000px;"></div>' +
+ ' <iframe frameborder="0"/>' +
+ "</div>";
+const iframeURL =
+ "data:text/html;charset=utf-8," +
+ "<style>" +
+ " html,body {" +
+ " /* Convenient for calculation of element positions */" +
+ " margin: 0;" +
+ " padding: 0;" +
+ " }" +
+ "</style>" +
+ '<div id="target" style="width: 100px; height: 100px;">target</div>';
+
+add_task(async function() {
+ const win = await BrowserTestUtils.openNewBrowserWindow({
+ fission: true,
+ });
+
+ try {
+ const browser = win.gBrowser.selectedTab.linkedBrowser;
+
+ BrowserTestUtils.loadURI(browser, parentURL);
+ await BrowserTestUtils.browserLoaded(browser, false, parentURL);
+
+ async function setup(url) {
+ const iframe = content.document.querySelector("iframe");
+
+ iframe.contentWindow.location = url;
+ await new Promise(resolve => {
+ iframe.addEventListener("load", resolve, { once: true });
+ });
+
+ return iframe.browsingContext;
+ }
+
+ async function scrollTo(x, y) {
+ await SpecialPowers.spawn(browser, [x, y], async (scrollX, scrollY) => {
+ const scroller = content.document.getElementById("scroller");
+ scroller.scrollTo(scrollX, scrollY);
+ await new Promise(resolve => {
+ scroller.addEventListener("scroll", resolve, { once: true });
+ });
+ });
+ await waitForIFrameUpdates();
+ }
+
+ // Setup an out-of-process iframe which is initially scrolled out.
+ const iframe = await SpecialPowers.spawn(browser, [iframeURL], setup);
+
+ await waitForIFrameA11yReady(iframe);
+ await spawnTestStates(
+ iframe,
+ "target",
+ nsIAccessibleStates.STATE_OFFSCREEN,
+ nsIAccessibleStates.STATE_INVISIBLE
+ );
+
+ // Scroll the iframe into view and the target element is also visible but
+ // the visible area height is 11px.
+ await scrollTo(0, 711);
+ await spawnTestStates(
+ iframe,
+ "target",
+ nsIAccessibleStates.STATE_OFFSCREEN,
+ nsIAccessibleStates.STATE_INVISIBLE
+ );
+
+ // Scroll to a position where the visible height is 13px.
+ await scrollTo(0, 713);
+ await spawnTestStates(
+ iframe,
+ "target",
+ 0,
+ nsIAccessibleStates.STATE_OFFSCREEN
+ );
+
+ // Scroll the iframe out again.
+ await scrollTo(0, 0);
+ await spawnTestStates(
+ iframe,
+ "target",
+ nsIAccessibleStates.STATE_OFFSCREEN,
+ nsIAccessibleStates.STATE_INVISIBLE
+ );
+ } finally {
+ await BrowserTestUtils.closeWindow(win);
+ }
+});
diff --git a/accessible/tests/browser/states/browser_test_link.js b/accessible/tests/browser/states/browser_test_link.js
new file mode 100644
index 0000000000..f747a69971
--- /dev/null
+++ b/accessible/tests/browser/states/browser_test_link.js
@@ -0,0 +1,47 @@
+/* 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 runTests(browser, accDoc) {
+ let getAcc = id => findAccessibleChildByID(accDoc, id);
+
+ // a: no traversed state
+ testStates(getAcc("link_traversed"), 0, 0, STATE_TRAVERSED);
+
+ let onStateChanged = waitForEvent(EVENT_STATE_CHANGE, "link_traversed");
+ let newWinOpened = BrowserTestUtils.waitForNewWindow();
+
+ await BrowserTestUtils.synthesizeMouse(
+ "#link_traversed",
+ 1,
+ 1,
+ { shiftKey: true },
+ browser
+ );
+
+ await onStateChanged;
+ testStates(getAcc("link_traversed"), STATE_TRAVERSED);
+
+ let newWin = await newWinOpened;
+ await BrowserTestUtils.closeWindow(newWin);
+}
+
+/**
+ * Test caching of accessible object states
+ */
+addAccessibleTask(
+ `
+ <a id="link_traversed" href="http://www.example.com" target="_top">
+ example.com
+ </a>`,
+ runTests
+);
diff --git a/accessible/tests/browser/states/browser_test_visibility.js b/accessible/tests/browser/states/browser_test_visibility.js
new file mode 100644
index 0000000000..572c6f57d3
--- /dev/null
+++ b/accessible/tests/browser/states/browser_test_visibility.js
@@ -0,0 +1,52 @@
+/* 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 runTest(browser, accDoc) {
+ let getAcc = id => findAccessibleChildByID(accDoc, id);
+
+ testStates(getAcc("div"), 0, 0, STATE_INVISIBLE | STATE_OFFSCREEN);
+
+ let input = getAcc("input_scrolledoff");
+ testStates(input, STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+
+ // scrolled off item (twice)
+ let lastLi = getAcc("li_last");
+ testStates(lastLi, STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+
+ // scroll into view the item
+ await SpecialPowers.spawn(browser, [], () => {
+ content.document.getElementById("li_last").scrollIntoView(true);
+ });
+ testStates(lastLi, 0, 0, STATE_OFFSCREEN | STATE_INVISIBLE);
+
+ // first item is scrolled off now (testcase for bug 768786)
+ let firstLi = getAcc("li_first");
+ testStates(firstLi, STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+
+ let newTab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
+ // Accessibles in background tab should have offscreen state and no
+ // invisible state.
+ testStates(getAcc("div"), STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+ BrowserTestUtils.removeTab(newTab);
+}
+
+addAccessibleTask(
+ `
+ <div id="div" style="border:2px solid blue; width: 500px; height: 110vh;"></div>
+ <input id="input_scrolledoff">
+ <ul style="border:2px solid red; width: 100px; height: 50px; overflow: auto;">
+ <li id="li_first">item1</li><li>item2</li><li>item3</li>
+ <li>item4</li><li>item5</li><li id="li_last">item6</li>
+ </ul>`,
+ runTest
+);
diff --git a/accessible/tests/browser/states/head.js b/accessible/tests/browser/states/head.js
new file mode 100644
index 0000000000..f9d7393229
--- /dev/null
+++ b/accessible/tests/browser/states/head.js
@@ -0,0 +1,81 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+/* exported waitForIFrameA11yReady, waitForIFrameUpdates, spawnTestStates */
+
+// Load the shared-head file first.
+/* import-globals-from ../shared-head.js */
+Services.scriptloader.loadSubScript(
+ "chrome://mochitests/content/browser/accessible/tests/browser/shared-head.js",
+ this
+);
+
+// Loading and common.js from accessible/tests/mochitest/ for all tests, as
+// well as promisified-events.js.
+loadScripts(
+ { name: "common.js", dir: MOCHITESTS_DIR },
+ { name: "promisified-events.js", dir: MOCHITESTS_DIR }
+);
+
+// This is another version of addA11yLoadEvent for fission.
+async function waitForIFrameA11yReady(iFrameBrowsingContext) {
+ await SimpleTest.promiseFocus(window);
+
+ await SpecialPowers.spawn(iFrameBrowsingContext, [], () => {
+ return new Promise(resolve => {
+ function waitForDocLoad() {
+ SpecialPowers.executeSoon(() => {
+ const acc = SpecialPowers.Cc[
+ "@mozilla.org/accessibilityService;1"
+ ].getService(SpecialPowers.Ci.nsIAccessibilityService);
+
+ const accDoc = acc.getAccessibleFor(content.document);
+ let state = {};
+ accDoc.getState(state, {});
+ if (state.value & SpecialPowers.Ci.nsIAccessibleStates.STATE_BUSY) {
+ SpecialPowers.executeSoon(waitForDocLoad);
+ return;
+ }
+ resolve();
+ }, 0);
+ }
+ waitForDocLoad();
+ });
+ });
+}
+
+// A utility function to make sure the information of scroll position or visible
+// area changes reach to out-of-process iframes.
+async function waitForIFrameUpdates() {
+ // Wait for two frames since the information is notified via asynchronous IPC
+ // calls.
+ await new Promise(resolve => requestAnimationFrame(resolve));
+ await new Promise(resolve => requestAnimationFrame(resolve));
+}
+
+// A utility function to test the state of |elementId| element in out-of-process
+// |browsingContext|.
+async function spawnTestStates(browsingContext, elementId, expectedStates) {
+ function testStates(id, expected, unexpected) {
+ const acc = SpecialPowers.Cc[
+ "@mozilla.org/accessibilityService;1"
+ ].getService(SpecialPowers.Ci.nsIAccessibilityService);
+ const target = content.document.getElementById(id);
+ let state = {};
+ acc.getAccessibleFor(target).getState(state, {});
+ if (expected === 0) {
+ Assert.equal(state.value, expected);
+ } else {
+ Assert.ok(state.value & expected);
+ }
+ Assert.ok(!(state.value & unexpected));
+ }
+ await SpecialPowers.spawn(
+ browsingContext,
+ [elementId, expectedStates],
+ testStates
+ );
+}
diff --git a/accessible/tests/browser/states/target.html b/accessible/tests/browser/states/target.html
new file mode 100644
index 0000000000..0412c13d53
--- /dev/null
+++ b/accessible/tests/browser/states/target.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<div id="target">target</div>
diff --git a/accessible/tests/browser/states/test_deck_has_out_of_process_iframe.xhtml b/accessible/tests/browser/states/test_deck_has_out_of_process_iframe.xhtml
new file mode 100644
index 0000000000..72d93ca30a
--- /dev/null
+++ b/accessible/tests/browser/states/test_deck_has_out_of_process_iframe.xhtml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ title="XUL elements visibility states testing">
+<deck id="deck" selectedIndex="0">
+ <iframe id="first" flex="1"/>
+ <iframe id="second" flex="1"/>
+</deck>
+</window>