summaryrefslogtreecommitdiffstats
path: root/browser/components/preferences/tests/head.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /browser/components/preferences/tests/head.js
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/components/preferences/tests/head.js')
-rw-r--r--browser/components/preferences/tests/head.js264
1 files changed, 264 insertions, 0 deletions
diff --git a/browser/components/preferences/tests/head.js b/browser/components/preferences/tests/head.js
new file mode 100644
index 0000000000..69d174d534
--- /dev/null
+++ b/browser/components/preferences/tests/head.js
@@ -0,0 +1,264 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+ChromeUtils.import("resource://gre/modules/Promise.jsm", this);
+const { PermissionTestUtils } = ChromeUtils.import(
+ "resource://testing-common/PermissionTestUtils.jsm"
+);
+
+const kDefaultWait = 2000;
+
+function is_element_visible(aElement, aMsg) {
+ isnot(aElement, null, "Element should not be null, when checking visibility");
+ ok(!BrowserTestUtils.is_hidden(aElement), aMsg);
+}
+
+function is_element_hidden(aElement, aMsg) {
+ isnot(aElement, null, "Element should not be null, when checking visibility");
+ ok(BrowserTestUtils.is_hidden(aElement), aMsg);
+}
+
+function open_preferences(aCallback) {
+ gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:preferences");
+ let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
+ newTabBrowser.addEventListener(
+ "Initialized",
+ function() {
+ aCallback(gBrowser.contentWindow);
+ },
+ { capture: true, once: true }
+ );
+}
+
+function openAndLoadSubDialog(
+ aURL,
+ aFeatures = null,
+ aParams = null,
+ aClosingCallback = null
+) {
+ let promise = promiseLoadSubDialog(aURL);
+ content.gSubDialog.open(
+ aURL,
+ { features: aFeatures, closingCallback: aClosingCallback },
+ aParams
+ );
+ return promise;
+}
+
+function promiseLoadSubDialog(aURL) {
+ return new Promise((resolve, reject) => {
+ content.gSubDialog._dialogStack.addEventListener(
+ "dialogopen",
+ function dialogopen(aEvent) {
+ if (
+ aEvent.detail.dialog._frame.contentWindow.location == "about:blank"
+ ) {
+ return;
+ }
+ content.gSubDialog._dialogStack.removeEventListener(
+ "dialogopen",
+ dialogopen
+ );
+
+ is(
+ aEvent.detail.dialog._frame.contentWindow.location.toString(),
+ aURL,
+ "Check the proper URL is loaded"
+ );
+
+ // Check visibility
+ is_element_visible(aEvent.detail.dialog._overlay, "Overlay is visible");
+
+ // Check that stylesheets were injected
+ let expectedStyleSheetURLs = aEvent.detail.dialog._injectedStyleSheets.slice(
+ 0
+ );
+ for (let styleSheet of aEvent.detail.dialog._frame.contentDocument
+ .styleSheets) {
+ let i = expectedStyleSheetURLs.indexOf(styleSheet.href);
+ if (i >= 0) {
+ info("found " + styleSheet.href);
+ expectedStyleSheetURLs.splice(i, 1);
+ }
+ }
+ is(
+ expectedStyleSheetURLs.length,
+ 0,
+ "All expectedStyleSheetURLs should have been found"
+ );
+
+ // Wait for the next event tick to make sure the remaining part of the
+ // testcase runs after the dialog gets ready for input.
+ executeSoon(() => resolve(aEvent.detail.dialog._frame.contentWindow));
+ }
+ );
+ });
+}
+
+/**
+ * Waits a specified number of miliseconds for a specified event to be
+ * fired on a specified element.
+ *
+ * Usage:
+ * let receivedEvent = waitForEvent(element, "eventName");
+ * // Do some processing here that will cause the event to be fired
+ * // ...
+ * // Now yield until the Promise is fulfilled
+ * yield receivedEvent;
+ * if (receivedEvent && !(receivedEvent instanceof Error)) {
+ * receivedEvent.msg == "eventName";
+ * // ...
+ * }
+ *
+ * @param aSubject the element that should receive the event
+ * @param aEventName the event to wait for
+ * @param aTimeoutMs the number of miliseconds to wait before giving up
+ * @returns a Promise that resolves to the received event, or to an Error
+ */
+function waitForEvent(aSubject, aEventName, aTimeoutMs, aTarget) {
+ let eventDeferred = Promise.defer();
+ let timeoutMs = aTimeoutMs || kDefaultWait;
+ let stack = new Error().stack;
+ let timerID = setTimeout(function wfe_canceller() {
+ aSubject.removeEventListener(aEventName, listener);
+ eventDeferred.reject(new Error(aEventName + " event timeout at " + stack));
+ }, timeoutMs);
+
+ var listener = function(aEvent) {
+ if (aTarget && aTarget !== aEvent.target) {
+ return;
+ }
+
+ // stop the timeout clock and resume
+ clearTimeout(timerID);
+ eventDeferred.resolve(aEvent);
+ };
+
+ function cleanup(aEventOrError) {
+ // unhook listener in case of success or failure
+ aSubject.removeEventListener(aEventName, listener);
+ return aEventOrError;
+ }
+ aSubject.addEventListener(aEventName, listener);
+ return eventDeferred.promise.then(cleanup, cleanup);
+}
+
+async function openPreferencesViaOpenPreferencesAPI(aPane, aOptions) {
+ let finalPaneEvent = Services.prefs.getBoolPref("identity.fxaccounts.enabled")
+ ? "sync-pane-loaded"
+ : "privacy-pane-loaded";
+ let finalPrefPaneLoaded = TestUtils.topicObserved(finalPaneEvent, () => true);
+ gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, "about:blank");
+ openPreferences(aPane, aOptions);
+ let newTabBrowser = gBrowser.selectedBrowser;
+
+ if (!newTabBrowser.contentWindow) {
+ await BrowserTestUtils.waitForEvent(newTabBrowser, "Initialized", true);
+ await BrowserTestUtils.waitForEvent(newTabBrowser.contentWindow, "load");
+ await finalPrefPaneLoaded;
+ }
+
+ let win = gBrowser.contentWindow;
+ let selectedPane = win.history.state;
+ if (!aOptions || !aOptions.leaveOpen) {
+ gBrowser.removeCurrentTab();
+ }
+ return { selectedPane };
+}
+
+async function evaluateSearchResults(
+ keyword,
+ searchReults,
+ includeExperiments = false
+) {
+ searchReults = Array.isArray(searchReults) ? searchReults : [searchReults];
+ searchReults.push("header-searchResults");
+
+ let searchInput = gBrowser.contentDocument.getElementById("searchInput");
+ searchInput.focus();
+ let searchCompletedPromise = BrowserTestUtils.waitForEvent(
+ gBrowser.contentWindow,
+ "PreferencesSearchCompleted",
+ evt => evt.detail == keyword
+ );
+ EventUtils.sendString(keyword);
+ await searchCompletedPromise;
+
+ let mainPrefTag = gBrowser.contentDocument.getElementById("mainPrefPane");
+ for (let i = 0; i < mainPrefTag.childElementCount; i++) {
+ let child = mainPrefTag.children[i];
+ if (!includeExperiments && child.id?.startsWith("pane-experimental")) {
+ continue;
+ }
+ if (searchReults.includes(child.id)) {
+ is_element_visible(child, `${child.id} should be in search results`);
+ } else if (child.id) {
+ is_element_hidden(child, `${child.id} should not be in search results`);
+ }
+ }
+}
+
+function waitForMutation(target, opts, cb) {
+ return new Promise(resolve => {
+ let observer = new MutationObserver(() => {
+ if (!cb || cb(target)) {
+ observer.disconnect();
+ resolve();
+ }
+ });
+ observer.observe(target, opts);
+ });
+}
+
+// Used to add sample experimental features for testing. To use, create
+// a DefinitionServer, then call addDefinition as needed.
+class DefinitionServer {
+ constructor(definitionOverrides = []) {
+ let { HttpServer } = ChromeUtils.import(
+ "resource://testing-common/httpd.js"
+ );
+
+ this.server = new HttpServer();
+ this.server.registerPathHandler("/definitions.json", this);
+ this.definitions = {};
+
+ for (const override of definitionOverrides) {
+ this.addDefinition(override);
+ }
+
+ this.server.start();
+ registerCleanupFunction(
+ () => new Promise(resolve => this.server.stop(resolve))
+ );
+ }
+
+ // for nsIHttpRequestHandler
+ handle(request, response) {
+ response.write(JSON.stringify(this.definitions));
+ }
+
+ get definitionsUrl() {
+ const { primaryScheme, primaryHost, primaryPort } = this.server.identity;
+ return `${primaryScheme}://${primaryHost}:${primaryPort}/definitions.json`;
+ }
+
+ addDefinition(overrides = {}) {
+ const definition = {
+ id: "test-feature",
+ // These l10n IDs are just random so we have some text to display
+ title: "experimental-features-media-avif",
+ description: "pane-experimental-description",
+ restartRequired: false,
+ type: "boolean",
+ preference: "test.feature",
+ defaultValue: false,
+ isPublic: false,
+ ...overrides,
+ };
+ // convert targeted values, used by fromId
+ definition.isPublic = { default: definition.isPublic };
+ definition.defaultValue = { default: definition.defaultValue };
+ this.definitions[definition.id] = definition;
+ return definition;
+ }
+}