summaryrefslogtreecommitdiffstats
path: root/accessible/tests/browser/e10s/browser_caching_actions.js
diff options
context:
space:
mode:
Diffstat (limited to 'accessible/tests/browser/e10s/browser_caching_actions.js')
-rw-r--r--accessible/tests/browser/e10s/browser_caching_actions.js295
1 files changed, 295 insertions, 0 deletions
diff --git a/accessible/tests/browser/e10s/browser_caching_actions.js b/accessible/tests/browser/e10s/browser_caching_actions.js
new file mode 100644
index 0000000000..893c818b75
--- /dev/null
+++ b/accessible/tests/browser/e10s/browser_caching_actions.js
@@ -0,0 +1,295 @@
+/* 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 gClickEvents = ["mousedown", "mouseup", "click"];
+
+const gActionDescrMap = {
+ jump: "Jump",
+ press: "Press",
+ check: "Check",
+ uncheck: "Uncheck",
+ select: "Select",
+ open: "Open",
+ close: "Close",
+ switch: "Switch",
+ click: "Click",
+ collapse: "Collapse",
+ expand: "Expand",
+ activate: "Activate",
+ cycle: "Cycle",
+ "click ancestor": "Click ancestor",
+};
+
+async function testActions(browser, docAcc, id, expectedActions, domEvents) {
+ const acc = findAccessibleChildByID(docAcc, id);
+ is(acc.actionCount, expectedActions.length, "Correct action count");
+
+ let actionNames = [];
+ let actionDescriptions = [];
+ for (let i = 0; i < acc.actionCount; i++) {
+ actionNames.push(acc.getActionName(i));
+ actionDescriptions.push(acc.getActionDescription(i));
+ }
+
+ is(actionNames.join(","), expectedActions.join(","), "Correct action names");
+ is(
+ actionDescriptions.join(","),
+ expectedActions.map(a => gActionDescrMap[a]).join(","),
+ "Correct action descriptions"
+ );
+
+ if (!domEvents) {
+ return;
+ }
+
+ // We need to set up the listener, and wait for the promise in two separate
+ // content tasks.
+ await invokeContentTask(browser, [id, domEvents], (_id, _domEvents) => {
+ let promises = _domEvents.map(
+ evtName =>
+ new Promise(resolve => {
+ const listener = e => {
+ if (e.target.id == _id) {
+ content.removeEventListener(evtName, listener);
+ content.evtPromise = null;
+ resolve(42);
+ }
+ };
+ content.addEventListener(evtName, listener);
+ })
+ );
+ content.evtPromise = Promise.all(promises);
+ });
+
+ acc.doAction(0);
+
+ let eventFired = await invokeContentTask(browser, [], async () => {
+ await content.evtPromise;
+ return true;
+ });
+
+ ok(eventFired, `DOM events fired '${domEvents}'`);
+}
+
+addAccessibleTask(
+ `<ul>
+ <li id="li_clickable1" onclick="">Clickable list item</li>
+ <li id="li_clickable2" onmousedown="">Clickable list item</li>
+ <li id="li_clickable3" onmouseup="">Clickable list item</li>
+ </ul>
+
+ <img id="onclick_img" onclick=""
+ src="http://example.com/a11y/accessible/tests/mochitest/moz.png">
+
+ <a id="link1" href="#">linkable textleaf accessible</a>
+ <div id="link2" onclick="">linkable textleaf accessible</div>
+
+ <a id="link3" href="#">
+ <img id="link3img" alt="image in link"
+ src="http://example.com/a11y/accessible/tests/mochitest/moz.png">
+ </a>
+
+ <a href="about:mozilla" id="link4" target="_blank" rel="opener">
+ <img src="../moz.png" id="link4img">
+ </a>
+ <a id="link5" onmousedown="">
+ <img src="../moz.png" id="link5img">
+ </a>
+ <a id="link6" onclick="">
+ <img src="../moz.png" id="link6img">
+ </a>
+ <a id="link7" onmouseup="">
+ <img src="../moz.png" id="link7img">
+ </a>
+
+ <div>
+ <label for="TextBox_t2" id="label1">
+ <span>Explicit</span>
+ </label>
+ <input name="in2" id="TextBox_t2" type="text" maxlength="17">
+ </div>
+
+ <div onclick=""><p id="p_in_clickable_div">p in clickable div</p></div>
+ `,
+ async function (browser, docAcc) {
+ is(docAcc.actionCount, 0, "Doc should not have any actions");
+
+ const _testActions = async (id, expectedActions, domEvents) => {
+ await testActions(browser, docAcc, id, expectedActions, domEvents);
+ };
+
+ await _testActions("li_clickable1", ["click"], gClickEvents);
+ await _testActions("li_clickable2", ["click"], gClickEvents);
+ await _testActions("li_clickable3", ["click"], gClickEvents);
+
+ await _testActions("onclick_img", ["click"], gClickEvents);
+ await _testActions("link1", ["jump"], gClickEvents);
+ await _testActions("link2", ["click"], gClickEvents);
+ await _testActions("link3", ["jump"], gClickEvents);
+ await _testActions("link3img", ["click ancestor"], gClickEvents);
+ await _testActions("link4", ["jump"], gClickEvents);
+ await _testActions("link4img", ["click ancestor"], gClickEvents);
+ await _testActions("link5", ["click"], gClickEvents);
+ await _testActions("link5img", ["click ancestor"], gClickEvents);
+ await _testActions("link6", ["click"], gClickEvents);
+ await _testActions("link6img", ["click ancestor"], gClickEvents);
+ await _testActions("link7", ["click"], gClickEvents);
+ await _testActions("link7img", ["click ancestor"], gClickEvents);
+ await _testActions("label1", ["click"], gClickEvents);
+ await _testActions("p_in_clickable_div", ["click ancestor"], gClickEvents);
+
+ await invokeContentTask(browser, [], () => {
+ content.document
+ .getElementById("li_clickable1")
+ .removeAttribute("onclick");
+ });
+
+ let acc = findAccessibleChildByID(docAcc, "li_clickable1");
+ await untilCacheIs(() => acc.actionCount, 0, "li has no actions");
+ let thrown = false;
+ try {
+ acc.doAction(0);
+ } catch (e) {
+ thrown = true;
+ }
+ ok(thrown, "doAction should throw exception");
+
+ // Remove 'for' from label
+ await invokeContentTask(browser, [], () => {
+ content.document.getElementById("label1").removeAttribute("for");
+ });
+ acc = findAccessibleChildByID(docAcc, "label1");
+ await untilCacheIs(() => acc.actionCount, 0, "label has no actions");
+ thrown = false;
+ try {
+ acc.doAction(0);
+ ok(false, "doAction should throw exception");
+ } catch (e) {
+ thrown = true;
+ }
+ ok(thrown, "doAction should throw exception");
+
+ // Add 'longdesc' to image
+ await invokeContentTask(browser, [], () => {
+ content.document
+ .getElementById("onclick_img")
+ // eslint-disable-next-line @microsoft/sdl/no-insecure-url
+ .setAttribute("longdesc", "http://example.com");
+ });
+ acc = findAccessibleChildByID(docAcc, "onclick_img");
+ await untilCacheIs(() => acc.actionCount, 2, "img has 2 actions");
+ await _testActions("onclick_img", ["click", "showlongdesc"]);
+
+ // Remove 'onclick' from image with 'longdesc'
+ await invokeContentTask(browser, [], () => {
+ content.document.getElementById("onclick_img").removeAttribute("onclick");
+ });
+ acc = findAccessibleChildByID(docAcc, "onclick_img");
+ await untilCacheIs(() => acc.actionCount, 1, "img has 1 actions");
+ await _testActions("onclick_img", ["showlongdesc"]);
+
+ // Remove 'href' from link and test linkable child
+ let link1Acc = findAccessibleChildByID(docAcc, "link1");
+ is(
+ link1Acc.firstChild.getActionName(0),
+ "click ancestor",
+ "linkable child has click ancestor action"
+ );
+ let onRecreation = waitForEvents({
+ expected: [
+ [EVENT_HIDE, link1Acc],
+ [EVENT_SHOW, "link1"],
+ ],
+ });
+ await invokeContentTask(browser, [], () => {
+ let link1 = content.document.getElementById("link1");
+ link1.removeAttribute("href");
+ });
+ await onRecreation;
+ link1Acc = findAccessibleChildByID(docAcc, "link1");
+ await untilCacheIs(() => link1Acc.actionCount, 0, "link has no actions");
+ is(link1Acc.firstChild.actionCount, 0, "linkable child's actions removed");
+
+ // Add a click handler to the body. Ensure it propagates to descendants.
+ await invokeContentTask(browser, [], () => {
+ content.document.body.onclick = () => {};
+ });
+ await untilCacheIs(() => docAcc.actionCount, 1, "Doc has 1 action");
+ await _testActions("link1", ["click ancestor"]);
+
+ await invokeContentTask(browser, [], () => {
+ content.document.body.onclick = null;
+ });
+ await untilCacheIs(() => docAcc.actionCount, 0, "Doc has no actions");
+ is(link1Acc.actionCount, 0, "link has no actions");
+
+ // Add a click handler to the root element. Ensure it propagates to
+ // descendants.
+ await invokeContentTask(browser, [], () => {
+ content.document.documentElement.onclick = () => {};
+ });
+ await untilCacheIs(() => docAcc.actionCount, 1, "Doc has 1 action");
+ await _testActions("link1", ["click ancestor"]);
+ },
+ {
+ chrome: true,
+ topLevel: true,
+ iframe: true,
+ remoteIframe: true,
+ }
+);
+
+/**
+ * Test access key.
+ */
+addAccessibleTask(
+ `
+<button id="noKey">noKey</button>
+<button id="key" accesskey="a">key</button>
+ `,
+ async function (browser, docAcc) {
+ const noKey = findAccessibleChildByID(docAcc, "noKey");
+ is(noKey.accessKey, "", "noKey has no accesskey");
+ const key = findAccessibleChildByID(docAcc, "key");
+ is(key.accessKey, MAC ? "⌃⌥a" : "Alt+Shift+a", "key has correct accesskey");
+
+ info("Changing accesskey");
+ await invokeContentTask(browser, [], () => {
+ content.document.getElementById("key").accessKey = "b";
+ });
+ await untilCacheIs(
+ () => key.accessKey,
+ MAC ? "⌃⌥b" : "Alt+Shift+b",
+ "Correct accesskey after change"
+ );
+
+ info("Removing accesskey");
+ await invokeContentTask(browser, [], () => {
+ content.document.getElementById("key").removeAttribute("accesskey");
+ });
+ await untilCacheIs(
+ () => key.accessKey,
+ "",
+ "Empty accesskey after removal"
+ );
+
+ info("Adding accesskey");
+ await invokeContentTask(browser, [], () => {
+ content.document.getElementById("key").accessKey = "c";
+ });
+ await untilCacheIs(
+ () => key.accessKey,
+ MAC ? "⌃⌥c" : "Alt+Shift+c",
+ "Correct accesskey after addition"
+ );
+ },
+ {
+ chrome: true,
+ topLevel: true,
+ iframe: false, // Bug 1796846
+ remoteIframe: false, // Bug 1796846
+ }
+);