diff options
Diffstat (limited to '')
-rw-r--r-- | toolkit/components/narrate/test/NarrateTestUtils.sys.mjs | 150 |
1 files changed, 150 insertions, 0 deletions
diff --git a/toolkit/components/narrate/test/NarrateTestUtils.sys.mjs b/toolkit/components/narrate/test/NarrateTestUtils.sys.mjs new file mode 100644 index 0000000000..92d88e8e3b --- /dev/null +++ b/toolkit/components/narrate/test/NarrateTestUtils.sys.mjs @@ -0,0 +1,150 @@ +/* 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/. */ + +import { ContentTaskUtils } from "resource://testing-common/ContentTaskUtils.sys.mjs"; +import { Preferences } from "resource://gre/modules/Preferences.sys.mjs"; +import { setTimeout } from "resource://gre/modules/Timer.sys.mjs"; + +export var NarrateTestUtils = { + TOGGLE: ".narrate-toggle", + POPUP: ".narrate-dropdown .dropdown-popup", + VOICE_SELECT: ".narrate-voices .select-toggle", + VOICE_OPTIONS: ".narrate-voices .options", + VOICE_SELECTED: ".narrate-voices .options .option.selected", + VOICE_SELECT_LABEL: ".narrate-voices .select-toggle .current-voice", + RATE: ".narrate-rate-input", + START: ".narrate-dropdown:not(.speaking) .narrate-start-stop", + STOP: ".narrate-dropdown.speaking .narrate-start-stop", + BACK: ".narrate-skip-previous", + FORWARD: ".narrate-skip-next", + + isVisible(element) { + let win = element.ownerGlobal; + let style = win.getComputedStyle(element); + if (style.display == "none") { + return false; + } + if (style.visibility != "visible") { + return false; + } + if (win.XULPopupElement.isInstance(element) && element.state != "open") { + return false; + } + + // Hiding a parent element will hide all its children + if (element.parentNode != element.ownerDocument) { + return this.isVisible(element.parentNode); + } + + return true; + }, + + isStoppedState(window, ok) { + let $ = window.document.querySelector.bind(window.document); + ok($(this.BACK).disabled, "back button is disabled"); + ok($(this.FORWARD).disabled, "forward button is disabled"); + ok(!!$(this.START), "start button is showing"); + ok(!$(this.STOP), "stop button is hidden"); + // This checks for a localized label. Not the best... + ok($(this.START).title == "Start (N)", "Button tooltip is correct"); + }, + + isStartedState(window, ok) { + let $ = window.document.querySelector.bind(window.document); + ok(!$(this.BACK).disabled, "back button is enabled"); + ok(!$(this.FORWARD).disabled, "forward button is enabled"); + ok(!$(this.START), "start button is hidden"); + ok(!!$(this.STOP), "stop button is showing"); + // This checks for a localized label. Not the best... + ok($(this.STOP).title == "Stop (N)", "Button tooltip is correct"); + }, + + selectVoice(window, voiceUri) { + if (!this.isVisible(window.document.querySelector(this.VOICE_OPTIONS))) { + window.document.querySelector(this.VOICE_SELECT).click(); + } + + let voiceOption = window.document.querySelector( + `.narrate-voices .option[data-value="${voiceUri}"]` + ); + + voiceOption.focus(); + voiceOption.click(); + + return voiceOption.classList.contains("selected"); + }, + + getEventUtils(window) { + let eventUtils = { + _EU_Ci: Ci, + _EU_Cc: Cc, + window, + setTimeout, + parent: window, + navigator: window.navigator, + KeyboardEvent: window.KeyboardEvent, + KeyEvent: window.KeyEvent, + }; + Services.scriptloader.loadSubScript( + "chrome://mochikit/content/tests/SimpleTest/EventUtils.js", + eventUtils + ); + return eventUtils; + }, + + getReaderReadyPromise(window) { + return new Promise(resolve => { + function observeReady(subject, topic) { + if (subject == window) { + Services.obs.removeObserver(observeReady, topic); + resolve(); + } + } + + if (window.document.body.classList.contains("loaded")) { + resolve(); + } else { + Services.obs.addObserver(observeReady, "AboutReader:Ready"); + } + }); + }, + + waitForNarrateToggle(window) { + let toggle = window.document.querySelector(this.TOGGLE); + return ContentTaskUtils.waitForCondition(() => !toggle.hidden, ""); + }, + + waitForPrefChange(pref) { + return new Promise(resolve => { + function observeChange() { + Services.prefs.removeObserver(pref, observeChange); + resolve(Preferences.get(pref)); + } + + Services.prefs.addObserver(pref, observeChange); + }); + }, + + sendBoundaryEvent(window, name, charIndex, charLength) { + let detail = { type: "boundary", args: { name, charIndex, charLength } }; + window.dispatchEvent(new window.CustomEvent("testsynthevent", { detail })); + }, + + isWordHighlightGone(window, ok) { + let $ = window.document.querySelector.bind(window.document); + ok(!$(".narrate-word-highlight"), "No more word highlights exist"); + }, + + getWordHighlights(window) { + let $$ = window.document.querySelectorAll.bind(window.document); + let nodes = Array.from($$(".narrate-word-highlight")); + return nodes.map(node => { + return { + word: node.dataset.word, + left: Number(node.style.left.replace(/px$/, "")), + top: Number(node.style.top.replace(/px$/, "")), + }; + }); + }, +}; |