зеркало из https://github.com/mozilla/gecko-dev.git
Bug 825410 - intermittent browser_inspector_pseudoclass_lock.js test failures; r=bgrins
This commit is contained in:
Родитель
a64f3ea049
Коммит
b05a01e60c
|
@ -36,14 +36,12 @@ function test()
|
|||
|
||||
// Make sure the body element is selected initially.
|
||||
node = doc.querySelector("body");
|
||||
inspector.once("inspector-updated", () => {
|
||||
is(inspector.selection.node, node, "Body should be selected initially.");
|
||||
node = doc.querySelector("h1")
|
||||
inspector.once("inspector-updated", highlightHeaderNode);
|
||||
let bc = inspector.breadcrumbs;
|
||||
bc.nodeHierarchy[bc.currentIndex].button.focus();
|
||||
EventUtils.synthesizeKey("VK_RIGHT", { });
|
||||
});
|
||||
is(inspector.selection.node, node, "Body should be selected initially.");
|
||||
node = doc.querySelector("h1")
|
||||
inspector.once("inspector-updated", highlightHeaderNode);
|
||||
let bc = inspector.breadcrumbs;
|
||||
bc.nodeHierarchy[bc.currentIndex].button.focus();
|
||||
EventUtils.synthesizeKey("VK_RIGHT", {});
|
||||
}
|
||||
|
||||
function highlightHeaderNode()
|
||||
|
|
|
@ -25,7 +25,7 @@ function test() {
|
|||
openInspector((aInspector, aToolbox) => {
|
||||
inspector = aInspector;
|
||||
markupView = inspector.markup;
|
||||
inspector.once("inspector-updated", startTests);
|
||||
startTests();
|
||||
});
|
||||
}, content);
|
||||
}, true);
|
||||
|
|
|
@ -35,9 +35,7 @@ function createDocument() {
|
|||
// Open the inspector, start the picker mode, and start the tests
|
||||
openInspector(aInspector => {
|
||||
inspector = aInspector;
|
||||
inspector.once("inspector-updated", () => {
|
||||
inspector.toolbox.highlighterUtils.startPicker().then(runTests);
|
||||
});
|
||||
inspector.toolbox.highlighterUtils.startPicker().then(runTests);
|
||||
});
|
||||
}, false);
|
||||
|
||||
|
|
|
@ -13,9 +13,7 @@ function test() {
|
|||
|
||||
openInspector(aInspector => {
|
||||
inspector = aInspector;
|
||||
inspector.once("inspector-updated", () => {
|
||||
inspector.toolbox.highlighter.showBoxModel(getNodeFront(div)).then(runTest);
|
||||
});
|
||||
inspector.toolbox.highlighter.showBoxModel(getNodeFront(div)).then(runTest);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1,189 +1,142 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that locking the pseudoclass displays correctly in the ruleview
|
||||
|
||||
let DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils);
|
||||
const PSEUDO = ":hover";
|
||||
const TEST_URL = 'data:text/html,' +
|
||||
'<head>' +
|
||||
' <style>div {color:red;} div:hover {color:blue;}</style>' +
|
||||
'</head>' +
|
||||
'<body>' +
|
||||
' <div id="parent-div">' +
|
||||
' <div id="div-1">test div</div>' +
|
||||
' <div id="div-2">test div2</div>' +
|
||||
' </div>' +
|
||||
'</body>';
|
||||
|
||||
let doc;
|
||||
let parentDiv, div, div2;
|
||||
let inspector;
|
||||
let ruleview;
|
||||
waitForExplicitFinish();
|
||||
|
||||
let pseudo = ":hover";
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
function test() {
|
||||
ignoreAllUncaughtExceptions();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(createDocument, content);
|
||||
waitForFocus(startTests, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,pseudo-class lock tests";
|
||||
content.location = TEST_URL;
|
||||
}
|
||||
|
||||
function createDocument()
|
||||
{
|
||||
parentDiv = doc.createElement("div");
|
||||
parentDiv.textContent = "parent div";
|
||||
let startTests = Task.async(function*() {
|
||||
let {toolbox, inspector, view} = yield openRuleView();
|
||||
yield selectNode("#div-1", inspector);
|
||||
|
||||
div = doc.createElement("div");
|
||||
div.textContent = "test div";
|
||||
yield performTests(inspector, view);
|
||||
|
||||
div2 = doc.createElement("div");
|
||||
div2.textContent = "test div2";
|
||||
yield finishUp(toolbox);
|
||||
finish();
|
||||
});
|
||||
|
||||
let head = doc.getElementsByTagName('head')[0];
|
||||
let style = doc.createElement('style');
|
||||
let rules = doc.createTextNode('div { color: red; } div:hover { color: blue; }');
|
||||
function* performTests(inspector, ruleview) {
|
||||
yield togglePseudoClass(inspector);
|
||||
yield testAdded(inspector, ruleview);
|
||||
|
||||
style.appendChild(rules);
|
||||
head.appendChild(style);
|
||||
parentDiv.appendChild(div);
|
||||
parentDiv.appendChild(div2);
|
||||
doc.body.appendChild(parentDiv);
|
||||
yield togglePseudoClass(inspector);
|
||||
yield testRemoved();
|
||||
yield testRemovedFromUI(inspector, ruleview);
|
||||
|
||||
openInspector(selectNode);
|
||||
yield togglePseudoClass(inspector);
|
||||
yield testNavigate(inspector, ruleview);
|
||||
}
|
||||
|
||||
function selectNode(aInspector)
|
||||
{
|
||||
inspector = aInspector;
|
||||
function* togglePseudoClass(inspector) {
|
||||
info("Toggle the pseudoclass, wait for the pseudoclass event and wait for the refresh of the rule view");
|
||||
|
||||
waitForView("ruleview", () => {
|
||||
ruleview = inspector.sidebar.getWindowForTab("ruleview").ruleview.view;
|
||||
inspector.sidebar.select("ruleview");
|
||||
inspector.selection.setNode(div, "test");
|
||||
inspector.once("inspector-updated", performTests);
|
||||
});
|
||||
let onPseudo = inspector.selection.once("pseudoclass");
|
||||
let onRefresh = inspector.once("rule-view-refreshed");
|
||||
inspector.togglePseudoClass(PSEUDO);
|
||||
|
||||
yield onPseudo;
|
||||
yield onRefresh;
|
||||
}
|
||||
|
||||
function performTests()
|
||||
{
|
||||
// toggle the class
|
||||
inspector.togglePseudoClass(pseudo);
|
||||
function* testNavigate(inspector, ruleview) {
|
||||
yield selectNode("#parent-div", inspector);
|
||||
|
||||
// Wait for the "pseudoclass" event so we know the
|
||||
// inspector has been told of the pseudoclass lock change.
|
||||
inspector.selection.once("pseudoclass", () => {
|
||||
inspector.once("rule-view-refreshed", () => {
|
||||
testAdded(() => {
|
||||
// Change the pseudo class and give the rule view time to update.
|
||||
inspector.togglePseudoClass(pseudo);
|
||||
inspector.selection.once("pseudoclass", () => {
|
||||
inspector.once("rule-view-refreshed", () => {
|
||||
testRemoved();
|
||||
testRemovedFromUI(() => {
|
||||
// toggle it back on
|
||||
inspector.togglePseudoClass(pseudo);
|
||||
inspector.selection.once("pseudoclass", () => {
|
||||
inspector.once("rule-view-refreshed", () => {
|
||||
testNavigate(() => {
|
||||
// close the inspector
|
||||
finishUp();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
info("Make sure the pseudoclass is still on after navigating to a parent");
|
||||
is(DOMUtils.hasPseudoClassLock(getNode("#div-1"), PSEUDO), true,
|
||||
"pseudo-class lock is still applied after inspecting ancestor");
|
||||
|
||||
let onPseudo = inspector.selection.once("pseudoclass");
|
||||
yield selectNode("#div-2", inspector);
|
||||
yield onPseudo;
|
||||
|
||||
info("Make sure the pseudoclass is removed after navigating to a non-hierarchy node");
|
||||
is(DOMUtils.hasPseudoClassLock(getNode("#div-1"), PSEUDO), false,
|
||||
"pseudo-class lock is removed after inspecting sibling node");
|
||||
|
||||
yield selectNode("#div-1", inspector);
|
||||
yield togglePseudoClass(inspector);
|
||||
yield inspector.once("computed-view-refreshed");
|
||||
}
|
||||
|
||||
function testNavigate(callback)
|
||||
{
|
||||
inspector.selection.setNode(parentDiv, "test");
|
||||
inspector.once("inspector-updated", () => {
|
||||
|
||||
// make sure it's still on after naving to parent
|
||||
is(DOMUtils.hasPseudoClassLock(div, pseudo), true,
|
||||
"pseudo-class lock is still applied after inspecting ancestor");
|
||||
|
||||
inspector.selection.setNode(div2, "test");
|
||||
inspector.selection.once("pseudoclass", () => {
|
||||
// make sure it's removed after naving to a non-hierarchy node
|
||||
is(DOMUtils.hasPseudoClassLock(div, pseudo), false,
|
||||
"pseudo-class lock is removed after inspecting sibling node");
|
||||
|
||||
// toggle it back on
|
||||
inspector.selection.setNode(div, "test");
|
||||
inspector.once("inspector-updated", () => {
|
||||
inspector.togglePseudoClass(pseudo);
|
||||
inspector.once("computed-view-refreshed", callback);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function showPickerOn(node, cb)
|
||||
{
|
||||
function showPickerOn(node, inspector) {
|
||||
let highlighter = inspector.toolbox.highlighter;
|
||||
highlighter.showBoxModel(getNodeFront(node)).then(cb);
|
||||
return highlighter.showBoxModel(getNodeFront(node));
|
||||
}
|
||||
|
||||
function testAdded(cb)
|
||||
{
|
||||
// lock is applied to it and ancestors
|
||||
let node = div;
|
||||
function* testAdded(inspector, ruleview) {
|
||||
info("Make sure the pseudoclass lock is applied to #div-1 and its ancestors");
|
||||
let node = getNode("#div-1");
|
||||
do {
|
||||
is(DOMUtils.hasPseudoClassLock(node, pseudo), true,
|
||||
is(DOMUtils.hasPseudoClassLock(node, PSEUDO), true,
|
||||
"pseudo-class lock has been applied");
|
||||
node = node.parentNode;
|
||||
} while (node.parentNode)
|
||||
|
||||
// ruleview contains pseudo-class rule
|
||||
info("Check that the ruleview contains the pseudo-class rule");
|
||||
let rules = ruleview.element.querySelectorAll(".ruleview-rule.theme-separator");
|
||||
is(rules.length, 3, "rule view is showing 3 rules for pseudo-class locked div");
|
||||
is(rules[1]._ruleEditor.rule.selectorText, "div:hover", "rule view is showing " + pseudo + " rule");
|
||||
is(rules[1]._ruleEditor.rule.selectorText, "div:hover", "rule view is showing " + PSEUDO + " rule");
|
||||
|
||||
// Show the highlighter by starting the pick mode and hovering over the div
|
||||
showPickerOn(div, () => {
|
||||
// infobar selector contains pseudo-class
|
||||
let pseudoClassesBox = getHighlighter().querySelector(".highlighter-nodeinfobar-pseudo-classes");
|
||||
is(pseudoClassesBox.textContent, pseudo, "pseudo-class in infobar selector");
|
||||
inspector.toolbox.highlighter.hideBoxModel().then(cb);
|
||||
});
|
||||
info("Show the highlighter on #div-1");
|
||||
yield showPickerOn(getNode("#div-1"), inspector);
|
||||
|
||||
info("Check that the infobar selector contains the pseudo-class");
|
||||
let pseudoClassesBox = getHighlighter().querySelector(".highlighter-nodeinfobar-pseudo-classes");
|
||||
is(pseudoClassesBox.textContent, PSEUDO, "pseudo-class in infobar selector");
|
||||
yield inspector.toolbox.highlighter.hideBoxModel();
|
||||
}
|
||||
|
||||
function testRemoved()
|
||||
{
|
||||
// lock removed from node and ancestors
|
||||
let node = div;
|
||||
function* testRemoved() {
|
||||
info("Make sure the pseudoclass lock is removed from #div-1 and its ancestors");
|
||||
let node = getNode("#div-1");
|
||||
do {
|
||||
is(DOMUtils.hasPseudoClassLock(node, pseudo), false,
|
||||
is(DOMUtils.hasPseudoClassLock(node, PSEUDO), false,
|
||||
"pseudo-class lock has been removed");
|
||||
node = node.parentNode;
|
||||
} while (node.parentNode)
|
||||
}
|
||||
|
||||
function testRemovedFromUI(cb)
|
||||
{
|
||||
// ruleview no longer contains pseudo-class rule
|
||||
function* testRemovedFromUI(inspector, ruleview) {
|
||||
info("Check that the ruleview no longer contains the pseudo-class rule");
|
||||
let rules = ruleview.element.querySelectorAll(".ruleview-rule.theme-separator");
|
||||
is(rules.length, 2, "rule view is showing 2 rules after removing lock");
|
||||
|
||||
showPickerOn(div, () => {
|
||||
let pseudoClassesBox = getHighlighter().querySelector(".highlighter-nodeinfobar-pseudo-classes");
|
||||
is(pseudoClassesBox.textContent, "", "pseudo-class removed from infobar selector");
|
||||
inspector.toolbox.highlighter.hideBoxModel().then(cb);
|
||||
});
|
||||
yield showPickerOn(getNode("#div-1"), inspector);
|
||||
|
||||
let pseudoClassesBox = getHighlighter().querySelector(".highlighter-nodeinfobar-pseudo-classes");
|
||||
is(pseudoClassesBox.textContent, "", "pseudo-class removed from infobar selector");
|
||||
yield inspector.toolbox.highlighter.hideBoxModel();
|
||||
}
|
||||
|
||||
function finishUp()
|
||||
{
|
||||
gDevTools.once("toolbox-destroyed", function() {
|
||||
testRemoved();
|
||||
inspector = ruleview = null;
|
||||
doc = div = null;
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
});
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
function* finishUp(toolbox) {
|
||||
let onDestroy = gDevTools.once("toolbox-destroyed");
|
||||
toolbox.destroy();
|
||||
yield onDestroy;
|
||||
|
||||
yield testRemoved(getNode("#div-1"));
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
||||
|
|
|
@ -41,12 +41,152 @@ SimpleTest.registerCleanupFunction(() => {
|
|||
Services.prefs.clearUserPref("devtools.inspector.activeSidebar");
|
||||
});
|
||||
|
||||
function openInspector(callback)
|
||||
{
|
||||
/**
|
||||
* 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}
|
||||
*/
|
||||
function getNode(nodeOrSelector) {
|
||||
return typeof nodeOrSelector === "string" ?
|
||||
content.document.querySelector(nodeOrSelector) :
|
||||
nodeOrSelector;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the inspector's current selection to a node or to the first match of the
|
||||
* given css 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
|
||||
* @param {String} reason Defaults to "test" which instructs the inspector not to highlight the node upon selection
|
||||
* @return a promise that resolves when the inspector is updated with the new
|
||||
* node
|
||||
*/
|
||||
function selectNode(nodeOrSelector, inspector, reason="test") {
|
||||
info("Selecting the node " + nodeOrSelector);
|
||||
let node = getNode(nodeOrSelector);
|
||||
let updated = inspector.once("inspector-updated");
|
||||
inspector.selection.setNode(node, reason);
|
||||
return updated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the toolbox, with the inspector tool visible.
|
||||
* @param {Function} cb Optional callback, if you don't want to use the returned
|
||||
* promise
|
||||
* @return a promise that resolves when the inspector is ready
|
||||
*/
|
||||
let openInspector = Task.async(function*(cb) {
|
||||
info("Opening the inspector");
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
gDevTools.showToolbox(target, "inspector").then(function(toolbox) {
|
||||
callback(toolbox.getCurrentPanel(), toolbox);
|
||||
}).then(null, console.error);
|
||||
|
||||
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");
|
||||
if (cb) {
|
||||
return cb(inspector, toolbox);
|
||||
} else {
|
||||
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");
|
||||
|
||||
if (cb) {
|
||||
return cb(inspector, toolbox);
|
||||
} else {
|
||||
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
|
||||
*/
|
||||
let 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");
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
function getActiveInspector()
|
||||
|
|
Загрузка…
Ссылка в новой задаче