mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1181837 - 6 - Include inspector's head.js in rule and computed view tests to remove duplication; r=bgrins
This commit is contained in:
parent
f0bc872ead
commit
9b6ebd4e60
@ -28,7 +28,10 @@ let promise = require("promise");
|
||||
|
||||
const TEST_DIR = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
|
||||
const CHROME_URL_ROOT = TEST_DIR + "/";
|
||||
const URL_ROOT = CHROME_URL_ROOT.replace("chrome://mochitests/content/", "http://example.com/");
|
||||
const URL_ROOT = CHROME_URL_ROOT.replace("chrome://mochitests/content/",
|
||||
"http://example.com/");
|
||||
const URL_ROOT_SSL = CHROME_URL_ROOT.replace("chrome://mochitests/content/",
|
||||
"https://example.com/");
|
||||
|
||||
// All test are asynchronous
|
||||
waitForExplicitFinish();
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
const {PropertyView} =
|
||||
require("devtools/client/inspector/computed/computed");
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_matched_selectors.html";
|
||||
const TEST_URI = URL_ROOT + "doc_matched_selectors.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Tests that we correctly display appropriate media query titles in the
|
||||
// property view.
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_media_queries.html";
|
||||
const TEST_URI = URL_ROOT + "doc_media_queries.html";
|
||||
|
||||
var {PropertyView} = require("devtools/client/inspector/computed/computed");
|
||||
var {CssLogic} = require("devtools/shared/inspector/css-logic");
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Tests that the computed view shows the original source link when source maps
|
||||
// are enabled.
|
||||
|
||||
const TESTCASE_URI = TEST_URL_ROOT_SSL + "doc_sourcemaps.html";
|
||||
const TESTCASE_URI = URL_ROOT_SSL + "doc_sourcemaps.html";
|
||||
const PREF = "devtools.styleeditor.source-maps-enabled";
|
||||
const SCSS_LOC = "doc_sourcemaps.scss:4";
|
||||
const CSS_LOC = "doc_sourcemaps.css:1";
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
// Tests that pseudoelements are displayed correctly in the rule view.
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_pseudoelement.html";
|
||||
const TEST_URI = URL_ROOT + "doc_pseudoelement.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -19,7 +19,9 @@ add_task(function*() {
|
||||
|
||||
info("Changing the node's style and waiting for the update");
|
||||
let onUpdated = inspector.once("computed-view-refreshed");
|
||||
getNode("#testdiv").style.cssText = "font-size: 15px; color: red;";
|
||||
// FIXME: use the testActor to set style on the node.
|
||||
content.document.querySelector("#testdiv")
|
||||
.style.cssText = "font-size: 15px; color: red;";
|
||||
yield onUpdated;
|
||||
|
||||
fontSize = getComputedViewPropertyValue(view, "font-size");
|
||||
|
@ -44,7 +44,7 @@ add_task(function*() {
|
||||
yield checkSelectAll(view);
|
||||
});
|
||||
|
||||
function checkCopySelection(view) {
|
||||
function* checkCopySelection(view) {
|
||||
info("Testing selection copy");
|
||||
|
||||
let contentDocument = view.styleDocument;
|
||||
@ -63,16 +63,15 @@ function checkCopySelection(view) {
|
||||
"font-size: 16px;[\\r\\n]+" +
|
||||
"font-variant-caps: small-caps;[\\r\\n]*";
|
||||
|
||||
return waitForClipboard(() => {
|
||||
fireCopyEvent(props[0]);
|
||||
}, () => {
|
||||
return checkClipboardData(expectedPattern);
|
||||
}).then(() => {}, () => {
|
||||
try {
|
||||
yield waitForClipboard(() => fireCopyEvent(props[0]),
|
||||
() => checkClipboardData(expectedPattern));
|
||||
} catch (e) {
|
||||
failedClipboard(expectedPattern);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function checkSelectAll(view) {
|
||||
function* checkSelectAll(view) {
|
||||
info("Testing select-all copy");
|
||||
|
||||
let contentDoc = view.styleDocument;
|
||||
@ -86,13 +85,12 @@ function checkSelectAll(view) {
|
||||
"font-size: 16px;[\\r\\n]+" +
|
||||
"font-variant-caps: small-caps;[\\r\\n]*";
|
||||
|
||||
return waitForClipboard(() => {
|
||||
fireCopyEvent(prop);
|
||||
}, () => {
|
||||
return checkClipboardData(expectedPattern);
|
||||
}).then(() => {}, () => {
|
||||
try {
|
||||
yield waitForClipboard(() => fireCopyEvent(prop),
|
||||
() => checkClipboardData(expectedPattern));
|
||||
} catch (e) {
|
||||
failedClipboard(expectedPattern);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function checkClipboardData(expectedPattern) {
|
||||
|
@ -1,137 +1,31 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
let Cu = Components.utils;
|
||||
let {gDevTools} = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {});
|
||||
let {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
let {TargetFactory} = require("devtools/client/framework/target");
|
||||
let {CssComputedView} =
|
||||
require("devtools/client/inspector/computed/computed");
|
||||
let DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
let promise = require("promise");
|
||||
let {console} =
|
||||
Components.utils.import("resource://gre/modules/Console.jsm", {});
|
||||
// Import the inspector's head.js first (which itself imports shared-head.js).
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
|
||||
this);
|
||||
|
||||
// All tests are asynchronous
|
||||
waitForExplicitFinish();
|
||||
|
||||
const TEST_URL_ROOT =
|
||||
"http://example.com/browser/devtools/client/inspector/computed/test/";
|
||||
const TEST_URL_ROOT_SSL =
|
||||
"https://example.com/browser/devtools/client/inspector/computed/test/";
|
||||
const ROOT_TEST_DIR = getRootDirectory(gTestPath);
|
||||
const FRAME_SCRIPT_URL = ROOT_TEST_DIR + "doc_frame_script.js";
|
||||
|
||||
// Auto clean-up when a test ends
|
||||
registerCleanupFunction(function*() {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
yield gDevTools.closeToolbox(target);
|
||||
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
});
|
||||
|
||||
// Uncomment this pref to dump all devtools emitted events to the console.
|
||||
// Services.prefs.setBoolPref("devtools.dump.emit", true);
|
||||
|
||||
// Set the testing flag on gDevTools and reset it when the test ends
|
||||
DevToolsUtils.testing = true;
|
||||
registerCleanupFunction(() => DevToolsUtils.testing = false);
|
||||
|
||||
// Clean-up all prefs that might have been changed during a test run
|
||||
// (safer here because if the test fails, then the pref is never reverted)
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.inspector.activeSidebar");
|
||||
Services.prefs.clearUserPref("devtools.dump.emit");
|
||||
Services.prefs.clearUserPref("devtools.defaultColorUnit");
|
||||
});
|
||||
|
||||
/**
|
||||
* The functions found below are here to ease test development and maintenance.
|
||||
* Most of these functions are stateless and will require some form of context
|
||||
* (the instance of the current toolbox, or inspector panel for instance).
|
||||
*
|
||||
* Most of these functions are async too and return promises.
|
||||
*
|
||||
* All tests should follow the following pattern:
|
||||
*
|
||||
* add_task(function*() {
|
||||
* yield addTab(TEST_URI);
|
||||
* let {toolbox, inspector, view} = yield openComputedView();
|
||||
*
|
||||
* yield selectNode("#test", inspector);
|
||||
* yield someAsyncTestFunction(view);
|
||||
* });
|
||||
*
|
||||
* add_task is the way to define the testcase in the test file. It accepts
|
||||
* a single generator-function argument.
|
||||
* The generator function should yield any async call.
|
||||
*
|
||||
* There is no need to clean tabs up at the end of a test as this is done
|
||||
* automatically.
|
||||
*
|
||||
* It is advised not to store any references on the global scope. There
|
||||
* shouldn't be a need to anyway. Thanks to add_task, test steps, even
|
||||
* though asynchronous, can be described in a nice flat way, and
|
||||
* if/for/while/... control flow can be used as in sync code, making it
|
||||
* possible to write the outline of the test case all in add_task, and delegate
|
||||
* actual processing and assertions to other functions.
|
||||
* Open the toolbox, with the inspector tool visible, and the computed-view
|
||||
* sidebar tab selected.
|
||||
* @return a promise that resolves when the inspector is ready and the computed
|
||||
* view is visible and ready
|
||||
*/
|
||||
|
||||
/* *********************************************
|
||||
* UTILS
|
||||
* *********************************************
|
||||
* General test utilities.
|
||||
* Add new tabs, open the toolbox and switch to the various panels, select
|
||||
* nodes, get node references, ...
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 addTab(url) {
|
||||
info("Adding a new tab with URL: '" + url + "'");
|
||||
let def = promise.defer();
|
||||
|
||||
window.focus();
|
||||
|
||||
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
|
||||
let browser = tab.linkedBrowser;
|
||||
|
||||
info("Loading the helper frame script " + FRAME_SCRIPT_URL);
|
||||
browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
|
||||
|
||||
browser.addEventListener("load", function onload() {
|
||||
browser.removeEventListener("load", onload, true);
|
||||
info("URL '" + url + "' loading complete");
|
||||
|
||||
def.resolve(tab);
|
||||
}, true);
|
||||
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple DOM node accesor function that takes either a node or a string css
|
||||
* selector as argument and returns the corresponding node
|
||||
*
|
||||
* @param {String|DOMNode} nodeOrSelector
|
||||
* @return {DOMNode|CPOW} Note that in e10s mode a CPOW object is returned which
|
||||
* doesn't implement *all* of the DOMNode's properties
|
||||
*/
|
||||
function getNode(nodeOrSelector) {
|
||||
info("Getting the node for '" + nodeOrSelector + "'");
|
||||
return typeof nodeOrSelector === "string" ?
|
||||
content.document.querySelector(nodeOrSelector) :
|
||||
nodeOrSelector;
|
||||
function openComputedView() {
|
||||
return openInspectorSidebarTab("computedview").then(objects => {
|
||||
return {
|
||||
toolbox: objects.toolbox,
|
||||
inspector: objects.inspector,
|
||||
view: objects.view.view
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -146,187 +40,6 @@ function getNodeFront(selector, {walker}) {
|
||||
return walker.querySelector(walker.rootNode, selector);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the inspector's current selection to a node or to the first match of the
|
||||
* given css selector.
|
||||
*
|
||||
* @param {String|NodeFront} data
|
||||
* The node to select
|
||||
* @param {InspectorPanel} inspector
|
||||
* The instance of InspectorPanel currently loaded in the toolbox
|
||||
* @param {String} reason
|
||||
* Defaults to "test" which instructs the inspector not
|
||||
* to highlight the node upon selection
|
||||
* @return {Promise} Resolves when the inspector is updated with the new node
|
||||
*/
|
||||
var selectNode = Task.async(function*(data, inspector, reason="test") {
|
||||
info("Selecting the node for '" + data + "'");
|
||||
let nodeFront = data;
|
||||
if (!data._form) {
|
||||
nodeFront = yield getNodeFront(data, inspector);
|
||||
}
|
||||
let updated = inspector.once("inspector-updated");
|
||||
inspector.selection.setNodeFront(nodeFront, reason);
|
||||
yield updated;
|
||||
});
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible.
|
||||
*
|
||||
* @return a promise that resolves when the inspector is ready
|
||||
*/
|
||||
var openInspector = Task.async(function*() {
|
||||
info("Opening the inspector");
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
|
||||
let inspector, toolbox;
|
||||
|
||||
// Checking if the toolbox and the inspector are already loaded
|
||||
// The inspector-updated event should only be waited for if the inspector
|
||||
// isn't loaded yet
|
||||
toolbox = gDevTools.getToolbox(target);
|
||||
if (toolbox) {
|
||||
inspector = toolbox.getPanel("inspector");
|
||||
if (inspector) {
|
||||
info("Toolbox and inspector already open");
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
info("Opening the toolbox");
|
||||
toolbox = yield gDevTools.showToolbox(target, "inspector");
|
||||
yield waitForToolboxFrameFocus(toolbox);
|
||||
inspector = toolbox.getPanel("inspector");
|
||||
|
||||
info("Waiting for the inspector to update");
|
||||
yield inspector.once("inspector-updated");
|
||||
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Wait for the toolbox frame to receive focus after it loads
|
||||
*
|
||||
* @param {Toolbox} toolbox
|
||||
* @return a promise that resolves when focus has been received
|
||||
*/
|
||||
function waitForToolboxFrameFocus(toolbox) {
|
||||
info("Making sure that the toolbox's frame is focused");
|
||||
let def = promise.defer();
|
||||
let win = toolbox.frame.contentWindow;
|
||||
waitForFocus(def.resolve, win);
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the sidebar that
|
||||
* corresponds to the given id selected
|
||||
*
|
||||
* @return a promise that resolves when the inspector is ready and the sidebar
|
||||
* view is visible and ready
|
||||
*/
|
||||
var openInspectorSideBar = Task.async(function*(id) {
|
||||
let {toolbox, inspector} = yield openInspector();
|
||||
|
||||
if (!hasSideBarTab(inspector, id)) {
|
||||
info("Waiting for the " + id + " sidebar to be ready");
|
||||
yield inspector.sidebar.once(id + "-ready");
|
||||
}
|
||||
|
||||
info("Selecting the " + id + " sidebar");
|
||||
inspector.sidebar.select(id);
|
||||
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector,
|
||||
view: inspector.sidebar.getWindowForTab(id)[id].view
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the computed-view
|
||||
* sidebar tab selected.
|
||||
*
|
||||
* @return a promise that resolves when the inspector is ready and the computed
|
||||
* view is visible and ready
|
||||
*/
|
||||
function openComputedView() {
|
||||
return openInspectorSideBar("computedview");
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for eventName on target to be delivered a number of times.
|
||||
*
|
||||
* @param {Object} target
|
||||
* An observable object that either supports on/off or
|
||||
* addEventListener/removeEventListener
|
||||
* @param {String} eventName
|
||||
* @param {Number} numTimes
|
||||
* Number of deliveries to wait for.
|
||||
* @param {Boolean} useCapture
|
||||
* Optional, for addEventListener/removeEventListener
|
||||
* @return A promise that resolves when the event has been handled
|
||||
*/
|
||||
function waitForNEvents(target, eventName, numTimes, useCapture = false) {
|
||||
info("Waiting for event: '" + eventName + "' on " + target + ".");
|
||||
|
||||
let deferred = promise.defer();
|
||||
let count = 0;
|
||||
|
||||
for (let [add, remove] of [
|
||||
["addEventListener", "removeEventListener"],
|
||||
["addListener", "removeListener"],
|
||||
["on", "off"]
|
||||
]) {
|
||||
if ((add in target) && (remove in target)) {
|
||||
target[add](eventName, function onEvent(...aArgs) {
|
||||
if (++count == numTimes) {
|
||||
target[remove](eventName, onEvent, useCapture);
|
||||
deferred.resolve.apply(deferred, aArgs);
|
||||
}
|
||||
}, useCapture);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for eventName on target.
|
||||
*
|
||||
* @param {Object} target
|
||||
* An observable object that either supports on/off or
|
||||
* addEventListener/removeEventListener
|
||||
* @param {String} eventName
|
||||
* @param {Boolean} useCapture
|
||||
* Optional, for addEventListener/removeEventListener
|
||||
* @return A promise that resolves when the event has been handled
|
||||
*/
|
||||
function once(target, eventName, useCapture=false) {
|
||||
return waitForNEvents(target, eventName, 1, useCapture);
|
||||
}
|
||||
|
||||
/**
|
||||
* This shouldn't be used in the tests, but is useful when writing new tests or
|
||||
* debugging existing tests in order to introduce delays in the test steps
|
||||
*
|
||||
* @param {Number} ms
|
||||
* The time to wait
|
||||
* @return A promise that resolves when the time is passed
|
||||
*/
|
||||
function wait(ms) {
|
||||
let def = promise.defer();
|
||||
content.setTimeout(def.resolve, ms);
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen for a new tab to open and return a promise that resolves when one
|
||||
* does and completes the load event.
|
||||
@ -343,23 +56,6 @@ var waitForTab = Task.async(function*() {
|
||||
return tab;
|
||||
});
|
||||
|
||||
/**
|
||||
* @see SimpleTest.waitForClipboard
|
||||
*
|
||||
* @param {Function} setup
|
||||
* Function to execute before checking for the
|
||||
* clipboard content
|
||||
* @param {String|Boolean} expected
|
||||
* An expected string or validator function
|
||||
* @return a promise that resolves when the expected string has been found or
|
||||
* the validator function has returned true, rejects otherwise.
|
||||
*/
|
||||
function waitForClipboard(setup, expected) {
|
||||
let def = promise.defer();
|
||||
SimpleTest.waitForClipboard(expected, setup, def.resolve, def.reject);
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the copy event on the given element
|
||||
*/
|
||||
@ -369,18 +65,6 @@ function fireCopyEvent(element) {
|
||||
element.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the inspector's sidebar corresponding to the given id already
|
||||
* exists
|
||||
*
|
||||
* @param {InspectorPanel}
|
||||
* @param {String}
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function hasSideBarTab(inspector, id) {
|
||||
return !!inspector.sidebar.getWindowForTab(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simulate the key input for the given input in the window.
|
||||
*
|
||||
@ -395,13 +79,6 @@ function synthesizeKeys(input, win) {
|
||||
}
|
||||
}
|
||||
|
||||
/* *********************************************
|
||||
* COMPUTED-VIEW
|
||||
* *********************************************
|
||||
* Computed-view related utility functions.
|
||||
* Allows to get properties, links, expand properties, ...
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get references to the name and value span nodes corresponding to a given
|
||||
* property name in the computed-view
|
||||
@ -534,77 +211,3 @@ function getComputedViewLinkByIndex(view, index) {
|
||||
let links = view.styleDocument.querySelectorAll(".rule-link .link");
|
||||
return links[index];
|
||||
}
|
||||
|
||||
/* *********************************************
|
||||
* STYLE-EDITOR
|
||||
* *********************************************
|
||||
* Style-editor related utility functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wait for the toolbox to emit the styleeditor-selected event and when done
|
||||
* wait for the stylesheet identified by href to be loaded in the stylesheet
|
||||
* editor
|
||||
*
|
||||
* @param {Toolbox} toolbox
|
||||
* @param {String} href
|
||||
* Optional, if not provided, wait for the first editor to be ready
|
||||
* @return a promise that resolves to the editor when the stylesheet editor is
|
||||
* ready
|
||||
*/
|
||||
function waitForStyleEditor(toolbox, href) {
|
||||
let def = promise.defer();
|
||||
|
||||
info("Waiting for the toolbox to switch to the styleeditor");
|
||||
toolbox.once("styleeditor-selected").then(() => {
|
||||
let panel = toolbox.getCurrentPanel();
|
||||
ok(panel && panel.UI, "Styleeditor panel switched to front");
|
||||
|
||||
// A helper that resolves the promise once it receives an editor that
|
||||
// matches the expected href. Returns false if the editor was not correct.
|
||||
let gotEditor = (event, editor) => {
|
||||
let currentHref = editor.styleSheet.href;
|
||||
if (!href || (href && currentHref.endsWith(href))) {
|
||||
info("Stylesheet editor selected");
|
||||
panel.UI.off("editor-selected", gotEditor);
|
||||
|
||||
editor.getSourceEditor().then(sourceEditor => {
|
||||
info("Stylesheet editor fully loaded");
|
||||
def.resolve(sourceEditor);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
info("The editor was incorrect. Waiting for editor-selected event.");
|
||||
return false;
|
||||
};
|
||||
|
||||
// The expected editor may already be selected. Check the if the currently
|
||||
// selected editor is the expected one and if not wait for an
|
||||
// editor-selected event.
|
||||
if (!gotEditor("styleeditor-selected", panel.UI.selectedEditor)) {
|
||||
// The expected editor is not selected (yet). Wait for it.
|
||||
panel.UI.on("editor-selected", gotEditor);
|
||||
}
|
||||
});
|
||||
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the current page and wait for the inspector to be initialized after
|
||||
* the navigation
|
||||
*
|
||||
* @param {InspectorPanel} inspector
|
||||
* The instance of InspectorPanel currently loaded in the toolbox
|
||||
* @return a promise that resolves after page reload and inspector
|
||||
* initialization
|
||||
*/
|
||||
function reloadPage(inspector) {
|
||||
let onNewRoot = inspector.once("new-root");
|
||||
content.location.reload();
|
||||
return onNewRoot.then(() => {
|
||||
inspector.markup._waitForChildren();
|
||||
});
|
||||
}
|
||||
|
@ -45,52 +45,29 @@ function selectAndHighlightNode(nodeOrSelector, inspector) {
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the inspector's sidebar corresponding to the given id already
|
||||
* exists
|
||||
* @param {InspectorPanel}
|
||||
* @param {String}
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function hasSideBarTab(inspector, id) {
|
||||
return !!inspector.sidebar.getWindowForTab(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the layout-view
|
||||
* sidebar tab selected.
|
||||
* @return a promise that resolves when the inspector is ready and the layout
|
||||
* view is visible and ready
|
||||
*/
|
||||
var openLayoutView = Task.async(function*() {
|
||||
let {toolbox, inspector} = yield openInspector();
|
||||
function openLayoutView() {
|
||||
return openInspectorSidebarTab("layoutview").then(objects => {
|
||||
// The actual highligher show/hide methods are mocked in layoutview tests.
|
||||
// The highlighter is tested in devtools/inspector/test.
|
||||
function mockHighlighter({highlighter}) {
|
||||
highlighter.showBoxModel = function(nodeFront, options) {
|
||||
return promise.resolve();
|
||||
};
|
||||
highlighter.hideBoxModel = function() {
|
||||
return promise.resolve();
|
||||
};
|
||||
}
|
||||
mockHighlighter(objects.toolbox);
|
||||
|
||||
// The actual highligher show/hide methods are mocked in layoutview tests.
|
||||
// The highlighter is tested in devtools/inspector/test.
|
||||
function mockHighlighter({highlighter}) {
|
||||
highlighter.showBoxModel = function(nodeFront, options) {
|
||||
return promise.resolve();
|
||||
};
|
||||
highlighter.hideBoxModel = function() {
|
||||
return promise.resolve();
|
||||
};
|
||||
}
|
||||
mockHighlighter(toolbox);
|
||||
|
||||
if (!hasSideBarTab(inspector, "layoutview")) {
|
||||
info("Waiting for the layoutview sidebar to be ready");
|
||||
yield inspector.sidebar.once("layoutview-ready");
|
||||
}
|
||||
|
||||
info("Selecting the layoutview sidebar");
|
||||
inspector.sidebar.select("layoutview");
|
||||
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector,
|
||||
view: inspector.sidebar.getWindowForTab("layoutview")["layoutview"]
|
||||
};
|
||||
});
|
||||
return objects;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the layoutview-updated event.
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Tests that adding properties to rules work and reselecting the element still
|
||||
// show them.
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_content_stylesheet.html";
|
||||
const TEST_URI = URL_ROOT + "doc_content_stylesheet.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -39,7 +39,7 @@ add_task(function* () {
|
||||
});
|
||||
|
||||
function* testShowMdnTooltip(view) {
|
||||
setBaseCssDocsUrl(TEST_URL_ROOT);
|
||||
setBaseCssDocsUrl(URL_ROOT);
|
||||
|
||||
info("Setting the popupNode for the MDN docs tooltip");
|
||||
|
||||
|
@ -13,7 +13,7 @@ XPCOMUtils.defineLazyGetter(this, "osString", function() {
|
||||
return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).OS;
|
||||
});
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_copystyles.html";
|
||||
const TEST_URI = URL_ROOT + "doc_copystyles.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Test to ensure that CSSOM doesn't make the rule view blow up.
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1224121
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_cssom.html";
|
||||
const TEST_URI = URL_ROOT + "doc_cssom.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_custom.html";
|
||||
const TEST_URI = URL_ROOT + "doc_custom.html";
|
||||
|
||||
// Tests the display of custom declarations in the rule-view.
|
||||
|
||||
|
@ -23,7 +23,7 @@ const TEST_URI = `
|
||||
<div id="testid2">Styled Node</div>
|
||||
`;
|
||||
|
||||
var BACKGROUND_IMAGE_URL = 'url("' + TEST_URL_ROOT + 'doc_test_image.png")';
|
||||
var BACKGROUND_IMAGE_URL = 'url("' + URL_ROOT + 'doc_test_image.png")';
|
||||
|
||||
var TEST_DATA = [
|
||||
{ name: "border-color", value: "red", isValid: true },
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// Tests the that Filter Editor Tooltip opens by clicking on filter swatches
|
||||
|
||||
const TEST_URL = TEST_URL_ROOT + "doc_filter.html";
|
||||
const TEST_URL = URL_ROOT + "doc_filter.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URL);
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
// Tests the Filter Editor Tooltip committing changes on ENTER
|
||||
|
||||
const TEST_URL = TEST_URL_ROOT + "doc_filter.html";
|
||||
const TEST_URL = URL_ROOT + "doc_filter.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URL);
|
||||
|
@ -6,7 +6,7 @@
|
||||
// Tests that changes made to the Filter Editor Tooltip are reverted when
|
||||
// ESC is pressed
|
||||
|
||||
const TEST_URL = TEST_URL_ROOT + "doc_filter.html";
|
||||
const TEST_URL = URL_ROOT + "doc_filter.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URL);
|
||||
|
@ -7,9 +7,6 @@
|
||||
// Tests that we can guess indentation from a style sheet, not just a
|
||||
// rule.
|
||||
|
||||
// Needed for openStyleEditor.
|
||||
Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/client/styleeditor/test/head.js", this);
|
||||
|
||||
// Use a weird indentation depth to avoid accidental success.
|
||||
const TEST_URI = `
|
||||
<style type='text/css'>
|
||||
@ -35,12 +32,12 @@ div {
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI));
|
||||
let {inspector, view} = yield openRuleView();
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
yield selectNode("#testid", inspector);
|
||||
yield testIndentation(inspector, view);
|
||||
yield testIndentation(toolbox, inspector, view);
|
||||
});
|
||||
|
||||
function* testIndentation(inspector, view) {
|
||||
function* testIndentation(toolbox, inspector, view) {
|
||||
let ruleEditor = getRuleViewRuleEditor(view, 2);
|
||||
|
||||
info("Focusing a new property name in the rule-view");
|
||||
@ -68,9 +65,9 @@ function* testIndentation(inspector, view) {
|
||||
yield onBlur;
|
||||
yield onModifications;
|
||||
|
||||
let { ui } = yield openStyleEditor();
|
||||
let { UI } = yield toolbox.selectTool("styleeditor");
|
||||
|
||||
let styleEditor = yield ui.editors[0].getSourceEditor();
|
||||
let styleEditor = yield UI.editors[0].getSourceEditor();
|
||||
let text = styleEditor.sourceEditor.getText();
|
||||
is(text, expectedText, "style inspector changes are synced");
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Test that editing a rule will update the line numbers of subsequent
|
||||
// rules in the rule view.
|
||||
|
||||
const TESTCASE_URI = TEST_URL_ROOT + "doc_keyframeLineNumbers.html";
|
||||
const TESTCASE_URI = URL_ROOT + "doc_keyframeLineNumbers.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TESTCASE_URI);
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Test that keyframe rules and gutters are displayed correctly in the
|
||||
// rule view.
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_keyframeanimation.html";
|
||||
const TEST_URI = URL_ROOT + "doc_keyframeanimation.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Test that verifies the content of the keyframes rule and property changes
|
||||
// to keyframe rules.
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_keyframeanimation.html";
|
||||
const TEST_URI = URL_ROOT + "doc_keyframeanimation.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Test that editing a rule will update the line numbers of subsequent
|
||||
// rules in the rule view.
|
||||
|
||||
const TESTCASE_URI = TEST_URL_ROOT + "doc_ruleLineNumbers.html";
|
||||
const TESTCASE_URI = URL_ROOT + "doc_ruleLineNumbers.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TESTCASE_URI);
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Tests that we correctly display appropriate media query titles in the
|
||||
// rule view.
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_media_queries.html";
|
||||
const TEST_URI = URL_ROOT + "doc_media_queries.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Test that the stylesheet links in the rule view are correct when source maps
|
||||
// are involved.
|
||||
|
||||
const TESTCASE_URI = TEST_URL_ROOT + "doc_sourcemaps.html";
|
||||
const TESTCASE_URI = URL_ROOT + "doc_sourcemaps.html";
|
||||
const PREF = "devtools.styleeditor.source-maps-enabled";
|
||||
const SCSS_LOC = "doc_sourcemaps.scss:4";
|
||||
const CSS_LOC = "doc_sourcemaps.css:1";
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
// Test that pseudoelements are displayed correctly in the rule view
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_pseudoelement.html";
|
||||
const TEST_URI = URL_ROOT + "doc_pseudoelement.html";
|
||||
const PSEUDO_PREF = "devtools.inspector.show_pseudo_elements";
|
||||
|
||||
add_task(function*() {
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
// Test that pseudoelements are displayed correctly in the rule view
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_pseudoelement.html";
|
||||
const TEST_URI = URL_ROOT + "doc_pseudoelement.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -8,7 +8,7 @@
|
||||
// selectors.
|
||||
|
||||
const SEARCH = "20%";
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_keyframeanimation.html";
|
||||
const TEST_URI = URL_ROOT + "doc_keyframeanimation.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -7,7 +7,7 @@
|
||||
// Tests that the rule view search filter works properly for stylesheet source.
|
||||
|
||||
const SEARCH = "doc_urls_clickable.css";
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_urls_clickable.html";
|
||||
const TEST_URI = URL_ROOT + "doc_urls_clickable.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -8,7 +8,7 @@
|
||||
// input that could be parsed as a property line.
|
||||
|
||||
const SEARCH = "doc_urls_clickable.css: url";
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_urls_clickable.html";
|
||||
const TEST_URI = URL_ROOT + "doc_urls_clickable.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -8,7 +8,7 @@
|
||||
// source.
|
||||
|
||||
const SEARCH = "`doc_urls_clickable.css:1`";
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_urls_clickable.html";
|
||||
const TEST_URI = URL_ROOT + "doc_urls_clickable.html";
|
||||
|
||||
add_task(function*() {
|
||||
yield addTab(TEST_URI);
|
||||
|
@ -19,7 +19,7 @@ const STYLESHEET_URL = "data:text/css,"+encodeURIComponent(
|
||||
"}"].join("\n"));
|
||||
|
||||
const EXTERNAL_STYLESHEET_FILE_NAME = "doc_style_editor_link.css";
|
||||
const EXTERNAL_STYLESHEET_URL = TEST_URL_ROOT + EXTERNAL_STYLESHEET_FILE_NAME;
|
||||
const EXTERNAL_STYLESHEET_URL = URL_ROOT + EXTERNAL_STYLESHEET_FILE_NAME;
|
||||
|
||||
const DOCUMENT_URL = "data:text/html;charset=utf-8,"+encodeURIComponent(
|
||||
['<html>' +
|
||||
|
@ -6,8 +6,8 @@
|
||||
|
||||
// Tests to make sure that URLs are clickable in the rule view
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_urls_clickable.html";
|
||||
const TEST_IMAGE = TEST_URL_ROOT + "doc_test_image.png";
|
||||
const TEST_URI = URL_ROOT + "doc_urls_clickable.html";
|
||||
const TEST_IMAGE = URL_ROOT + "doc_test_image.png";
|
||||
const BASE_64_URL = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAA" +
|
||||
"FCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAA" +
|
||||
"BJRU5ErkJggg==";
|
||||
|
@ -10,7 +10,7 @@
|
||||
var PREF_UA_STYLES = "devtools.inspector.showUserAgentStyles";
|
||||
const { PrefObserver } = require("devtools/client/styleeditor/utils");
|
||||
|
||||
const TEST_URI = TEST_URL_ROOT + "doc_author-sheet.html";
|
||||
const TEST_URI = URL_ROOT + "doc_author-sheet.html";
|
||||
|
||||
const TEST_DATA = [
|
||||
{
|
||||
|
@ -1,125 +1,60 @@
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
var Cu = Components.utils;
|
||||
var {gDevTools} = Cu.import("resource://devtools/client/framework/gDevTools.jsm", {});
|
||||
var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
var {TargetFactory} = require("devtools/client/framework/target");
|
||||
var {CssRuleView, _ElementStyle} =
|
||||
require("devtools/client/inspector/rules/rules");
|
||||
var {CssLogic, CssSelector} = require("devtools/shared/inspector/css-logic");
|
||||
var DevToolsUtils = require("devtools/shared/DevToolsUtils");
|
||||
var promise = require("promise");
|
||||
var {editableField, getInplaceEditorForSpan: inplaceEditor} =
|
||||
// Import the inspector's head.js first (which itself imports shared-head.js).
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/inspector/test/head.js",
|
||||
this);
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.defaultColorUnit");
|
||||
});
|
||||
|
||||
var {CssLogic} = require("devtools/shared/inspector/css-logic");
|
||||
var {getInplaceEditorForSpan: inplaceEditor} =
|
||||
require("devtools/client/shared/inplace-editor");
|
||||
var {console} =
|
||||
Components.utils.import("resource://gre/modules/Console.jsm", {});
|
||||
|
||||
// All tests are asynchronous
|
||||
waitForExplicitFinish();
|
||||
|
||||
const TEST_URL_ROOT =
|
||||
"http://example.com/browser/devtools/client/inspector/rules/test/";
|
||||
const TEST_URL_ROOT_SSL =
|
||||
"https://example.com/browser/devtools/client/inspector/rules/test/";
|
||||
const ROOT_TEST_DIR = getRootDirectory(gTestPath);
|
||||
const FRAME_SCRIPT_URL = ROOT_TEST_DIR + "doc_frame_script.js";
|
||||
|
||||
// Auto clean-up when a test ends
|
||||
registerCleanupFunction(function*() {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
yield gDevTools.closeToolbox(target);
|
||||
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
});
|
||||
|
||||
// Uncomment this pref to dump all devtools emitted events to the console.
|
||||
// Services.prefs.setBoolPref("devtools.dump.emit", true);
|
||||
|
||||
// Set the testing flag on gDevTools and reset it when the test ends
|
||||
DevToolsUtils.testing = true;
|
||||
registerCleanupFunction(() => DevToolsUtils.testing = false);
|
||||
|
||||
// Clean-up all prefs that might have been changed during a test run
|
||||
// (safer here because if the test fails, then the pref is never reverted)
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.inspector.activeSidebar");
|
||||
Services.prefs.clearUserPref("devtools.dump.emit");
|
||||
Services.prefs.clearUserPref("devtools.defaultColorUnit");
|
||||
});
|
||||
|
||||
/**
|
||||
* The functions found below are here to ease test development and maintenance.
|
||||
* Most of these functions are stateless and will require some form of context
|
||||
* (the instance of the current toolbox, or inspector panel for instance).
|
||||
*
|
||||
* Most of these functions are async too and return promises.
|
||||
*
|
||||
* All tests should follow the following pattern:
|
||||
*
|
||||
* add_task(function*() {
|
||||
* yield addTab(TEST_URI);
|
||||
* let {toolbox, inspector, view} = yield openComputedView();
|
||||
*
|
||||
* yield selectNode("#test", inspector);
|
||||
* yield someAsyncTestFunction(view);
|
||||
* });
|
||||
*
|
||||
* add_task is the way to define the testcase in the test file. It accepts
|
||||
* a single generator-function argument.
|
||||
* The generator function should yield any async call.
|
||||
*
|
||||
* There is no need to clean tabs up at the end of a test as this is done
|
||||
* automatically.
|
||||
*
|
||||
* It is advised not to store any references on the global scope. There
|
||||
* shouldn't be a need to anyway. Thanks to add_task, test steps, even
|
||||
* though asynchronous, can be described in a nice flat way, and
|
||||
* if/for/while/... control flow can be used as in sync code, making it
|
||||
* possible to write the outline of the test case all in add_task, and delegate
|
||||
* actual processing and assertions to other functions.
|
||||
*/
|
||||
|
||||
/* *********************************************
|
||||
* UTILS
|
||||
* *********************************************
|
||||
* General test utilities.
|
||||
* Add new tabs, open the toolbox and switch to the various panels, select
|
||||
* nodes, get node references, ...
|
||||
* The rule-view tests rely on a frame-script to be injected in the content test
|
||||
* page. So override the shared-head's addTab to load the frame script after the
|
||||
* tab was added.
|
||||
* FIXME: Refactor the rule-view tests to use the testActor instead of a frame
|
||||
* script, so they can run on remote targets too.
|
||||
*/
|
||||
var _addTab = addTab;
|
||||
addTab = function(url) {
|
||||
return _addTab(url).then(tab => {
|
||||
info("Loading the helper frame script " + FRAME_SCRIPT_URL);
|
||||
let browser = tab.linkedBrowser;
|
||||
browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
|
||||
return tab;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new test tab in the browser and load the given url.
|
||||
* Open the toolbox, with the inspector tool visible, and the rule-view
|
||||
* sidebar tab selected.
|
||||
*
|
||||
* @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
|
||||
* @return a promise that resolves when the inspector is ready and the rule
|
||||
* view is visible and ready
|
||||
*/
|
||||
function addTab(url) {
|
||||
info("Adding a new tab with URL: '" + url + "'");
|
||||
let def = promise.defer();
|
||||
|
||||
window.focus();
|
||||
|
||||
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
|
||||
let browser = tab.linkedBrowser;
|
||||
|
||||
info("Loading the helper frame script " + FRAME_SCRIPT_URL);
|
||||
browser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false);
|
||||
|
||||
browser.addEventListener("load", function onload() {
|
||||
browser.removeEventListener("load", onload, true);
|
||||
info("URL '" + url + "' loading complete");
|
||||
|
||||
def.resolve(tab);
|
||||
}, true);
|
||||
|
||||
return def.promise;
|
||||
function openRuleView() {
|
||||
return openInspectorSidebarTab("ruleview").then(objects => {
|
||||
return {
|
||||
toolbox: objects.toolbox,
|
||||
inspector: objects.inspector,
|
||||
view: objects.view.view
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -137,42 +72,6 @@ function getNode(nodeOrSelector) {
|
||||
nodeOrSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NodeFront for a given css selector, via the protocol
|
||||
*
|
||||
* @param {String} selector
|
||||
* @param {InspectorPanel} inspector
|
||||
* The instance of InspectorPanel currently loaded in the toolbox
|
||||
* @return {Promise} Resolves to the NodeFront instance
|
||||
*/
|
||||
function getNodeFront(selector, {walker}) {
|
||||
return walker.querySelector(walker.rootNode, selector);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the inspector's current selection to a node or to the first match of the
|
||||
* given css selector.
|
||||
*
|
||||
* @param {String|NodeFront} data
|
||||
* The node to select
|
||||
* @param {InspectorPanel} inspector
|
||||
* The instance of InspectorPanel currently loaded in the toolbox
|
||||
* @param {String} reason
|
||||
* Defaults to "test" which instructs the inspector not
|
||||
* to highlight the node upon selection
|
||||
* @return {Promise} Resolves when the inspector is updated with the new node
|
||||
*/
|
||||
var selectNode = Task.async(function*(data, inspector, reason="test") {
|
||||
info("Selecting the node for '" + data + "'");
|
||||
let nodeFront = data;
|
||||
if (!data._form) {
|
||||
nodeFront = yield getNodeFront(data, inspector);
|
||||
}
|
||||
let updated = inspector.once("inspector-updated");
|
||||
inspector.selection.setNodeFront(nodeFront, reason);
|
||||
yield updated;
|
||||
});
|
||||
|
||||
/**
|
||||
* Set the inspector's current selection to null so that no node is selected
|
||||
*
|
||||
@ -187,107 +86,6 @@ function clearCurrentNodeSelection(inspector) {
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible.
|
||||
*
|
||||
* @return a promise that resolves when the inspector is ready
|
||||
*/
|
||||
var openInspector = Task.async(function*() {
|
||||
info("Opening the inspector");
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
|
||||
let inspector, toolbox;
|
||||
|
||||
// Checking if the toolbox and the inspector are already loaded
|
||||
// The inspector-updated event should only be waited for if the inspector
|
||||
// isn't loaded yet
|
||||
toolbox = gDevTools.getToolbox(target);
|
||||
if (toolbox) {
|
||||
inspector = toolbox.getPanel("inspector");
|
||||
if (inspector) {
|
||||
info("Toolbox and inspector already open");
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
info("Opening the toolbox");
|
||||
toolbox = yield gDevTools.showToolbox(target, "inspector");
|
||||
yield waitForToolboxFrameFocus(toolbox);
|
||||
inspector = toolbox.getPanel("inspector");
|
||||
|
||||
info("Waiting for the inspector to update");
|
||||
yield inspector.once("inspector-updated");
|
||||
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Wait for the toolbox frame to receive focus after it loads
|
||||
*
|
||||
* @param {Toolbox} toolbox
|
||||
* @return a promise that resolves when focus has been received
|
||||
*/
|
||||
function waitForToolboxFrameFocus(toolbox) {
|
||||
info("Making sure that the toolbox's frame is focused");
|
||||
let def = promise.defer();
|
||||
let win = toolbox.frame.contentWindow;
|
||||
waitForFocus(def.resolve, win);
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the sidebar that
|
||||
* corresponds to the given id selected
|
||||
*
|
||||
* @return a promise that resolves when the inspector is ready and the sidebar
|
||||
* view is visible and ready
|
||||
*/
|
||||
var openInspectorSideBar = Task.async(function*(id) {
|
||||
let {toolbox, inspector} = yield openInspector();
|
||||
|
||||
if (!hasSideBarTab(inspector, id)) {
|
||||
info("Waiting for the " + id + " sidebar to be ready");
|
||||
yield inspector.sidebar.once(id + "-ready");
|
||||
}
|
||||
|
||||
info("Selecting the " + id + " sidebar");
|
||||
inspector.sidebar.select(id);
|
||||
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector,
|
||||
view: inspector.sidebar.getWindowForTab(id)[id].view
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the computed-view
|
||||
* sidebar tab selected.
|
||||
*
|
||||
* @return a promise that resolves when the inspector is ready and the computed
|
||||
* view is visible and ready
|
||||
*/
|
||||
function openComputedView() {
|
||||
return openInspectorSideBar("computedview");
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the rule-view
|
||||
* sidebar tab selected.
|
||||
*
|
||||
* @return a promise that resolves when the inspector is ready and the rule
|
||||
* view is visible and ready
|
||||
*/
|
||||
function openRuleView() {
|
||||
return openInspectorSideBar("ruleview");
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for eventName on target to be delivered a number of times.
|
||||
*
|
||||
@ -326,21 +124,6 @@ function waitForNEvents(target, eventName, numTimes, useCapture = false) {
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for eventName on target.
|
||||
*
|
||||
* @param {Object} target
|
||||
* An observable object that either supports on/off or
|
||||
* addEventListener/removeEventListener
|
||||
* @param {String} eventName
|
||||
* @param {Boolean} useCapture
|
||||
* Optional, for addEventListener/removeEventListener
|
||||
* @return A promise that resolves when the event has been handled
|
||||
*/
|
||||
function once(target, eventName, useCapture=false) {
|
||||
return waitForNEvents(target, eventName, 1, useCapture);
|
||||
}
|
||||
|
||||
/**
|
||||
* This shouldn't be used in the tests, but is useful when writing new tests or
|
||||
* debugging existing tests in order to introduce delays in the test steps
|
||||
@ -513,23 +296,6 @@ var waitForTab = Task.async(function*() {
|
||||
return tab;
|
||||
});
|
||||
|
||||
/**
|
||||
* @see SimpleTest.waitForClipboard
|
||||
*
|
||||
* @param {Function} setup
|
||||
* Function to execute before checking for the
|
||||
* clipboard content
|
||||
* @param {String|Boolean} expected
|
||||
* An expected string or validator function
|
||||
* @return a promise that resolves when the expected string has been found or
|
||||
* the validator function has returned true, rejects otherwise.
|
||||
*/
|
||||
function waitForClipboard(setup, expected) {
|
||||
let def = promise.defer();
|
||||
SimpleTest.waitForClipboard(expected, setup, def.resolve, def.reject);
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Polls a given function waiting for it to return true.
|
||||
*
|
||||
@ -577,18 +343,6 @@ function addStyle(doc, style) {
|
||||
return node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the inspector's sidebar corresponding to the given id already
|
||||
* exists
|
||||
*
|
||||
* @param {InspectorPanel}
|
||||
* @param {String}
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function hasSideBarTab(inspector, id) {
|
||||
return !!inspector.sidebar.getWindowForTab(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the dataURL for the font family tooltip.
|
||||
*
|
||||
@ -621,13 +375,6 @@ function synthesizeKeys(input, win) {
|
||||
}
|
||||
}
|
||||
|
||||
/* *********************************************
|
||||
* RULE-VIEW
|
||||
* *********************************************
|
||||
* Rule-view related test utility functions
|
||||
* This object contains functions to get rules, get properties, ...
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get the DOMNode for a css rule in the rule-view that corresponds to the given
|
||||
* selector
|
||||
@ -881,109 +628,6 @@ var setSearchFilter = Task.async(function*(view, searchValue) {
|
||||
yield view.inspector.once("ruleview-filtered");
|
||||
});
|
||||
|
||||
/* *********************************************
|
||||
* COMPUTED-VIEW
|
||||
* *********************************************
|
||||
* Computed-view related utility functions.
|
||||
* Allows to get properties, links, expand properties, ...
|
||||
*/
|
||||
|
||||
/**
|
||||
* Get references to the name and value span nodes corresponding to a given
|
||||
* property name in the computed-view
|
||||
*
|
||||
* @param {CssComputedView} view
|
||||
* The instance of the computed view panel
|
||||
* @param {String} name
|
||||
* The name of the property to retrieve
|
||||
* @return an object {nameSpan, valueSpan}
|
||||
*/
|
||||
function getComputedViewProperty(view, name) {
|
||||
let prop;
|
||||
for (let property of view.styleDocument.querySelectorAll(".property-view")) {
|
||||
let nameSpan = property.querySelector(".property-name");
|
||||
let valueSpan = property.querySelector(".property-value");
|
||||
|
||||
if (nameSpan.textContent === name) {
|
||||
prop = {nameSpan: nameSpan, valueSpan: valueSpan};
|
||||
break;
|
||||
}
|
||||
}
|
||||
return prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the text value of the property corresponding to a given name in the
|
||||
* computed-view
|
||||
*
|
||||
* @param {CssComputedView} view
|
||||
* The instance of the computed view panel
|
||||
* @param {String} name
|
||||
* The name of the property to retrieve
|
||||
* @return {String} The property value
|
||||
*/
|
||||
function getComputedViewPropertyValue(view, name, propertyName) {
|
||||
return getComputedViewProperty(view, name, propertyName)
|
||||
.valueSpan.textContent;
|
||||
}
|
||||
|
||||
/* *********************************************
|
||||
* STYLE-EDITOR
|
||||
* *********************************************
|
||||
* Style-editor related utility functions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wait for the toolbox to emit the styleeditor-selected event and when done
|
||||
* wait for the stylesheet identified by href to be loaded in the stylesheet
|
||||
* editor
|
||||
*
|
||||
* @param {Toolbox} toolbox
|
||||
* @param {String} href
|
||||
* Optional, if not provided, wait for the first editor to be ready
|
||||
* @return a promise that resolves to the editor when the stylesheet editor is
|
||||
* ready
|
||||
*/
|
||||
function waitForStyleEditor(toolbox, href) {
|
||||
let def = promise.defer();
|
||||
|
||||
info("Waiting for the toolbox to switch to the styleeditor");
|
||||
toolbox.once("styleeditor-selected").then(() => {
|
||||
let panel = toolbox.getCurrentPanel();
|
||||
ok(panel && panel.UI, "Styleeditor panel switched to front");
|
||||
|
||||
// A helper that resolves the promise once it receives an editor that
|
||||
// matches the expected href. Returns false if the editor was not correct.
|
||||
let gotEditor = (event, editor) => {
|
||||
let currentHref = editor.styleSheet.href;
|
||||
if (!href || (href && currentHref.endsWith(href))) {
|
||||
info("Stylesheet editor selected");
|
||||
panel.UI.off("editor-selected", gotEditor);
|
||||
|
||||
editor.getSourceEditor().then(sourceEditor => {
|
||||
info("Stylesheet editor fully loaded");
|
||||
def.resolve(sourceEditor);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
info("The editor was incorrect. Waiting for editor-selected event.");
|
||||
return false;
|
||||
};
|
||||
|
||||
// The expected editor may already be selected. Check the if the currently
|
||||
// selected editor is the expected one and if not wait for an
|
||||
// editor-selected event.
|
||||
if (!gotEditor("styleeditor-selected", panel.UI.selectedEditor)) {
|
||||
// The expected editor is not selected (yet). Wait for it.
|
||||
panel.UI.on("editor-selected", gotEditor);
|
||||
}
|
||||
});
|
||||
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the current page and wait for the inspector to be initialized after
|
||||
* the navigation
|
||||
|
@ -7,7 +7,7 @@ http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const TEST_URL = URL_ROOT + "doc_inspector_outerhtml.html";
|
||||
|
||||
add_task(function *() {
|
||||
add_task(function*() {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URL);
|
||||
let root = inspector.markup._elt;
|
||||
|
||||
@ -33,19 +33,12 @@ function* setSelectionNodeFront(node, inspector) {
|
||||
}
|
||||
|
||||
function* checkClipboard(expectedText, node) {
|
||||
let deferred = promise.defer();
|
||||
waitForClipboard(
|
||||
expectedText,
|
||||
() => fireCopyEvent(node),
|
||||
deferred.resolve,
|
||||
deferred.reject
|
||||
);
|
||||
|
||||
try {
|
||||
yield deferred.promise;
|
||||
yield waitForClipboard(() => fireCopyEvent(node), expectedText);
|
||||
ok(true, "Clipboard successfully filled with : " + expectedText);
|
||||
} catch (e) {
|
||||
ok(false, "Clipboard could not be filled with the expected text : " + expectedText);
|
||||
ok(false, "Clipboard could not be filled with the expected text : " +
|
||||
expectedText);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,7 @@ const COPY_ITEMS_TEST_DATA = [
|
||||
},
|
||||
];
|
||||
|
||||
add_task(function *() {
|
||||
add_task(function*() {
|
||||
let { inspector } = yield openInspectorForURL(TEST_URL);
|
||||
for (let {desc, id, selector, text} of COPY_ITEMS_TEST_DATA) {
|
||||
info("Testing " + desc);
|
||||
@ -43,9 +43,6 @@ add_task(function *() {
|
||||
let item = inspector.panelDoc.getElementById(id);
|
||||
ok(item, "The popup has a " + desc + " menu item.");
|
||||
|
||||
let deferred = promise.defer();
|
||||
waitForClipboard(text, () => item.doCommand(),
|
||||
deferred.resolve, deferred.reject);
|
||||
yield deferred.promise;
|
||||
yield waitForClipboard(() => item.doCommand(), text);
|
||||
}
|
||||
});
|
||||
|
@ -14,11 +14,6 @@ Services.scriptloader.loadSubScript(
|
||||
// Services.prefs.clearUserPref("devtools.debugger.log");
|
||||
// });
|
||||
|
||||
// Uncomment this pref to dump all devtools emitted events to the console.
|
||||
// Services.prefs.setBoolPref("devtools.dump.emit", true);
|
||||
|
||||
var ROOT_TEST_DIR = getRootDirectory(gTestPath);
|
||||
|
||||
// Import the GCLI test helper
|
||||
Services.scriptloader.loadSubScript(
|
||||
"chrome://mochitests/content/browser/devtools/client/commandline/test/helpers.js",
|
||||
@ -35,7 +30,6 @@ registerCleanupFunction(() => {
|
||||
});
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.dump.emit");
|
||||
Services.prefs.clearUserPref("devtools.inspector.activeSidebar");
|
||||
});
|
||||
|
||||
@ -165,6 +159,43 @@ function getActiveInspector() {
|
||||
return gDevTools.getToolbox(target).getPanel("inspector");
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible, and the one of the sidebar
|
||||
* tabs selected.
|
||||
* @param {String} id The ID of the sidebar tab to be opened
|
||||
* @param {String} hostType Optional hostType, as defined in Toolbox.HostType
|
||||
* @return a promise that resolves when the inspector is ready and the tab is
|
||||
* visible and ready
|
||||
*/
|
||||
var openInspectorSidebarTab = Task.async(function*(id, hostType) {
|
||||
let {toolbox, inspector} = yield openInspector();
|
||||
|
||||
if (!hasSideBarTab(inspector, id)) {
|
||||
info("Waiting for the " + id + " sidebar to be ready");
|
||||
yield inspector.sidebar.once(id + "-ready");
|
||||
}
|
||||
|
||||
info("Selecting the " + id + " sidebar");
|
||||
inspector.sidebar.select(id);
|
||||
|
||||
return {
|
||||
toolbox: toolbox,
|
||||
inspector: inspector,
|
||||
view: inspector.sidebar.getWindowForTab(id)[id]
|
||||
};
|
||||
});
|
||||
|
||||
/**
|
||||
* Checks whether the inspector's sidebar corresponding to the given id already
|
||||
* exists
|
||||
* @param {InspectorPanel}
|
||||
* @param {String}
|
||||
* @return {Boolean}
|
||||
*/
|
||||
function hasSideBarTab(inspector, id) {
|
||||
return !!inspector.sidebar.getWindowForTab(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NodeFront for a node that matches a given css selector, via the
|
||||
* protocol.
|
||||
@ -477,3 +508,71 @@ function waitForChildrenUpdated({markup}) {
|
||||
});
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for the toolbox to emit the styleeditor-selected event and when done
|
||||
* wait for the stylesheet identified by href to be loaded in the stylesheet
|
||||
* editor
|
||||
*
|
||||
* @param {Toolbox} toolbox
|
||||
* @param {String} href
|
||||
* Optional, if not provided, wait for the first editor to be ready
|
||||
* @return a promise that resolves to the editor when the stylesheet editor is
|
||||
* ready
|
||||
*/
|
||||
function waitForStyleEditor(toolbox, href) {
|
||||
let def = promise.defer();
|
||||
|
||||
info("Waiting for the toolbox to switch to the styleeditor");
|
||||
toolbox.once("styleeditor-selected").then(() => {
|
||||
let panel = toolbox.getCurrentPanel();
|
||||
ok(panel && panel.UI, "Styleeditor panel switched to front");
|
||||
|
||||
// A helper that resolves the promise once it receives an editor that
|
||||
// matches the expected href. Returns false if the editor was not correct.
|
||||
let gotEditor = (event, editor) => {
|
||||
let currentHref = editor.styleSheet.href;
|
||||
if (!href || (href && currentHref.endsWith(href))) {
|
||||
info("Stylesheet editor selected");
|
||||
panel.UI.off("editor-selected", gotEditor);
|
||||
|
||||
editor.getSourceEditor().then(sourceEditor => {
|
||||
info("Stylesheet editor fully loaded");
|
||||
def.resolve(sourceEditor);
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
info("The editor was incorrect. Waiting for editor-selected event.");
|
||||
return false;
|
||||
};
|
||||
|
||||
// The expected editor may already be selected. Check the if the currently
|
||||
// selected editor is the expected one and if not wait for an
|
||||
// editor-selected event.
|
||||
if (!gotEditor("styleeditor-selected", panel.UI.selectedEditor)) {
|
||||
// The expected editor is not selected (yet). Wait for it.
|
||||
panel.UI.on("editor-selected", gotEditor);
|
||||
}
|
||||
});
|
||||
|
||||
return def.promise;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see SimpleTest.waitForClipboard
|
||||
*
|
||||
* @param {Function} setup
|
||||
* Function to execute before checking for the
|
||||
* clipboard content
|
||||
* @param {String|Function} expected
|
||||
* An expected string or validator function
|
||||
* @return a promise that resolves when the expected string has been found or
|
||||
* the validator function has returned true, rejects otherwise.
|
||||
*/
|
||||
function waitForClipboard(setup, expected) {
|
||||
let def = promise.defer();
|
||||
SimpleTest.waitForClipboard(expected, setup, def.resolve, def.reject);
|
||||
return def.promise;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user