author | Julian Descottes <jdescottes@mozilla.com> |
Wed, 20 Apr 2016 11:40:02 +0200 | |
changeset 294091 | 1a63948d29b2920e89d0f301dea13338b293e6ef |
parent 294090 | 85616706a29b8944f3a09f5cc32e9e219f6ceb40 |
child 294092 | cd879bc4cda15611f87e784930c0f11e24bcfd3a |
push id | 30200 |
push user | kwierso@gmail.com |
push date | Thu, 21 Apr 2016 21:25:48 +0000 |
treeherder | mozilla-central@6e5771e2760a [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | gl |
bugs | 1245776 |
milestone | 48.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/devtools/client/framework/test/shared-head.js +++ b/devtools/client/framework/test/shared-head.js @@ -160,48 +160,70 @@ function synthesizeKeyFromKeyTag(key) { accelKey: !!modifiersAttr.match("accel") }; info("Synthesizing key " + name + " " + JSON.stringify(modifiers)); EventUtils.synthesizeKey(name, modifiers); } /** - * Wait for eventName on target. - * @param {Object} target An observable object that either supports on/off or - * addEventListener/removeEventListener + * 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 {Boolean} useCapture Optional, for - * addEventListener/removeEventListener + * @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 once(target, eventName, useCapture = false) { +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) { info("Got event: '" + eventName + "' on " + target + "."); - target[remove](eventName, onEvent, useCapture); - deferred.resolve.apply(deferred, 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); +} + +/** * Some tests may need to import one or more of the test helper scripts. * A test helper script is simply a js file that contains common test code that * is either not common-enough to be in head.js, or that is located in a * separate directory. * The script will be loaded synchronously and in the test's scope. * @param {String} filePath The file path, relative to the current directory. * Examples: * - "helper_attributes_test_runner.js" @@ -218,16 +240,30 @@ function loadHelperScript(filePath) { */ function waitForTick() { let deferred = promise.defer(); executeSoon(deferred.resolve); return deferred.promise; } /** + * 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; +} + +/** * Open the toolbox in a given tab. * @param {XULNode} tab The tab the toolbox should be opened in. * @param {String} toolId Optional. The ID of the tool to be selected. * @param {String} hostType Optional. The type of toolbox host to be used. * @return {Promise} Resolves with the toolbox, when it has been opened. */ var openToolboxForTab = Task.async(function* (tab, toolId, hostType) { info("Opening the toolbox");
--- a/devtools/client/inspector/computed/test/head.js +++ b/devtools/client/inspector/computed/test/head.js @@ -24,67 +24,25 @@ function openComputedView() { toolbox, inspector, view: inspector.computedview.view }; }); } /** - * 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); -} - -/** - * Listen for a new tab to open and return a promise that resolves when one - * does and completes the load event. - * - * @return a promise that resolves to the tab object - */ -var waitForTab = Task.async(function*() { - info("Waiting for a tab to open"); - yield once(gBrowser.tabContainer, "TabOpen"); - let tab = gBrowser.selectedTab; - let browser = tab.linkedBrowser; - yield once(browser, "load", true); - info("The tab load completed"); - return tab; -}); - -/** * Dispatch the copy event on the given element */ function fireCopyEvent(element) { let evt = element.ownerDocument.createEvent("Event"); evt.initEvent("copy", true, true); element.dispatchEvent(evt); } /** - * Simulate the key input for the given input in the window. - * - * @param {String} input - * The string value to input - * @param {Window} win - * The window containing the panel - */ -function synthesizeKeys(input, win) { - for (let key of input.split("")) { - EventUtils.synthesizeKey(key, {}, win); - } -} - -/** * 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}
--- a/devtools/client/inspector/rules/test/head.js +++ b/devtools/client/inspector/rules/test/head.js @@ -55,68 +55,16 @@ function openRuleView() { inspector: data.inspector, testActor: data.testActor, view: data.inspector.ruleview.view }; }); } /** - * Set the inspector's current selection to null so that no node is selected - * - * @param {InspectorPanel} inspector - * The instance of InspectorPanel currently loaded in the toolbox - * @return a promise that resolves when the inspector is updated - */ -function clearCurrentNodeSelection(inspector) { - info("Clearing the current selection"); - let updated = inspector.once("inspector-updated"); - inspector.selection.setNodeFront(null); - return updated; -} - -/** - * 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 a content -> chrome message on the message manager (the window * messagemanager is used). * * @param {String} name * The message name * @return {Promise} A promise that resolves to the response data when the * message has been received */ @@ -280,32 +228,16 @@ function assertHoverTooltipOn(tooltip, e */ function* hideTooltipAndWaitForRuleViewChanged(tooltip, view) { let onModified = view.once("ruleview-changed"); tooltip.hide(); yield onModified; } /** - * Listen for a new tab to open and return a promise that resolves when one - * does and completes the load event. - * - * @return a promise that resolves to the tab object - */ -var waitForTab = Task.async(function* () { - info("Waiting for a tab to open"); - yield once(gBrowser.tabContainer, "TabOpen"); - let tab = gBrowser.selectedTab; - let browser = tab.linkedBrowser; - yield once(browser, "load", true); - info("The tab load completed"); - return tab; -}); - -/** * Polls a given generator function waiting for it to return true. * * @param {Function} validatorFn * A validator generator function that returns a boolean. * This is called every few milliseconds to check if the result is true. * When it is true, the promise resolves. * @param {String} name * Optional name of the test. This is used to generate @@ -344,30 +276,16 @@ var getFontFamilyDataURL = Task.async(fu "black" : "white"; let {data} = yield nodeFront.getFontFamilyDataURL(font, fillStyle); let dataURL = yield data.string(); return dataURL; }); /** - * Simulate the key input for the given input in the window. - * - * @param {String} input - * The string value to input - * @param {Window} win - * The window containing the panel - */ -function synthesizeKeys(input, win) { - for (let key of input.split("")) { - EventUtils.synthesizeKey(key, {}, win); - } -} - -/** * Get the DOMNode for a css rule in the rule-view that corresponds to the given * selector * * @param {CssRuleView} view * The instance of the rule-view panel * @param {String} selectorText * The selector in the rule-view for which the rule * object is wanted
--- a/devtools/client/inspector/shared/test/browser.ini +++ b/devtools/client/inspector/shared/test/browser.ini @@ -7,21 +7,27 @@ support-files = doc_content_stylesheet.xul doc_content_stylesheet_imported.css doc_content_stylesheet_imported2.css doc_content_stylesheet_linked.css doc_content_stylesheet_script.css doc_content_stylesheet_xul.css doc_frame_script.js head.js + !/devtools/client/commandline/test/helpers.js + !/devtools/client/inspector/test/head.js + !/devtools/client/framework/test/shared-head.js + !/devtools/client/shared/test/test-actor.js + !/devtools/client/shared/test/test-actor-registry.js [browser_styleinspector_context-menu-copy-color_01.js] [browser_styleinspector_context-menu-copy-color_02.js] [browser_styleinspector_context-menu-copy-urls.js] [browser_styleinspector_csslogic-content-stylesheets.js] +skip-if = e10s && debug # Bug 1250058 (docshell leak when opening 2 toolboxes) [browser_styleinspector_output-parser.js] [browser_styleinspector_refresh_when_active.js] [browser_styleinspector_tooltip-background-image.js] [browser_styleinspector_tooltip-closes-on-new-selection.js] skip-if = e10s # Bug 1111546 (e10s) [browser_styleinspector_tooltip-longhand-fontfamily.js] [browser_styleinspector_tooltip-multiple-background-images.js] [browser_styleinspector_tooltip-shorthand-fontfamily.js]
--- a/devtools/client/inspector/shared/test/head.js +++ b/devtools/client/inspector/shared/test/head.js @@ -1,58 +1,35 @@ /* 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/ */ +/* import-globals-from ../../test/head.js */ "use strict"; -var Cu = Components.utils; -var {require} = Cu.import("resource://devtools/shared/Loader.jsm", {}); -var {gDevTools} = require("devtools/client/framework/devtools"); -var {TargetFactory} = require("devtools/client/framework/target"); -var {CssRuleView, _ElementStyle} = require("devtools/client/inspector/rules/rules"); +// 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); + +var {CssRuleView} = 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} = +var {getInplaceEditorForSpan: inplaceEditor} = require("devtools/client/shared/inplace-editor"); -var {console} = Cu.import("resource://gre/modules/Console.jsm", {}); - -// All tests are asynchronous -waitForExplicitFinish(); const TEST_URL_ROOT = "http://example.com/browser/devtools/client/inspector/shared/test/"; const TEST_URL_ROOT_SSL = "https://example.com/browser/devtools/client/inspector/shared/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). * @@ -87,108 +64,31 @@ registerCleanupFunction(() => { * 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 + * 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. */ -function getNode(nodeOrSelector) { - info("Getting the node for '" + nodeOrSelector + "'"); - return typeof nodeOrSelector === "string" ? - content.document.querySelector(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 - * - * @param {InspectorPanel} inspector - * The instance of InspectorPanel currently loaded in the toolbox - * @return a promise that resolves when the inspector is updated - */ -function clearCurrentNodeSelection(inspector) { - info("Clearing the current selection"); - let updated = inspector.once("inspector-updated"); - inspector.selection.setNodeFront(null); - return updated; -} +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; + }); +}; /** * 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"); @@ -279,83 +179,16 @@ function openComputedView() { * @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. - * - * @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; -} - -/** * Wait for a content -> chrome message on the message manager (the window * messagemanager is used). * * @param {String} name * The message name * @return {Promise} A promise that resolves to the response data when the * message has been received */ @@ -488,49 +321,16 @@ function assertHoverTooltipOn(tooltip, e return isHoverTooltipTarget(tooltip, element).then(() => { ok(true, "A tooltip is defined on hover of the given element"); }, () => { ok(false, "No tooltip is defined on hover of the given element"); }); } /** - * Listen for a new tab to open and return a promise that resolves when one - * does and completes the load event. - * - * @return a promise that resolves to the tab object - */ -var waitForTab = Task.async(function*() { - info("Waiting for a tab to open"); - yield once(gBrowser.tabContainer, "TabOpen"); - let tab = gBrowser.selectedTab; - let browser = tab.linkedBrowser; - yield once(browser, "load", true); - info("The tab load completed"); - 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. * * @param {Function} validatorFn * A validator function that returns a boolean. * This is called every few milliseconds to check if the result is true. * When it is true, the promise resolves. * @param {String} name * Optional name of the test. This is used to generate @@ -550,46 +350,16 @@ function waitForSuccess(validatorFn, nam } } wait(validatorFn); return def.promise; } /** - * Create a new style tag containing the given style text and append it to the - * document's head node - * - * @param {Document} doc - * @param {String} style - * @return {DOMNode} The newly created style node - */ -function addStyle(doc, style) { - info("Adding a new style tag to the document with style content: " + - style.substring(0, 50)); - let node = doc.createElement("style"); - node.setAttribute("type", "text/css"); - node.textContent = style; - doc.getElementsByTagName("head")[0].appendChild(node); - 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. * * @param {String} font * The font family value. * @param {object} nodeFront * The NodeActor that will used to retrieve the dataURL for the * font family tooltip contents. */ @@ -597,30 +367,16 @@ var getFontFamilyDataURL = Task.async(fu let fillStyle = (Services.prefs.getCharPref("devtools.theme") === "light") ? "black" : "white"; let {data} = yield nodeFront.getFontFamilyDataURL(font, fillStyle); let dataURL = yield data.string(); return dataURL; }); -/** - * Simulate the key input for the given input in the window. - * - * @param {String} input - * The string value to input - * @param {Window} win - * The window containing the panel - */ -function synthesizeKeys(input, win) { - for (let key of input.split("")) { - EventUtils.synthesizeKey(key, {}, win); - } -} - /* ********************************************* * RULE-VIEW * ********************************************* * Rule-view related test utility functions * This object contains functions to get rules, get properties, ... */ /** @@ -916,82 +672,8 @@ function getComputedViewProperty(view, n * @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 - * - * @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(); - }); -}
--- a/devtools/client/inspector/test/head.js +++ b/devtools/client/inspector/test/head.js @@ -133,16 +133,30 @@ var selectNode = Task.async(function*(se info("Selecting the node for '" + selector + "'"); let nodeFront = yield getNodeFront(selector, 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 + * + * @param {InspectorPanel} inspector + * The instance of InspectorPanel currently loaded in the toolbox + * @return a promise that resolves when the inspector is updated + */ +function clearCurrentNodeSelection(inspector) { + info("Clearing the current selection"); + let updated = inspector.once("inspector-updated"); + inspector.selection.setNodeFront(null); + return updated; +} + +/** * Open the inspector in a tab with given URL. * @param {string} url The URL to open. * @param {String} hostType Optional hostType, as defined in Toolbox.HostType * @return A promise that is resolved once the tab and inspector have loaded * with an object: { tab, toolbox, inspector }. */ var openInspectorForURL = Task.async(function*(url, hostType) { let tab = yield addTab(url); @@ -667,8 +681,38 @@ function containsFocus(doc, container) { while (elm) { if (elm === container) { return true; } elm = elm.parentNode; } return false; } + +/** + * Listen for a new tab to open and return a promise that resolves when one + * does and completes the load event. + * + * @return a promise that resolves to the tab object + */ +var waitForTab = Task.async(function*() { + info("Waiting for a tab to open"); + yield once(gBrowser.tabContainer, "TabOpen"); + let tab = gBrowser.selectedTab; + let browser = tab.linkedBrowser; + yield once(browser, "load", true); + info("The tab load completed"); + return tab; +}); + +/** + * Simulate the key input for the given input in the window. + * + * @param {String} input + * The string value to input + * @param {Window} win + * The window containing the panel + */ +function synthesizeKeys(input, win) { + for (let key of input.split("")) { + EventUtils.synthesizeKey(key, {}, win); + } +}