Bug 1030735 - Enable devtools/styleinspector test with e10s. r=jwalker

This commit is contained in:
Patrick Brosset 2014-08-18 01:19:00 -04:00
parent 485af060ec
commit caffbeac8a
38 changed files with 488 additions and 274 deletions

View File

@ -31,6 +31,7 @@ support-files =
[browser_graphs-12.js]
[browser_graphs-13.js]
[browser_graphs-14.js]
[browser_inplace-editor.js]
[browser_layoutHelpers.js]
[browser_layoutHelpers-getBoxQuads.js]
[browser_num-l10n.js]

View File

@ -1,18 +1,23 @@
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
// Test the inplace-editor behavior.
// This test doesn't open the devtools, it just exercises the inplace-editor
// on test elements in the page
let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
let {editableField, getInplaceEditorForSpan: inplaceEditor} = devtools.require("devtools/shared/inplace-editor");
// Test the inplace-editor behavior.
let test = Task.async(function*() {
yield promiseTab("data:text/html;charset=utf-8,inline editor tests");
let test = asyncTest(function*() {
yield addTab("data:text/html;charset=utf-8,inline editor tests");
yield testReturnCommit();
yield testBlurCommit();
yield testAdvanceCharCommit();
gBrowser.removeCurrentTab();
finish();
});
function testReturnCommit() {

View File

@ -286,8 +286,7 @@ CssHtmlTree.prototype = {
/**
* Update the highlighted element. The CssHtmlTree panel will show the style
* information for the given element.
* @param {nsIDOMElement} aElement The highlighted node to get styles for.
*
* @param {NodeFront} aElement The highlighted node to get styles for.
* @returns a promise that will be resolved when highlighting is complete.
*/
highlight: function(aElement) {
@ -408,6 +407,10 @@ CssHtmlTree.prototype = {
return promise.resolve();
}
// Capture the current viewed element to return from the promise handler
// early if it changed
let viewedElement = this.viewedElement;
return promise.all([
this._createPropertyViews(),
this.pageStyle.getComputed(this.viewedElement, {
@ -416,6 +419,10 @@ CssHtmlTree.prototype = {
markMatched: true
})
]).then(([createViews, computed]) => {
if (viewedElement !== this.viewedElement) {
return;
}
this._matchedProperties = new Set;
for (let name in computed) {
if (computed[name].matched) {

View File

@ -1,5 +1,4 @@
[DEFAULT]
skip-if = e10s # Bug ?????? - devtools tests disabled with e10s
subsuite = devtools
support-files =
doc_content_stylesheet.html
@ -9,6 +8,7 @@ support-files =
doc_content_stylesheet_linked.css
doc_content_stylesheet_script.css
doc_content_stylesheet_xul.css
doc_frame_script.js
doc_keyframeanimation.html
doc_keyframeanimation.css
doc_matched_selectors.html
@ -62,6 +62,7 @@ support-files =
[browser_ruleview_completion-new-property_02.js]
[browser_ruleview_content_01.js]
[browser_ruleview_content_02.js]
skip-if = e10s # Bug 1039528: "inspect element" contextual-menu doesn't work with e10s
[browser_ruleview_cubicbezier-appears-on-swatch-click.js]
[browser_ruleview_cubicbezier-commit-on-ENTER.js]
[browser_ruleview_cubicbezier-revert-on-ESC.js]
@ -74,7 +75,7 @@ support-files =
[browser_ruleview_edit-selector_01.js]
[browser_ruleview_edit-selector_02.js]
[browser_ruleview_eyedropper.js]
skip-if = os == "win" && debug # bug 963492
skip-if = (os == "win" && debug) || e10s # bug 963492: win. bug 1040653: e10s.
[browser_ruleview_inherit.js]
[browser_ruleview_keybindings.js]
[browser_ruleview_keyframes-rule_01.js]
@ -96,6 +97,7 @@ skip-if = os == "win" && debug # bug 963492
[browser_ruleview_refresh-on-style-change.js]
[browser_ruleview_select-and-copy-styles.js]
[browser_ruleview_style-editor-link.js]
skip-if = e10s # bug 1040670 Cannot open inline styles in viewSourceUtils
[browser_ruleview_urls-clickable.js]
[browser_ruleview_user-agent-styles.js]
[browser_ruleview_user-agent-styles-uneditable.js]
@ -103,9 +105,6 @@ skip-if = os == "win" && debug # bug 963492
[browser_styleinspector_context-menu-copy-color_01.js]
[browser_styleinspector_context-menu-copy-color_02.js]
[browser_styleinspector_csslogic-content-stylesheets.js]
[browser_styleinspector_csslogic-inherited-properties.js]
[browser_styleinspector_csslogic-specificity.js]
[browser_styleinspector_inplace-editor.js]
[browser_styleinspector_output-parser.js]
[browser_styleinspector_tooltip-background-image.js]
[browser_styleinspector_tooltip-closes-on-new-selection.js]

View File

@ -14,14 +14,14 @@ let test = asyncTest(function*() {
let {toolbox, inspector, view} = yield openComputedView();
yield selectNode("#test", inspector);
yield testMatchedSelectors(view);
yield testMatchedSelectors(view, inspector);
});
function* testMatchedSelectors(view) {
function* testMatchedSelectors(view, inspector) {
info("checking selector counts, matched rules and titles");
is(getNode("#test"), view.viewedElement.rawNode(),
"style inspector node matches the selected node");
let nodeFront = yield getNodeFront("#test", inspector);
is(nodeFront, view.viewedElement, "style inspector node matches the selected node");
let propertyView = new PropertyView(view, "color");
propertyView.buildMain();

View File

@ -19,31 +19,10 @@ let test = asyncTest(function*() {
info("Selecting the test element");
yield selectNode("div", inspector);
info("Checking CSSLogic");
checkCssLogic();
info("Checking property view");
yield checkPropertyView(view);
});
function checkCssLogic() {
let cssLogic = new CssLogic();
cssLogic.highlight(getNode("div"));
cssLogic.processMatchedSelectors();
let _strings = Services.strings
.createBundle("chrome://global/locale/devtools/styleinspector.properties");
let inline = _strings.GetStringFromName("rule.sourceInline");
let source1 = inline + ":8";
let source2 = inline + ":15 @media screen and (min-width: 1px)";
is(cssLogic._matchedRules[0][0].source, source1,
"rule.source gives correct output for rule 1");
is(cssLogic._matchedRules[1][0].source, source2,
"rule.source gives correct output for rule 2");
}
function checkPropertyView(view) {
let propertyView = new PropertyView(view, "width");
propertyView.buildMain();

View File

@ -13,19 +13,16 @@ const TESTCASE_URI = 'data:text/html;charset=utf-8,' +
let test = asyncTest(function*() {
yield addTab(TESTCASE_URI);
info("Getting the test node");
let div = getNode("#testdiv");
info("Opening the computed view and selecting the test node");
let {toolbox, inspector, view} = yield openComputedView();
yield selectNode(div, inspector);
yield selectNode("#testdiv", inspector);
let fontSize = getComputedViewPropertyValue(view, "font-size");
is(fontSize, "10px", "The computed view shows the right font-size");
info("Changing the node's style and waiting for the update");
let onUpdated = inspector.once("computed-view-refreshed");
div.style.cssText = "font-size: 15px; color: red;";
getNode("#testdiv").style.cssText = "font-size: 15px; color: red;";
yield onUpdated;
fontSize = getComputedViewPropertyValue(view, "font-size");

View File

@ -13,12 +13,9 @@ const TESTCASE_URI = 'data:text/html;charset=utf-8,' +
let test = asyncTest(function*() {
yield addTab(TESTCASE_URI);
info("Getting the test node");
let div = getNode("#testdiv");
info("Opening the computed view and selecting the test node");
let {toolbox, inspector, view} = yield openComputedView();
yield selectNode(div, inspector);
yield selectNode("#testdiv", inspector);
let fontSize = getComputedViewPropertyValue(view, "font-size");
is(fontSize, "10px", "The computed view shows the right font-size");
@ -28,7 +25,7 @@ let test = asyncTest(function*() {
info("Changing the node's style and waiting for the update");
let onUpdated = inspector.once("computed-view-refreshed");
div.style.cssText = "font-size: 20px; color: blue; text-align: center";
getNode("#testdiv").style.cssText = "font-size: 20px; color: blue; text-align: center";
yield onUpdated;
fontSize = getComputedViewPropertyValue(view, "font-size");

View File

@ -15,22 +15,18 @@ let test = asyncTest(function*() {
let target = getNode("#target");
let {toolbox, inspector, view} = yield openRuleView();
yield selectNode(target, inspector);
yield selectNode("#target", inspector);
info("Setting a font-weight property on all rules");
setPropertyOnAllRules(view);
info("Reselecting the element");
yield reselectElement(target, inspector);
yield selectNode("body", inspector);
yield selectNode("#target", inspector);
checkPropertyOnAllRules(view);
});
function* reselectElement(node, inspector) {
yield selectNode(node.parentNode, inspector);
yield selectNode(node, inspector);
}
function setPropertyOnAllRules(view) {
for (let rule of view._elementStyle.rules) {
rule.editor.addProperty("font-weight", "bold", "");

View File

@ -14,7 +14,7 @@ let test = asyncTest(function*() {
content.document.body.innerHTML = '<div id="testid">Styled Node</div>';
let element = getNode("#testid");
yield selectNode(element, inspector);
yield selectNode("#testid", inspector);
let elementStyle = view._elementStyle;
let elementRule = elementStyle.rules[0];

View File

@ -22,7 +22,7 @@ let PAGE_CONTENT = [
].join("\n");
let test = asyncTest(function*() {
yield addTab("data:text/html;charset=utf-8,test rule view user changes");
let tab = yield addTab("data:text/html;charset=utf-8,test rule view user changes");
info("Creating the test document");
content.document.body.innerHTML = PAGE_CONTENT;
@ -33,11 +33,11 @@ let test = asyncTest(function*() {
info("Selecting the test element");
yield selectNode("#testid", inspector);
yield testEditProperty(view, "border-color", "red");
yield testEditProperty(view, "background-image", TEST_URL);
yield testEditProperty(view, "border-color", "red", tab.linkedBrowser);
yield testEditProperty(view, "background-image", TEST_URL, tab.linkedBrowser);
});
function* testEditProperty(view, name, value) {
function* testEditProperty(view, name, value, browser) {
info("Test editing existing property name/value fields");
let idRuleEditor = getRuleViewRuleEditor(view, 1);
@ -72,7 +72,13 @@ function* testEditProperty(view, name, value) {
yield onBlur;
yield onModifications;
let propValue = idRuleEditor.rule.domRule._rawStyle().getPropertyValue(name);
is(propEditor.isValid(), true, value + " is a valid entry");
info("Checking that the style property was changed on the content page");
let propValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
ruleIndex: 0,
name
});
is(propValue, value, name + " should have been set.");
is(propEditor.isValid(), true, value + " should be a valid entry");
}

View File

@ -68,8 +68,12 @@ function* testEditProperty(inspector, ruleView) {
yield onBlur;
yield idRuleEditor.rule._applyingModifications;
is(idRuleEditor.rule.style._rawStyle().getPropertyValue("border-color"), "red",
"border-color should have been set.");
let newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
ruleIndex: 0,
name: "border-color"
});
is(newValue, "red", "border-color should have been set.");
info("Entering property name \"color\" followed by a colon to focus the value");
let onFocus = once(idRuleEditor.element, "focus", true);
@ -103,14 +107,24 @@ function* testDisableProperty(inspector, ruleView) {
info("Disabling a property");
propEditor.enable.click();
yield idRuleEditor.rule._applyingModifications;
is(idRuleEditor.rule.style._rawStyle().getPropertyValue("border-color"), "",
"Border-color should have been unset.");
let newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
ruleIndex: 0,
name: "border-color"
});
is(newValue, "", "Border-color should have been unset.");
info("Enabling the property again");
propEditor.enable.click();
yield idRuleEditor.rule._applyingModifications;
is(idRuleEditor.rule.style._rawStyle().getPropertyValue("border-color"), "red",
"Border-color should have been reset.");
let newValue = yield executeInContent("Test:GetRulePropertyValue", {
styleSheetIndex: 0,
ruleIndex: 0,
name: "border-color"
});
is(newValue, "red", "Border-color should have been reset.");
}
function* testPropertyStillMarkedDirty(inspector, ruleView) {

View File

@ -28,11 +28,9 @@ const EXPECTED_COLOR = "rgb(255, 255, 85)"; // #ff5
let test = asyncTest(function*() {
yield addTab("data:text/html;charset=utf-8,rule view eyedropper test");
content.document.body.innerHTML = PAGE_CONTENT;
let {toolbox, inspector, view} = yield openRuleView();
let element = content.document.querySelector("div");
inspector.selection.setNode(element, "test");
yield inspector.once("inspector-updated");
let {toolbox, inspector, view} = yield openRuleView();
yield selectNode("div", inspector);
let property = getRuleViewProperty(view, "div", "background-color");
let swatch = property.valueSpan.querySelector(".ruleview-colorswatch");
@ -53,7 +51,6 @@ let test = asyncTest(function*() {
yield testSelect(swatch, dropper);
});
function testESC(swatch, dropper) {
let deferred = promise.defer();

View File

@ -80,7 +80,7 @@ function testMoxy(inspector, view) {
function* testNode(selector, inspector, view) {
let element = getNode(selector);
yield selectNode(element, inspector);
yield selectNode(selector, inspector);
let elementStyle = view._elementStyle;
return {element, elementStyle};
}

View File

@ -98,7 +98,7 @@ function convertTextPropsToString(textProps) {
function* getKeyframeRules(selector, inspector, view) {
let element = getNode(selector);
yield selectNode(element, inspector);
yield selectNode(selector, inspector);
let elementStyle = view._elementStyle;
let rules = {

View File

@ -31,7 +31,7 @@ let test = asyncTest(function*() {
let testElement = getNode("#testid");
let {toolbox, inspector, view} = yield openRuleView();
yield selectNode(testElement, inspector);
yield selectNode("#testid", inspector);
for (let data of TEST_DATA) {
yield testLivePreviewData(data, view, testElement);

View File

@ -16,7 +16,7 @@ let test = asyncTest(function*() {
let newElement = content.document.createElement("div");
newElement.textContent = "Test Element";
content.document.body.appendChild(newElement);
yield selectNode(newElement, inspector);
yield selectNode("div", inspector);
let ruleEditor = getRuleViewRuleEditor(view, 0);
yield testCreateNewMultiDuplicates(inspector, ruleEditor);

View File

@ -16,7 +16,7 @@ let test = asyncTest(function*() {
let newElement = content.document.createElement("div");
newElement.textContent = "Test Element";
content.document.body.appendChild(newElement);
yield selectNode(newElement, inspector);
yield selectNode("div", inspector);
let ruleEditor = getRuleViewRuleEditor(view, 0);
yield testCreateNewMultiPriority(inspector, ruleEditor);

View File

@ -16,7 +16,7 @@ let test = asyncTest(function*() {
let newElement = content.document.createElement("div");
newElement.textContent = "Test Element";
content.document.body.appendChild(newElement);
yield selectNode(newElement, inspector);
yield selectNode("div", inspector);
let ruleEditor = getRuleViewRuleEditor(view, 0);
yield testCreateNewMultiUnfinished(inspector, ruleEditor, view);

View File

@ -16,7 +16,7 @@ let test = asyncTest(function*() {
let newElement = content.document.createElement("div");
newElement.textContent = "Test Element";
content.document.body.appendChild(newElement);
yield selectNode(newElement, inspector);
yield selectNode("div", inspector);
let ruleEditor = getRuleViewRuleEditor(view, 0);
yield testCreateNewMultiPartialUnfinished(inspector, ruleEditor, view);

View File

@ -16,7 +16,7 @@ let test = asyncTest(function*() {
let newElement = content.document.createElement("div");
newElement.textContent = "Test Element";
content.document.body.appendChild(newElement);
yield selectNode(newElement, inspector);
yield selectNode("div", inspector);
let ruleEditor = getRuleViewRuleEditor(view, 0);
yield testCreateNewMulti(inspector, ruleEditor);

View File

@ -16,7 +16,7 @@ let test = asyncTest(function*() {
let newElement = content.document.createElement("div");
newElement.textContent = "Test Element";
content.document.body.appendChild(newElement);
yield selectNode(newElement, inspector);
yield selectNode("div", inspector);
let ruleEditor = getRuleViewRuleEditor(view, 0);
yield testMultiValues(inspector, ruleEditor, view);

View File

@ -230,7 +230,7 @@ function convertTextPropsToString(textProps) {
function* testNode(selector, inspector, view) {
let element = getNode(selector);
yield selectNode(element, inspector);
yield selectNode(selector, inspector);
let elementStyle = view._elementStyle;
return {element: element, elementStyle: elementStyle};
}

View File

@ -24,7 +24,7 @@ let test = asyncTest(function*() {
testElement.setAttribute("style", elementStyle);
let {toolbox, inspector, view} = yield openRuleView();
yield selectNode(testElement, inspector);
yield selectNode("#testid", inspector);
info("Checking that the rule-view has the element, #testid and .testclass selectors");
checkRuleViewContent(view, ["element", "#testid", ".testclass"]);

View File

@ -14,7 +14,7 @@ let test = asyncTest(function*() {
testElement.setAttribute("style", "margin-top: 1px; padding-top: 5px;");
let {toolbox, inspector, view} = yield openRuleView();
yield selectNode(testElement, inspector);
yield selectNode("#testid", inspector);
yield testPropertyChanges(inspector, view, testElement);
yield testPropertyChange0(inspector, view, testElement);

View File

@ -20,7 +20,7 @@ let test = asyncTest(function*() {
info("Opening the rule view and selecting the test node");
let {toolbox, inspector, view} = yield openRuleView();
yield selectNode(div, inspector);
yield selectNode("#testdiv", inspector);
let fontSize = getRuleViewPropertyValue(view, "element", "font-size");
is(fontSize, "10px", "The rule view shows the right font-size");

View File

@ -19,19 +19,19 @@ let test = asyncTest(function*() {
yield selectNode("#id1", inspector);
yield modifyRuleViewWidth("300px", view, inspector);
assertRuleAndMarkupViewWidth("id1", "300px", view, inspector);
yield assertRuleAndMarkupViewWidth("id1", "300px", view, inspector);
yield selectNode("#id2", inspector);
assertRuleAndMarkupViewWidth("id2", "100px", view, inspector);
yield assertRuleAndMarkupViewWidth("id2", "100px", view, inspector);
yield modifyRuleViewWidth("50px", view, inspector);
assertRuleAndMarkupViewWidth("id2", "50px", view, inspector);
yield assertRuleAndMarkupViewWidth("id2", "50px", view, inspector);
yield reloadPage(inspector);
yield selectNode("#id1", inspector);
assertRuleAndMarkupViewWidth("id1", "200px", view, inspector);
yield assertRuleAndMarkupViewWidth("id1", "200px", view, inspector);
yield selectNode("#id2", inspector);
assertRuleAndMarkupViewWidth("id2", "100px", view, inspector);
yield assertRuleAndMarkupViewWidth("id2", "100px", view, inspector);
});
function getStyleRule(ruleView) {
@ -62,8 +62,8 @@ function* modifyRuleViewWidth(value, ruleView, inspector) {
yield onNewFieldBlur;
}
function getContainerStyleAttrValue(id, {markup}) {
let front = markup.walker.frontForRawNode(content.document.getElementById(id));
function* getContainerStyleAttrValue(id, {walker, markup}) {
let front = yield walker.querySelector(walker.rootNode, "#" + id);
let container = markup.getContainer(front);
let attrIndex = 0;
@ -75,11 +75,11 @@ function getContainerStyleAttrValue(id, {markup}) {
}
}
function assertRuleAndMarkupViewWidth(id, value, ruleView, inspector) {
function* assertRuleAndMarkupViewWidth(id, value, ruleView, inspector) {
let valueSpan = getStyleRule(ruleView).querySelector(".ruleview-propertyvalue");
is(valueSpan.textContent, value, "Rule-view style width is " + value + " as expected");
let attr = getContainerStyleAttrValue(id, inspector);
let attr = yield getContainerStyleAttrValue(id, inspector);
is(attr.textContent.replace(/\s/g, ""), "width:" + value + ";", "Markup-view style attribute width is " + value);
}

View File

@ -6,6 +6,9 @@
// Check stylesheets on HMTL and XUL document
// FIXME: this test opens the devtools for nothing, it should be changed into a
// toolkit/devtools/server/tests/mochitest/test_css-logic-...something...html test
const TEST_URI_HTML = TEST_URL_ROOT + "doc_content_stylesheet.html";
const TEST_URI_XUL = TEST_URL_ROOT + "doc_content_stylesheet.xul";
const XUL_URI = Cc["@mozilla.org/network/io-service;1"]
@ -15,18 +18,16 @@ const XUL_PRINCIPAL = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(XUL_URI);
let {CssLogic} = devtools.require("devtools/styleinspector/css-logic");
let test = asyncTest(function*() {
info("Checking stylesheets on HTML document");
yield addTab(TEST_URI_HTML);
let target = getNode("#target");
let {toolbox, inspector, view} = yield openRuleView();
yield selectNode(target, inspector);
yield selectNode("#target", inspector);
info("Checking stylesheets");
checkSheets(target);
yield checkSheets(target);
info("Checking stylesheets on XUL document");
info("Allowing XUL content");
@ -35,9 +36,9 @@ let test = asyncTest(function*() {
let {toolbox, inspector, view} = yield openRuleView();
let target = getNode("#target");
yield selectNode(target, inspector);
yield selectNode("#target", inspector);
checkSheets(target);
yield checkSheets(target);
info("Disallowing XUL content");
disallowXUL();
});
@ -52,21 +53,15 @@ function disallowXUL() {
.addFromPrincipal(XUL_PRINCIPAL, 'allowXULXBL', Ci.nsIPermissionManager.DENY_ACTION);
}
function checkSheets(target) {
let domUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(Ci.inIDOMUtils);
let domRules = domUtils.getCSSStyleRules(target);
for (let i = 0, n = domRules.Count(); i < n; i++) {
let domRule = domRules.GetElementAt(i);
let sheet = domRule.parentStyleSheet;
let isContentSheet = CssLogic.isContentStylesheet(sheet);
function* checkSheets(target) {
let sheets = yield executeInContent("Test:GetStyleSheetsInfoForNode", {}, {target});
for (let sheet of sheets) {
if (!sheet.href ||
/doc_content_stylesheet_/.test(sheet.href)) {
ok(isContentSheet, sheet.href + " identified as content stylesheet");
ok(sheet.isContentSheet, sheet.href + " identified as content stylesheet");
} else {
ok(!isContentSheet, sheet.href + " identified as non-content stylesheet");
ok(!sheet.isContentSheet, sheet.href + " identified as non-content stylesheet");
}
}
}

View File

@ -1,23 +0,0 @@
/* 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";
// Test that inherited properties are treated correctly.
let test = asyncTest(function*() {
yield addTab("data:text/html;charset=utf-8,selector text test, bug 692400");
content.document.body.innerHTML = '<div style="margin-left:10px; font-size: 5px"><div id="innerdiv">Inner div</div></div>';
content.document.title = "Style Inspector Inheritance Test";
let cssLogic = new CssLogic();
cssLogic.highlight(content.document.getElementById("innerdiv"));
let marginProp = cssLogic.getPropertyInfo("margin-left");
is(marginProp.matchedRuleCount, 0, "margin-left should not be included in matched selectors.");
let fontSizeProp = cssLogic.getPropertyInfo("font-size");
is(fontSizeProp.matchedRuleCount, 1, "font-size should be included in matched selectors.");
});

View File

@ -1,75 +0,0 @@
/* 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";
// Tests that CSS specificity is properly calculated.
const DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(Ci.inIDOMUtils);
const TEST_DATA = [
{text: "*", expected: 0},
{text: "LI", expected: 1},
{text: "UL LI", expected: 2},
{text: "UL OL + LI", expected: 3},
{text: "H1 + [REL=\"up\"]", expected: 257},
{text: "UL OL LI.red", expected: 259},
{text: "LI.red.level", expected: 513},
{text: ".red .level", expected: 512},
{text: "#x34y", expected: 65536},
{text: "#s12:not(FOO)", expected: 65537},
{text: "body#home div#warning p.message", expected: 131331},
{text: "* body#home div#warning p.message", expected: 131331},
{text: "#footer :not(nav) li", expected: 65538},
{text: "bar:nth-child(n)", expected: 257},
{text: "li::-moz-list-number", expected: 1},
{text: "a:hover", expected: 257}
];
let test = asyncTest(function*() {
yield addTab("data:text/html;charset=utf-8,Computed view specificity test");
createDocument();
info("Creating a CssLogic instance");
let cssLogic = new CssLogic();
cssLogic.highlight(content.document.body);
let cssSheet = cssLogic.sheets[0];
let cssRule = cssSheet.domSheet.cssRules[0];
let selectors = CssLogic.getSelectors(cssRule);
info("Iterating over the test selectors")
for (let i = 0; i < selectors.length; i++) {
let selectorText = selectors[i];
info("Testing selector " + selectorText);
let selector = new CssSelector(cssRule, selectorText, i);
let expected = getExpectedSpecificity(selectorText);
let specificity = DOMUtils.getSpecificity(selector.cssRule,
selector.selectorIndex)
is(specificity, expected,
'Selector "' + selectorText + '" has a specificity of ' + expected);
}
info("Testing specificity of element.style");
let colorProp = cssLogic.getPropertyInfo("background");
is(colorProp.matchedSelectors[0].specificity, 0x01000000,
"Element styles have specificity of 0x01000000 (16777216).");
});
function createDocument() {
let doc = content.document;
doc.body.innerHTML = getStylesheetText();
doc.body.style.background = "blue";
doc.title = "Computed view specificity test";
}
function getStylesheetText() {
info("Creating the test stylesheet");
let text = TEST_DATA.map(i=>i.text).join(",");
return '<style type="text/css">' + text + " {color:red;}</style>";
}
function getExpectedSpecificity(selectorText) {
return TEST_DATA.filter(i=>i.text === selectorText)[0].expected;
}

View File

@ -72,7 +72,7 @@ let test = asyncTest(function*() {
"The highlighter was shown once, after several mousemove");
info("Checking that the right NodeFront reference is passed");
yield selectNode(content.document.documentElement, inspector);
yield selectNode("html", inspector);
let {valueSpan} = getRuleViewProperty(rView, "html", "transform");
rView.highlighters._onMouseMove({target: valueSpan});
is(HighlighterFront.nodeFront.tagName, "HTML",

View File

@ -0,0 +1,76 @@
/* 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";
// A helper frame-script for brower/devtools/styleinspector tests.
//
// Most listeners in the script expect "Test:"-namespaced messages from chrome,
// then execute code upon receiving, and immediately send back a message.
// This is so that chrome test code can execute code in content and wait for a
// response this way:
// let response = yield executeInContent(browser, "Test:MessageName", data, true);
// The response message should have the same name "Test:MessageName"
//
// Some listeners do not send a response message back.
let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
let {require} = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}).devtools;
let {CssLogic} = require("devtools/styleinspector/css-logic");
/**
* Get a value for a given property name in a css rule in a stylesheet, given
* their indexes
* @param {Object} data Expects a data object with the following properties
* - {Number} styleSheetIndex
* - {Number} ruleIndex
* - {String} name
* @return {String} The value, if found, null otherwise
*/
addMessageListener("Test:GetRulePropertyValue", function(msg) {
let {name, styleSheetIndex, ruleIndex} = msg.data;
let value = null;
dumpn("Getting the value for property name " + name + " in sheet " +
styleSheetIndex + " and rule " + ruleIndex);
let sheet = content.document.styleSheets[styleSheetIndex];
if (sheet) {
let rule = sheet.cssRules[ruleIndex];
if (rule) {
value = rule.style.getPropertyValue(name);
}
}
sendAsyncMessage("Test:GetRulePropertyValue", value);
});
/**
* Get information about all the stylesheets that contain rules that apply to
* a given node. The information contains the sheet href and whether or not the
* sheet is a content sheet or not
* @param {Object} objects Expects a 'target' CPOW object
* @return {Array} A list of stylesheet info objects
*/
addMessageListener("Test:GetStyleSheetsInfoForNode", function(msg) {
let target = msg.objects.target;
let sheets = [];
let domUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(Ci.inIDOMUtils);
let domRules = domUtils.getCSSStyleRules(target);
for (let i = 0, n = domRules.Count(); i < n; i++) {
let sheet = domRules.GetElementAt(i).parentStyleSheet;
sheets.push({
href: sheet.href,
isContentSheet: CssLogic.isContentStylesheet(sheet)
});
}
sendAsyncMessage("Test:GetStyleSheetsInfoForNode", sheets);
});
let dumpn = msg => dump(msg + "\n");

View File

@ -15,20 +15,19 @@ let {Promise: promise} = Cu.import("resource://gre/modules/Promise.jsm", {});
let {editableField, getInplaceEditorForSpan: inplaceEditor} = devtools.require("devtools/shared/inplace-editor");
let {console} = Components.utils.import("resource://gre/modules/devtools/Console.jsm", {});
// All test are asynchronous
// All tests are asynchronous
waitForExplicitFinish();
const TEST_URL_ROOT = "http://example.com/browser/browser/devtools/styleinspector/test/";
const TEST_URL_ROOT_SSL = "https://example.com/browser/browser/devtools/styleinspector/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(() => {
try {
let target = TargetFactory.forTab(gBrowser.selectedTab);
gDevTools.closeToolbox(target);
} catch (ex) {
dump(ex);
}
registerCleanupFunction(function*() {
let target = TargetFactory.forTab(gBrowser.selectedTab);
yield gDevTools.closeToolbox(target);
while (gBrowser.tabs.length > 1) {
gBrowser.removeCurrentTab();
}
@ -101,17 +100,32 @@ function asyncTest(generator) {
* @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();
let tab = gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
info("URL " + url + " loading complete into new test tab");
waitForFocus(() => {
def.resolve(tab);
}, content);
window.focus();
let tab = window.gBrowser.selectedTab = window.gBrowser.addTab(url);
let browser = tab.linkedBrowser;
info("Loading the helper frame script " + FRAME_SCRIPT_URL);
// Bug 687194 - Mochitest registers its chrome URLs after browser
// initialization, so the content processes don't pick them up. That
// means we can't load our frame script from its chrome URI, because
// the content process won't be able to find it.
// Instead, we resolve the chrome URI for the script to a file URI, which
// we can then pass to the content process, which it is able to find.
let registry = Cc['@mozilla.org/chrome/chrome-registry;1']
.getService(Ci.nsIChromeRegistry);
let fileURI = registry.convertChromeURL(Services.io.newURI(FRAME_SCRIPT_URL, null, null)).spec;
browser.messageManager.loadFrameScript(fileURI, false);
browser.addEventListener("load", function onload() {
browser.removeEventListener("load", onload, true);
info("URL '" + url + "' loading complete");
def.resolve(tab);
}, true);
content.location = url;
return def.promise;
}
@ -120,53 +134,61 @@ function addTab(url) {
* 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}
* @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;
}
/**
* Highlight a node and set the inspector's current selection to the node or
* the first match of the given css selector.
* @param {String|DOMNode} nodeOrSelector
* @param {InspectorPanel} inspector
* The instance of InspectorPanel currently loaded in the toolbox
* @return a promise that resolves when the inspector is updated with the new
* node
* 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 selectAndHighlightNode(nodeOrSelector, inspector) {
info("Highlighting and selecting the node " + nodeOrSelector);
let node = getNode(nodeOrSelector);
let updated = inspector.toolbox.once("highlighter-ready");
inspector.selection.setNode(node, "test-highlight");
return updated;
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|DOMNode} nodeOrSelector
* @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 a promise that resolves when the inspector is updated with the new
* node
* Highlight a node that matches the given css selector and set the inspector's
* current selection to this node.
* @param {String} selector
* @param {InspectorPanel} inspector The instance of InspectorPanel currently
* loaded in the toolbox
* @return {Promise} Resolves when the inspector is updated with the new node
*/
function selectNode(nodeOrSelector, inspector, reason="test") {
info("Selecting the node " + nodeOrSelector);
let selectAndHighlightNode = Task.async(function*(selector, inspector) {
info("Highlighting and selecting the node for " + selector);
let node = getNode(nodeOrSelector);
let nodeFront = yield getNodeFront(selector, inspector);
let updated = inspector.toolbox.once("highlighter-ready");
inspector.selection.setNodeFront(nodeFront, "test-highlight");
yield updated;
});
/**
* Set the inspector's current selection to a node that matches the given css
* selector.
* @param {String} 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
*/
let 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.setNode(node, reason);
return updated;
}
inspector.selection.setNodeFront(nodeFront, reason);
yield updated;
});
/**
* Set the inspector's current selection to null so that no node is selected
@ -177,7 +199,7 @@ function selectNode(nodeOrSelector, inspector, reason="test") {
function clearCurrentNodeSelection(inspector) {
info("Clearing the current selection");
let updated = inspector.once("inspector-updated");
inspector.selection.setNode(null);
inspector.selection.setNodeFront(null);
return updated;
}
@ -319,6 +341,50 @@ function wait(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
*/
function waitForContentMessage(name) {
info("Expecting message " + name + " from content");
let mm = gBrowser.selectedTab.linkedBrowser.messageManager;
let def = promise.defer();
mm.addMessageListener(name, function onMessage(msg) {
mm.removeMessageListener(name, onMessage);
def.resolve(msg.data);
});
return def.promise;
}
/**
* Send an async message to the frame script (chrome -> content) and wait for a
* response message with the same name (content -> chrome).
* @param {String} name The message name. Should be one of the messages defined
* in doc_frame_script.js
* @param {Object} data Optional data to send along
* @param {Object} objects Optional CPOW objects to send along
* @param {Boolean} expectResponse If set to false, don't wait for a response
* with the same name from the content script. Defaults to true.
* @return {Promise} Resolves to the response data if a response is expected,
* immediately resolves otherwise
*/
function executeInContent(name, data={}, objects={}, expectResponse=true) {
info("Sending message " + name + " to content");
let mm = gBrowser.selectedTab.linkedBrowser.messageManager;
mm.sendAsyncMessage(name, data, objects);
if (expectResponse) {
return waitForContentMessage(name);
} else {
return promise.resolve();
}
}
/**
* Given an inplace editable element, click to switch it to edit mode, wait for
* focus

View File

@ -1004,19 +1004,6 @@ var StyleRuleFront = protocol.FrontClass(StyleRuleActor, {
this._originalLocation = location;
return location;
})
},
// Only used for testing, please keep it that way.
_rawStyle: function() {
if (!this.conn._transport._serverConnection) {
console.warn("Tried to use rawNode on a remote connection.");
return null;
}
let actor = this.conn._transport._serverConnection.getActor(this.actorID);
if (!actor) {
return null;
}
return actor.rawStyle;
}
});

View File

@ -20,6 +20,9 @@ support-files =
[test_connection-manager.html]
skip-if = buildapp == 'mulet'
[test_css-logic.html]
[test_css-logic-inheritance.html]
[test_css-logic-media-queries.html]
[test_css-logic-specificity.html]
[test_device.html]
skip-if = buildapp == 'mulet'
[test_framerate_01.html]

View File

@ -0,0 +1,43 @@
<!DOCTYPE HTML>
<html>
<!--
Test that css-logic handles inherited properties correctly
-->
<head>
<meta charset="utf-8">
<title>Test css-logic inheritance</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
</head>
<body>
<div style="margin-left:10px; font-size: 5px">
<div id="innerdiv">Inner div</div>
</div>
<script type="application/javascript;version=1.8">
window.onload = function() {
var Cu = Components.utils;
Cu.import("resource://gre/modules/devtools/Loader.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const {CssLogic} = devtools.require("devtools/styleinspector/css-logic");
SimpleTest.waitForExplicitFinish();
let cssLogic = new CssLogic();
cssLogic.highlight(document.getElementById("innerdiv"));
let marginProp = cssLogic.getPropertyInfo("margin-left");
is(marginProp.matchedRuleCount, 0,
"margin-left should not be included in matched selectors.");
let fontSizeProp = cssLogic.getPropertyInfo("font-size");
is(fontSizeProp.matchedRuleCount, 1,
"font-size should be included in matched selectors.");
SimpleTest.finish();
}
</script>
</body>
</html>

View File

@ -0,0 +1,60 @@
<!DOCTYPE HTML>
<html>
<!--
Test that css-logic handles media-queries correctly
-->
<head>
<meta charset="utf-8">
<title>Test css-logic media-queries</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
<style>
div {
width: 1000px;
height: 100px;
background-color: #f00;
}
@media screen and (min-width: 1px) {
div {
width: 200px;
}
}
</style>
</head>
<body>
<div></div>
<script type="application/javascript;version=1.8">
window.onload = function() {
var Cu = Components.utils;
Cu.import("resource://gre/modules/devtools/Loader.jsm");
Cu.import("resource://gre/modules/Services.jsm");
const {CssLogic} = devtools.require("devtools/styleinspector/css-logic");
SimpleTest.waitForExplicitFinish();
let div = document.querySelector("div");
let cssLogic = new CssLogic();
cssLogic.highlight(div);
cssLogic.processMatchedSelectors();
let _strings = Services.strings
.createBundle("chrome://global/locale/devtools/styleinspector.properties");
let inline = _strings.GetStringFromName("rule.sourceInline");
let source1 = inline + ":12";
let source2 = inline + ":19 @media screen and (min-width: 1px)";
is(cssLogic._matchedRules[0][0].source, source1,
"rule.source gives correct output for rule 1");
is(cssLogic._matchedRules[1][0].source, source2,
"rule.source gives correct output for rule 2");
SimpleTest.finish();
}
</script>
</body>
</html>

View File

@ -0,0 +1,84 @@
<!DOCTYPE HTML>
<html>
<!--
Test that css-logic calculates CSS specificity properly
-->
<head>
<meta charset="utf-8">
<title>Test css-logic specificity</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
</head>
<body style="background:blue;">
<script type="application/javascript;version=1.8">
window.onload = function() {
var {utils: Cu, classes: Cc, interfaces: Ci} = Components;
Cu.import("resource://gre/modules/devtools/Loader.jsm");
const {CssLogic, CssSelector} = devtools.require("devtools/styleinspector/css-logic");
const DOMUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(Ci.inIDOMUtils);
const TEST_DATA = [
{text: "*", expected: 0},
{text: "LI", expected: 1},
{text: "UL LI", expected: 2},
{text: "UL OL + LI", expected: 3},
{text: "H1 + [REL=\"up\"]", expected: 257},
{text: "UL OL LI.red", expected: 259},
{text: "LI.red.level", expected: 513},
{text: ".red .level", expected: 512},
{text: "#x34y", expected: 65536},
{text: "#s12:not(FOO)", expected: 65537},
{text: "body#home div#warning p.message", expected: 131331},
{text: "* body#home div#warning p.message", expected: 131331},
{text: "#footer :not(nav) li", expected: 65538},
{text: "bar:nth-child(n)", expected: 257},
{text: "li::-moz-list-number", expected: 1},
{text: "a:hover", expected: 257}
];
function createDocument() {
let text = TEST_DATA.map(i=>i.text).join(",");
text = '<style type="text/css">' + text + " {color:red;}</style>";
document.body.innerHTML = text;
}
function getExpectedSpecificity(selectorText) {
return TEST_DATA.filter(i => i.text === selectorText)[0].expected;
}
SimpleTest.waitForExplicitFinish();
createDocument();
let cssLogic = new CssLogic();
cssLogic.highlight(document.body);
let cssSheet = cssLogic.sheets[0];
let cssRule = cssSheet.domSheet.cssRules[0];
let selectors = CssLogic.getSelectors(cssRule);
info("Iterating over the test selectors")
for (let i = 0; i < selectors.length; i++) {
let selectorText = selectors[i];
info("Testing selector " + selectorText);
let selector = new CssSelector(cssRule, selectorText, i);
let expected = getExpectedSpecificity(selectorText);
let specificity = DOMUtils.getSpecificity(selector.cssRule,
selector.selectorIndex)
is(specificity, expected,
'Selector "' + selectorText + '" has a specificity of ' + expected);
}
info("Testing specificity of element.style");
let colorProp = cssLogic.getPropertyInfo("background");
is(colorProp.matchedSelectors[0].specificity, 0x01000000,
"Element styles have specificity of 0x01000000 (16777216).");
SimpleTest.finish();
}
</script>
</body>
</html>