mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-22 09:45:41 +00:00
22e4925d1f
MozReview-Commit-ID: DOYF2vTUEqq
172 lines
5.0 KiB
JavaScript
172 lines
5.0 KiB
JavaScript
/* vim: set ts=2 et sw=2 tw=80: */
|
|
/* Any copyright is dedicated to the Public Domain.
|
|
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
/* eslint no-unused-vars: [2, {"vars": "local", "args": "none"}] */
|
|
/* import-globals-from ../../framework/test/shared-head.js */
|
|
|
|
"use strict";
|
|
|
|
const FRAME_SCRIPT_UTILS_URL =
|
|
"chrome://devtools/content/shared/frame-script-utils.js";
|
|
|
|
// shared-head.js handles imports, constants, and utility functions
|
|
Services.scriptloader.loadSubScript(
|
|
"chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", this);
|
|
|
|
// DOM panel actions.
|
|
const constants = require("devtools/client/dom/content/constants");
|
|
|
|
// Uncomment this pref to dump all devtools emitted events to the console.
|
|
// Services.prefs.setBoolPref("devtools.dom.enabled", true);
|
|
|
|
// Enable the DOM panel
|
|
Services.prefs.setBoolPref("devtools.dom.enabled", true);
|
|
|
|
registerCleanupFunction(() => {
|
|
info("finish() was called, cleaning up...");
|
|
Services.prefs.clearUserPref("devtools.dump.emit");
|
|
Services.prefs.clearUserPref("devtools.dom.enabled");
|
|
});
|
|
|
|
/**
|
|
* Add a new test tab in the browser and load the given url.
|
|
* @param {String} url
|
|
* The url to be loaded in the new tab
|
|
* @return a promise that resolves to the tab object when
|
|
* the url is loaded
|
|
*/
|
|
function addTestTab(url) {
|
|
info("Adding a new test tab with URL: '" + url + "'");
|
|
|
|
return new Promise(resolve => {
|
|
addTab(url).then(tab => {
|
|
// Load devtools/shared/frame-script-utils.js
|
|
getFrameScript();
|
|
|
|
// Select the DOM panel and wait till it's initialized.
|
|
initDOMPanel(tab).then(panel => {
|
|
waitForDispatch(panel, "FETCH_PROPERTIES").then(() => {
|
|
resolve({
|
|
tab: tab,
|
|
browser: tab.linkedBrowser,
|
|
panel: panel
|
|
});
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Open the DOM panel for the given tab.
|
|
*
|
|
* @param {nsIDOMElement} tab
|
|
* Optional tab element for which you want open the DOM panel.
|
|
* The default tab is taken from the global variable |tab|.
|
|
* @return a promise that is resolved once the web console is open.
|
|
*/
|
|
function initDOMPanel(tab) {
|
|
return new Promise(resolve => {
|
|
let target = TargetFactory.forTab(tab || gBrowser.selectedTab);
|
|
gDevTools.showToolbox(target, "dom").then(toolbox => {
|
|
let panel = toolbox.getCurrentPanel();
|
|
resolve(panel);
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Synthesize asynchronous click event (with clean stack trace).
|
|
*/
|
|
function synthesizeMouseClickSoon(panel, element) {
|
|
return new Promise(resolve => {
|
|
executeSoon(() => {
|
|
EventUtils.synthesizeMouse(element, 2, 2, {}, panel.panelWin);
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Returns tree row with specified label.
|
|
*/
|
|
function getRowByLabel(panel, text) {
|
|
let doc = panel.panelWin.document;
|
|
let labels = [...doc.querySelectorAll(".treeLabel")];
|
|
let label = labels.find(node => node.textContent == text);
|
|
return label ? label.closest(".treeRow") : null;
|
|
}
|
|
|
|
/**
|
|
* Expands elements with given label and waits till
|
|
* children are received from the backend.
|
|
*/
|
|
function expandRow(panel, labelText) {
|
|
let row = getRowByLabel(panel, labelText);
|
|
return synthesizeMouseClickSoon(panel, row).then(() => {
|
|
// Wait till children (properties) are fetched
|
|
// from the backend.
|
|
return waitForDispatch(panel, "FETCH_PROPERTIES");
|
|
});
|
|
}
|
|
|
|
function evaluateJSAsync(panel, expression) {
|
|
return new Promise(resolve => {
|
|
panel.target.activeConsole.evaluateJSAsync(expression, res => {
|
|
resolve(res);
|
|
});
|
|
});
|
|
}
|
|
|
|
function refreshPanel(panel) {
|
|
let doc = panel.panelWin.document;
|
|
let button = doc.querySelector(".btn.refresh");
|
|
return synthesizeMouseClickSoon(panel, button).then(() => {
|
|
// Wait till children (properties) are fetched
|
|
// from the backend.
|
|
return waitForDispatch(panel, "FETCH_PROPERTIES");
|
|
});
|
|
}
|
|
|
|
// Redux related API, use from shared location
|
|
// as soon as bug 1261076 is fixed.
|
|
|
|
// Wait until an action of `type` is dispatched. If it's part of an
|
|
// async operation, wait until the `status` field is "done" or "error"
|
|
function _afterDispatchDone(store, type) {
|
|
return new Promise(resolve => {
|
|
store.dispatch({
|
|
// Normally we would use `services.WAIT_UNTIL`, but use the
|
|
// internal name here so tests aren't forced to always pass it
|
|
// in
|
|
type: "@@service/waitUntil",
|
|
predicate: action => {
|
|
if (action.type === type) {
|
|
return action.status ?
|
|
(action.status === "end" || action.status === "error") :
|
|
true;
|
|
}
|
|
return false;
|
|
},
|
|
run: (dispatch, getState, action) => {
|
|
resolve(action);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
function waitForDispatch(panel, type, eventRepeat = 1) {
|
|
const store = panel.panelWin.view.mainFrame.store;
|
|
const actionType = constants[type];
|
|
let count = 0;
|
|
|
|
return Task.spawn(function* () {
|
|
info("Waiting for " + type + " to dispatch " + eventRepeat + " time(s)");
|
|
while (count < eventRepeat) {
|
|
yield _afterDispatchDone(store, actionType);
|
|
count++;
|
|
info(type + " dispatched " + count + " time(s)");
|
|
}
|
|
});
|
|
}
|