303 lines
9.4 KiB
JavaScript
303 lines
9.4 KiB
JavaScript
/* Any copyright is dedicated to the Public Domain.
|
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
|
|
|
"use strict";
|
|
|
|
let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
|
|
// shared-head.js handles imports, constants, and utility functions
|
|
let sharedHeadURI = testDir + "../../../framework/test/shared-head.js";
|
|
Services.scriptloader.loadSubScript(sharedHeadURI, this);
|
|
|
|
// Import the GCLI test helper
|
|
let gcliHelpersURI = testDir + "../../../commandline/test/helpers.js";
|
|
Services.scriptloader.loadSubScript(gcliHelpersURI, this);
|
|
|
|
flags.testing = true;
|
|
Services.prefs.setBoolPref("devtools.responsive.html.enabled", false);
|
|
|
|
registerCleanupFunction(() => {
|
|
flags.testing = false;
|
|
Services.prefs.clearUserPref("devtools.responsive.html.enabled");
|
|
Services.prefs.clearUserPref("devtools.responsiveUI.currentPreset");
|
|
Services.prefs.clearUserPref("devtools.responsiveUI.customHeight");
|
|
Services.prefs.clearUserPref("devtools.responsiveUI.customWidth");
|
|
Services.prefs.clearUserPref("devtools.responsiveUI.presets");
|
|
Services.prefs.clearUserPref("devtools.responsiveUI.rotate");
|
|
});
|
|
|
|
SimpleTest.requestCompleteLog();
|
|
|
|
const { ResponsiveUIManager } = Cu.import("resource://devtools/client/responsivedesign/responsivedesign.jsm", {});
|
|
|
|
/**
|
|
* Open the Responsive Design Mode
|
|
* @param {Tab} The browser tab to open it into (defaults to the selected tab).
|
|
* @param {method} The method to use to open the RDM (values: menu, keyboard)
|
|
* @return {rdm, manager} Returns the RUI instance and the manager
|
|
*/
|
|
var openRDM = Task.async(function* (tab = gBrowser.selectedTab,
|
|
method = "menu") {
|
|
let manager = ResponsiveUIManager;
|
|
|
|
let opened = once(manager, "on");
|
|
let resized = once(manager, "content-resize");
|
|
if (method == "menu") {
|
|
document.getElementById("menu_responsiveUI").doCommand();
|
|
} else {
|
|
synthesizeKeyFromKeyTag(document.getElementById("key_responsiveUI"));
|
|
}
|
|
yield opened;
|
|
|
|
let rdm = manager.getResponsiveUIForTab(tab);
|
|
rdm.transitionsEnabled = false;
|
|
registerCleanupFunction(() => {
|
|
rdm.transitionsEnabled = true;
|
|
});
|
|
|
|
// Wait for content to resize. This is triggered async by the preset menu
|
|
// auto-selecting its default entry once it's in the document.
|
|
yield resized;
|
|
|
|
return {rdm, manager};
|
|
});
|
|
|
|
/**
|
|
* Close a responsive mode instance
|
|
* @param {rdm} ResponsiveUI instance for the tab
|
|
*/
|
|
var closeRDM = Task.async(function* (rdm) {
|
|
let manager = ResponsiveUIManager;
|
|
if (!rdm) {
|
|
rdm = manager.getResponsiveUIForTab(gBrowser.selectedTab);
|
|
}
|
|
let closed = once(manager, "off");
|
|
let resized = once(manager, "content-resize");
|
|
rdm.close();
|
|
yield resized;
|
|
yield closed;
|
|
});
|
|
|
|
/**
|
|
* 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");
|
|
if (inspector._updateProgress) {
|
|
yield inspector.once("inspector-updated");
|
|
}
|
|
|
|
return {
|
|
toolbox: toolbox,
|
|
inspector: inspector
|
|
};
|
|
});
|
|
|
|
var closeToolbox = Task.async(function* () {
|
|
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
|
yield gDevTools.closeToolbox(target);
|
|
});
|
|
|
|
/**
|
|
* 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();
|
|
waitForFocus(def.resolve, toolbox.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();
|
|
|
|
info("Selecting the " + id + " sidebar");
|
|
inspector.sidebar.select(id);
|
|
|
|
return {
|
|
toolbox: toolbox,
|
|
inspector: inspector,
|
|
view: inspector[id].view || inspector[id].computedView
|
|
};
|
|
});
|
|
|
|
/**
|
|
* 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 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");
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
*/
|
|
var addTab = Task.async(function* (url) {
|
|
info("Adding a new tab with URL: '" + url + "'");
|
|
|
|
window.focus();
|
|
|
|
let tab = gBrowser.selectedTab = gBrowser.addTab(url);
|
|
let browser = tab.linkedBrowser;
|
|
|
|
yield BrowserTestUtils.browserLoaded(browser);
|
|
info("URL '" + url + "' loading complete");
|
|
|
|
return tab;
|
|
});
|
|
|
|
/**
|
|
* Waits for the next load to complete in the current browser.
|
|
*
|
|
* @return promise
|
|
*/
|
|
function waitForDocLoadComplete(aBrowser = gBrowser) {
|
|
let deferred = promise.defer();
|
|
let progressListener = {
|
|
onStateChange: function (webProgress, req, flags, status) {
|
|
let docStop = Ci.nsIWebProgressListener.STATE_IS_NETWORK |
|
|
Ci.nsIWebProgressListener.STATE_STOP;
|
|
info(`Saw state ${flags.toString(16)} and status ${status.toString(16)}`);
|
|
|
|
// When a load needs to be retargetted to a new process it is cancelled
|
|
// with NS_BINDING_ABORTED so ignore that case
|
|
if ((flags & docStop) == docStop && status != Cr.NS_BINDING_ABORTED) {
|
|
aBrowser.removeProgressListener(progressListener);
|
|
info("Browser loaded");
|
|
deferred.resolve();
|
|
}
|
|
},
|
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
|
|
Ci.nsISupportsWeakReference])
|
|
};
|
|
aBrowser.addProgressListener(progressListener);
|
|
info("Waiting for browser load");
|
|
return deferred.promise;
|
|
}
|
|
|
|
/**
|
|
* Get the NodeFront for a node that matches a given css selector, via the
|
|
* protocol.
|
|
* @param {String|NodeFront} selector
|
|
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
|
|
* loaded in the toolbox
|
|
* @return {Promise} Resolves to the NodeFront instance
|
|
*/
|
|
function getNodeFront(selector, {walker}) {
|
|
if (selector._form) {
|
|
return selector;
|
|
}
|
|
return walker.querySelector(walker.rootNode, selector);
|
|
}
|
|
|
|
/**
|
|
* Set the inspector's current selection to the first match of the given css
|
|
* selector
|
|
* @param {String|NodeFront} selector
|
|
* @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* (selector, inspector, reason = "test") {
|
|
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;
|
|
});
|
|
|
|
function waitForResizeTo(manager, width, height) {
|
|
return new Promise(resolve => {
|
|
let onResize = (_, data) => {
|
|
if (data.width != width || data.height != height) {
|
|
return;
|
|
}
|
|
manager.off("content-resize", onResize);
|
|
info(`Got content-resize to ${width} x ${height}`);
|
|
resolve();
|
|
};
|
|
info(`Waiting for content-resize to ${width} x ${height}`);
|
|
manager.on("content-resize", onResize);
|
|
});
|
|
}
|
|
|
|
var setPresetIndex = Task.async(function* (rdm, manager, index) {
|
|
info(`Current preset: ${rdm.menulist.selectedIndex}, change to: ${index}`);
|
|
if (rdm.menulist.selectedIndex != index) {
|
|
let resized = once(manager, "content-resize");
|
|
rdm.menulist.selectedIndex = index;
|
|
yield resized;
|
|
}
|
|
});
|
|
|
|
var setSize = Task.async(function* (rdm, manager, width, height) {
|
|
let size = rdm.getSize();
|
|
info(`Current size: ${size.width} x ${size.height}, ` +
|
|
`set to: ${width} x ${height}`);
|
|
if (size.width != width || size.height != height) {
|
|
let resized = waitForResizeTo(manager, width, height);
|
|
rdm.setViewportSize({ width, height });
|
|
yield resized;
|
|
}
|
|
});
|