summaryrefslogtreecommitdiffstats
path: root/devtools/client/shared/test/head.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/client/shared/test/head.js')
-rw-r--r--devtools/client/shared/test/head.js211
1 files changed, 211 insertions, 0 deletions
diff --git a/devtools/client/shared/test/head.js b/devtools/client/shared/test/head.js
new file mode 100644
index 0000000000..47731bc74a
--- /dev/null
+++ b/devtools/client/shared/test/head.js
@@ -0,0 +1,211 @@
+/* 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/. */
+/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
+
+"use strict";
+
+// shared-head.js handles imports, constants, and utility functions
+Services.scriptloader.loadSubScript(
+ "chrome://mochitests/content/browser/devtools/client/shared/test/shared-head.js",
+ this
+);
+
+const { DOMHelpers } = require("resource://devtools/shared/dom-helpers.js");
+const {
+ Hosts,
+} = require("resource://devtools/client/framework/toolbox-hosts.js");
+
+const TEST_URI_ROOT = "http://example.com/browser/devtools/client/shared/test/";
+const TEST_URI_ROOT_SSL =
+ "https://example.com/browser/devtools/client/shared/test/";
+
+const EXAMPLE_URL =
+ "chrome://mochitests/content/browser/devtools/client/shared/test/";
+
+function catchFail(func) {
+ return function () {
+ try {
+ return func.apply(null, arguments);
+ } catch (ex) {
+ ok(false, ex);
+ console.error(ex);
+ finish();
+ throw ex;
+ }
+ };
+}
+
+/**
+ * Polls a given function waiting for the given value.
+ *
+ * @param object options
+ * Options object with the following properties:
+ * - validator
+ * A validator function that should return the expected value. This is
+ * called every few milliseconds to check if the result is the expected
+ * one. When the returned result is the expected one, then the |success|
+ * function is called and polling stops. If |validator| never returns
+ * the expected value, then polling timeouts after several tries and
+ * a failure is recorded - the given |failure| function is invoked.
+ * - success
+ * A function called when the validator function returns the expected
+ * value.
+ * - failure
+ * A function called if the validator function timeouts - fails to return
+ * the expected value in the given time.
+ * - name
+ * Name of test. This is used to generate the success and failure
+ * messages.
+ * - timeout
+ * Timeout for validator function, in milliseconds. Default is 5000 ms.
+ * - value
+ * The expected value. If this option is omitted then the |validator|
+ * function must return a trueish value.
+ * Each of the provided callback functions will receive two arguments:
+ * the |options| object and the last value returned by |validator|.
+ */
+function waitForValue(options) {
+ const start = Date.now();
+ const timeout = options.timeout || 5000;
+ let lastValue;
+
+ function wait(validatorFn, successFn, failureFn) {
+ if (Date.now() - start > timeout) {
+ // Log the failure.
+ ok(false, "Timed out while waiting for: " + options.name);
+ const expected =
+ "value" in options ? "'" + options.value + "'" : "a trueish value";
+ info("timeout info :: got '" + lastValue + "', expected " + expected);
+ failureFn(options, lastValue);
+ return;
+ }
+
+ lastValue = validatorFn(options, lastValue);
+ const successful =
+ "value" in options ? lastValue == options.value : lastValue;
+ if (successful) {
+ ok(true, options.name);
+ successFn(options, lastValue);
+ } else {
+ setTimeout(() => {
+ wait(validatorFn, successFn, failureFn);
+ }, 100);
+ }
+ }
+
+ wait(options.validator, options.success, options.failure);
+}
+
+function oneTimeObserve(name, callback) {
+ return new Promise(resolve => {
+ const func = function () {
+ Services.obs.removeObserver(func, name);
+ if (callback) {
+ callback();
+ }
+ resolve();
+ };
+ Services.obs.addObserver(func, name);
+ });
+}
+
+const createHost = async function (
+ type = "bottom",
+ src = CHROME_URL_ROOT + "dummy.html"
+) {
+ const host = new Hosts[type](gBrowser.selectedTab);
+ const iframe = await host.create();
+
+ await new Promise(resolve => {
+ iframe.setAttribute("src", src);
+ DOMHelpers.onceDOMReady(iframe.contentWindow, resolve);
+ });
+
+ // Popup tests fail very frequently on Linux + webrender because they run
+ // too early.
+ await waitForPresShell(iframe);
+
+ return { host, win: iframe.contentWindow, doc: iframe.contentDocument };
+};
+
+/**
+ * Open and close the toolbox in the current browser tab, several times, waiting
+ * some amount of time in between.
+ * @param {Number} nbOfTimes
+ * @param {Number} usageTime in milliseconds
+ * @param {String} toolId
+ */
+async function openAndCloseToolbox(nbOfTimes, usageTime, toolId) {
+ for (let i = 0; i < nbOfTimes; i++) {
+ info("Opening toolbox " + (i + 1));
+
+ const tab = gBrowser.selectedTab;
+ const toolbox = await gDevTools.showToolboxForTab(tab, { toolId });
+
+ // We use a timeout to check the toolbox's active time
+ await new Promise(resolve => setTimeout(resolve, usageTime));
+
+ info("Closing toolbox " + (i + 1));
+ await toolbox.destroy();
+ }
+}
+
+/**
+ * Waits until a predicate returns true.
+ *
+ * @param function predicate
+ * Invoked once in a while until it returns true.
+ * @param number interval [optional]
+ * How often the predicate is invoked, in milliseconds.
+ */
+function waitUntil(predicate, interval = 10) {
+ if (predicate()) {
+ return Promise.resolve(true);
+ }
+ return new Promise(resolve => {
+ setTimeout(function () {
+ waitUntil(predicate).then(() => resolve(true));
+ }, interval);
+ });
+}
+
+/**
+ * Show the presets list sidebar in the cssfilter widget popup
+ * @param {CSSFilterWidget} widget
+ * @return {Promise}
+ */
+function showFilterPopupPresets(widget) {
+ const onRender = widget.once("render");
+ widget._togglePresets();
+ return onRender;
+}
+
+/**
+ * Show presets list and create a sample preset with the name and value provided
+ * @param {CSSFilterWidget} widget
+ * @param {string} name
+ * @param {string} value
+ * @return {Promise}
+ */
+const showFilterPopupPresetsAndCreatePreset = async function (
+ widget,
+ name,
+ value
+) {
+ await showFilterPopupPresets(widget);
+
+ let onRender = widget.once("render");
+ widget.setCssValue(value);
+ await onRender;
+
+ const footer = widget.el.querySelector(".presets-list .footer");
+ footer.querySelector("input").value = name;
+
+ onRender = widget.once("render");
+ widget._savePreset({
+ preventDefault: () => {},
+ });
+
+ await onRender;
+};