diff options
Diffstat (limited to 'devtools/client/inspector/components/test')
18 files changed, 1382 insertions, 0 deletions
diff --git a/devtools/client/inspector/components/test/.eslintrc.js b/devtools/client/inspector/components/test/.eslintrc.js new file mode 100644 index 000000000..698ae9181 --- /dev/null +++ b/devtools/client/inspector/components/test/.eslintrc.js @@ -0,0 +1,6 @@ +"use strict"; + +module.exports = { + // Extend from the shared list of defined globals for mochitests. + "extends": "../../../../.eslintrc.mochitests.js" +}; diff --git a/devtools/client/inspector/components/test/browser.ini b/devtools/client/inspector/components/test/browser.ini new file mode 100644 index 000000000..42eb352d6 --- /dev/null +++ b/devtools/client/inspector/components/test/browser.ini @@ -0,0 +1,29 @@ +[DEFAULT] +tags = devtools +subsuite = devtools +support-files = + doc_boxmodel_iframe1.html + doc_boxmodel_iframe2.html + head.js + !/devtools/client/commandline/test/helpers.js + !/devtools/client/framework/test/shared-head.js + !/devtools/client/inspector/test/head.js + !/devtools/client/inspector/test/shared-head.js + !/devtools/client/shared/test/test-actor.js + !/devtools/client/shared/test/test-actor-registry.js + +[browser_boxmodel.js] +[browser_boxmodel_editablemodel.js] +# [browser_boxmodel_editablemodel_allproperties.js] +# Disabled for too many intermittent failures (bug 1009322) +[browser_boxmodel_editablemodel_bluronclick.js] +[browser_boxmodel_editablemodel_border.js] +[browser_boxmodel_editablemodel_stylerules.js] +[browser_boxmodel_guides.js] +[browser_boxmodel_rotate-labels-on-sides.js] +[browser_boxmodel_sync.js] +[browser_boxmodel_tooltips.js] +[browser_boxmodel_update-after-navigation.js] +[browser_boxmodel_update-after-reload.js] +# [browser_boxmodel_update-in-iframes.js] +# Bug 1020038 boxmodel-view updates for iframe elements changes diff --git a/devtools/client/inspector/components/test/browser_boxmodel.js b/devtools/client/inspector/components/test/browser_boxmodel.js new file mode 100644 index 000000000..f8b87f421 --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel.js @@ -0,0 +1,168 @@ +/* vim: set 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 the box model displays the right values and that it updates when +// the node's style is changed + +// Expected values: +var res1 = [ + { + selector: "#boxmodel-element-size", + value: "160" + "\u00D7" + "160.117" + }, + { + selector: ".boxmodel-size > span", + value: "100" + "\u00D7" + "100.117" + }, + { + selector: ".boxmodel-margin.boxmodel-top > span", + value: 30 + }, + { + selector: ".boxmodel-margin.boxmodel-left > span", + value: "auto" + }, + { + selector: ".boxmodel-margin.boxmodel-bottom > span", + value: 30 + }, + { + selector: ".boxmodel-margin.boxmodel-right > span", + value: "auto" + }, + { + selector: ".boxmodel-padding.boxmodel-top > span", + value: 20 + }, + { + selector: ".boxmodel-padding.boxmodel-left > span", + value: 20 + }, + { + selector: ".boxmodel-padding.boxmodel-bottom > span", + value: 20 + }, + { + selector: ".boxmodel-padding.boxmodel-right > span", + value: 20 + }, + { + selector: ".boxmodel-border.boxmodel-top > span", + value: 10 + }, + { + selector: ".boxmodel-border.boxmodel-left > span", + value: 10 + }, + { + selector: ".boxmodel-border.boxmodel-bottom > span", + value: 10 + }, + { + selector: ".boxmodel-border.boxmodel-right > span", + value: 10 + }, +]; + +var res2 = [ + { + selector: "#boxmodel-element-size", + value: "190" + "\u00D7" + "210" + }, + { + selector: ".boxmodel-size > span", + value: "100" + "\u00D7" + "150" + }, + { + selector: ".boxmodel-margin.boxmodel-top > span", + value: 30 + }, + { + selector: ".boxmodel-margin.boxmodel-left > span", + value: "auto" + }, + { + selector: ".boxmodel-margin.boxmodel-bottom > span", + value: 30 + }, + { + selector: ".boxmodel-margin.boxmodel-right > span", + value: "auto" + }, + { + selector: ".boxmodel-padding.boxmodel-top > span", + value: 20 + }, + { + selector: ".boxmodel-padding.boxmodel-left > span", + value: 20 + }, + { + selector: ".boxmodel-padding.boxmodel-bottom > span", + value: 20 + }, + { + selector: ".boxmodel-padding.boxmodel-right > span", + value: 50 + }, + { + selector: ".boxmodel-border.boxmodel-top > span", + value: 10 + }, + { + selector: ".boxmodel-border.boxmodel-left > span", + value: 10 + }, + { + selector: ".boxmodel-border.boxmodel-bottom > span", + value: 10 + }, + { + selector: ".boxmodel-border.boxmodel-right > span", + value: 10 + }, +]; + +add_task(function* () { + let style = "div { position: absolute; top: 42px; left: 42px; " + + "height: 100.111px; width: 100px; border: 10px solid black; " + + "padding: 20px; margin: 30px auto;}"; + let html = "<style>" + style + "</style><div></div>"; + + yield addTab("data:text/html," + encodeURIComponent(html)); + let {inspector, view, testActor} = yield openBoxModelView(); + yield selectNode("div", inspector); + + yield testInitialValues(inspector, view); + yield testChangingValues(inspector, view, testActor); +}); + +function* testInitialValues(inspector, view) { + info("Test that the initial values of the box model are correct"); + let viewdoc = view.doc; + + for (let i = 0; i < res1.length; i++) { + let elt = viewdoc.querySelector(res1[i].selector); + is(elt.textContent, res1[i].value, + res1[i].selector + " has the right value."); + } +} + +function* testChangingValues(inspector, view, testActor) { + info("Test that changing the document updates the box model"); + let viewdoc = view.doc; + + let onUpdated = waitForUpdate(inspector); + yield testActor.setAttribute("div", "style", + "height:150px;padding-right:50px;"); + yield onUpdated; + + for (let i = 0; i < res2.length; i++) { + let elt = viewdoc.querySelector(res2[i].selector); + is(elt.textContent, res2[i].value, + res2[i].selector + " has the right value after style update."); + } +} diff --git a/devtools/client/inspector/components/test/browser_boxmodel_editablemodel.js b/devtools/client/inspector/components/test/browser_boxmodel_editablemodel.js new file mode 100644 index 000000000..5c32c2029 --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_editablemodel.js @@ -0,0 +1,194 @@ +/* vim: set 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 editing the box-model values works as expected and test various +// key bindings + +const TEST_URI = "<style>" + + "div { margin: 10px; padding: 3px }" + + "#div1 { margin-top: 5px }" + + "#div2 { border-bottom: 1em solid black; }" + + "#div3 { padding: 2em; }" + + "#div4 { margin: 1px; }" + + "</style>" + + "<div id='div1'></div><div id='div2'></div>" + + "<div id='div3'></div><div id='div4'></div>"; + +add_task(function* () { + yield addTab("data:text/html," + encodeURIComponent(TEST_URI)); + let {inspector, view, testActor} = yield openBoxModelView(); + + yield testEditingMargins(inspector, view, testActor); + yield testKeyBindings(inspector, view, testActor); + yield testEscapeToUndo(inspector, view, testActor); + yield testDeletingValue(inspector, view, testActor); + yield testRefocusingOnClick(inspector, view, testActor); +}); + +function* testEditingMargins(inspector, view, testActor) { + info("Test that editing margin dynamically updates the document, pressing " + + "escape cancels the changes"); + + is((yield getStyle(testActor, "#div1", "margin-top")), "", + "Should be no margin-top on the element."); + yield selectNode("#div1", inspector); + + let span = view.doc.querySelector(".boxmodel-margin.boxmodel-top > span"); + is(span.textContent, 5, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "5px", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("3", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is((yield getStyle(testActor, "#div1", "margin-top")), "3px", + "Should have updated the margin."); + + EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is((yield getStyle(testActor, "#div1", "margin-top")), "", + "Should be no margin-top on the element."); + is(span.textContent, 5, "Should have the right value in the box model."); +} + +function* testKeyBindings(inspector, view, testActor) { + info("Test that arrow keys work correctly and pressing enter commits the " + + "changes"); + + is((yield getStyle(testActor, "#div1", "margin-left")), "", + "Should be no margin-top on the element."); + yield selectNode("#div1", inspector); + + let span = view.doc.querySelector(".boxmodel-margin.boxmodel-left > span"); + is(span.textContent, 10, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "10px", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("VK_UP", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "11px", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div1", "margin-left")), "11px", + "Should have updated the margin."); + + EventUtils.synthesizeKey("VK_DOWN", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "10px", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div1", "margin-left")), "10px", + "Should have updated the margin."); + + EventUtils.synthesizeKey("VK_UP", { shiftKey: true }, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "20px", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div1", "margin-left")), "20px", + "Should have updated the margin."); + EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView); + + is((yield getStyle(testActor, "#div1", "margin-left")), "20px", + "Should be the right margin-top on the element."); + is(span.textContent, 20, "Should have the right value in the box model."); +} + +function* testEscapeToUndo(inspector, view, testActor) { + info("Test that deleting the value removes the property but escape undoes " + + "that"); + + is((yield getStyle(testActor, "#div1", "margin-left")), "20px", + "Should be the right margin-top on the element."); + yield selectNode("#div1", inspector); + + let span = view.doc.querySelector(".boxmodel-margin.boxmodel-left > span"); + is(span.textContent, 20, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "20px", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div1", "margin-left")), "", + "Should have updated the margin."); + + EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is((yield getStyle(testActor, "#div1", "margin-left")), "20px", + "Should be the right margin-top on the element."); + is(span.textContent, 20, "Should have the right value in the box model."); +} + +function* testDeletingValue(inspector, view, testActor) { + info("Test that deleting the value removes the property"); + + yield setStyle(testActor, "#div1", "marginRight", "15px"); + yield waitForUpdate(inspector); + + yield selectNode("#div1", inspector); + + let span = view.doc.querySelector(".boxmodel-margin.boxmodel-right > span"); + is(span.textContent, 15, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "15px", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div1", "margin-right")), "", + "Should have updated the margin."); + + EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView); + + is((yield getStyle(testActor, "#div1", "margin-right")), "", + "Should be the right margin-top on the element."); + is(span.textContent, 10, "Should have the right value in the box model."); +} + +function* testRefocusingOnClick(inspector, view, testActor) { + info("Test that clicking in the editor input does not remove focus"); + + yield selectNode("#div4", inspector); + + let span = view.doc.querySelector(".boxmodel-margin.boxmodel-top > span"); + is(span.textContent, 1, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + + info("Click in the already opened editor input"); + EventUtils.synthesizeMouseAtCenter(editor, {}, view.doc.defaultView); + is(editor, view.doc.activeElement, + "Inplace editor input should still have focus."); + + info("Check the input can still be used as expected"); + EventUtils.synthesizeKey("VK_UP", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "2px", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div4", "margin-top")), "2px", + "Should have updated the margin."); + EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView); + + is((yield getStyle(testActor, "#div4", "margin-top")), "2px", + "Should be the right margin-top on the element."); + is(span.textContent, 2, "Should have the right value in the box model."); +} diff --git a/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_allproperties.js b/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_allproperties.js new file mode 100644 index 000000000..464a7b6c5 --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_allproperties.js @@ -0,0 +1,146 @@ +/* vim: set 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 editing box model values when all values are set + +const TEST_URI = "<style>" + + "div { margin: 10px; padding: 3px }" + + "#div1 { margin-top: 5px }" + + "#div2 { border-bottom: 1em solid black; }" + + "#div3 { padding: 2em; }" + + "</style>" + + "<div id='div1'></div><div id='div2'></div><div id='div3'></div>"; + +add_task(function* () { + yield addTab("data:text/html," + encodeURIComponent(TEST_URI)); + let {inspector, view, testActor} = yield openBoxModelView(); + + yield testEditing(inspector, view, testActor); + yield testEditingAndCanceling(inspector, view, testActor); + yield testDeleting(inspector, view, testActor); + yield testDeletingAndCanceling(inspector, view, testActor); +}); + +function* testEditing(inspector, view, testActor) { + info("When all properties are set on the node editing one should work"); + + yield setStyle(testActor, "#div1", "padding", "5px"); + yield waitForUpdate(inspector); + + yield selectNode("#div1", inspector); + + let span = view.doc.querySelector(".boxmodel-padding.boxmodel-bottom > span"); + is(span.textContent, 5, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "5px", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("7", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "7", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div1", "padding-bottom")), "7px", + "Should have updated the padding"); + + EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView); + + is((yield getStyle(testActor, "#div1", "padding-bottom")), "7px", + "Should be the right padding."); + is(span.textContent, 7, "Should have the right value in the box model."); +} + +function* testEditingAndCanceling(inspector, view, testActor) { + info("When all properties are set on the node editing one and then " + + "cancelling with ESCAPE should work"); + + yield setStyle(testActor, "#div1", "padding", "5px"); + yield waitForUpdate(inspector); + + yield selectNode("#div1", inspector); + + let span = view.doc.querySelector(".boxmodel-padding.boxmodel-left > span"); + is(span.textContent, 5, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "5px", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("8", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "8", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div1", "padding-left")), "8px", + "Should have updated the padding"); + + EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is((yield getStyle(testActor, "#div1", "padding-left")), "5px", + "Should be the right padding."); + is(span.textContent, 5, "Should have the right value in the box model."); +} + +function* testDeleting(inspector, view, testActor) { + info("When all properties are set on the node deleting one should work"); + + yield selectNode("#div1", inspector); + + let span = view.doc.querySelector(".boxmodel-padding.boxmodel-left > span"); + is(span.textContent, 5, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "5px", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div1", "padding-left")), "", + "Should have updated the padding"); + + EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView); + + is((yield getStyle(testActor, "#div1", "padding-left")), "", + "Should be the right padding."); + is(span.textContent, 3, "Should have the right value in the box model."); +} + +function* testDeletingAndCanceling(inspector, view, testActor) { + info("When all properties are set on the node deleting one then cancelling " + + "should work"); + + yield setStyle(testActor, "#div1", "padding", "5px"); + yield waitForUpdate(inspector); + + yield selectNode("#div1", inspector); + + let span = view.doc.querySelector(".boxmodel-padding.boxmodel-left > span"); + is(span.textContent, 5, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "5px", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("VK_DELETE", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div1", "padding-left")), "", + "Should have updated the padding"); + + EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is((yield getStyle(testActor, "#div1", "padding-left")), "5px", + "Should be the right padding."); + is(span.textContent, 5, "Should have the right value in the box model."); +} diff --git a/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_bluronclick.js b/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_bluronclick.js new file mode 100644 index 000000000..9e65e4dc7 --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_bluronclick.js @@ -0,0 +1,74 @@ +/* vim: set 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 inplace editors can be blurred by clicking outside of the editor. + +const TEST_URI = + `<style> + #div1 { + margin: 10px; + padding: 3px; + } + </style> + <div id="div1"></div>`; + +add_task(function* () { + // Make sure the toolbox is tall enough to have empty space below the + // boxmodel-container. + yield pushPref("devtools.toolbox.footer.height", 500); + + yield addTab("data:text/html," + encodeURIComponent(TEST_URI)); + let {inspector, view} = yield openBoxModelView(); + + yield selectNode("#div1", inspector); + yield testClickingOutsideEditor(view); + yield testClickingBelowContainer(view); +}); + +function* testClickingOutsideEditor(view) { + info("Test that clicking outside the editor blurs it"); + let span = view.doc.querySelector(".boxmodel-margin.boxmodel-top > span"); + is(span.textContent, 10, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + + info("Click next to the opened editor input."); + let onBlur = once(editor, "blur"); + let rect = editor.getBoundingClientRect(); + EventUtils.synthesizeMouse(editor, rect.width + 10, rect.height / 2, {}, + view.doc.defaultView); + yield onBlur; + + is(view.doc.querySelector(".styleinspector-propertyeditor"), null, + "Inplace editor has been removed."); +} + +function* testClickingBelowContainer(view) { + info("Test that clicking below the box-model container blurs it"); + let span = view.doc.querySelector(".boxmodel-margin.boxmodel-top > span"); + is(span.textContent, 10, "Should have the right value in the box model."); + + info("Test that clicking below the boxmodel-container blurs the opened editor"); + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + + let onBlur = once(editor, "blur"); + let container = view.doc.querySelector("#boxmodel-container"); + // Using getBoxQuads here because getBoundingClientRect (and therefore synthesizeMouse) + // use an erroneous height of ~50px for the boxmodel-container. + let bounds = container.getBoxQuads({relativeTo: view.doc})[0].bounds; + EventUtils.synthesizeMouseAtPoint( + bounds.left + 10, + bounds.top + bounds.height + 10, + {}, view.doc.defaultView); + yield onBlur; + + is(view.doc.querySelector(".styleinspector-propertyeditor"), null, + "Inplace editor has been removed."); +} diff --git a/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_border.js b/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_border.js new file mode 100644 index 000000000..6e9c04b14 --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_border.js @@ -0,0 +1,52 @@ +/* vim: set 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 editing the border value in the box model applies the border style + +const TEST_URI = "<style>" + + "div { margin: 10px; padding: 3px }" + + "#div1 { margin-top: 5px }" + + "#div2 { border-bottom: 1em solid black; }" + + "#div3 { padding: 2em; }" + + "</style>" + + "<div id='div1'></div><div id='div2'></div><div id='div3'></div>"; + +add_task(function* () { + yield addTab("data:text/html," + encodeURIComponent(TEST_URI)); + let {inspector, view, testActor} = yield openBoxModelView(); + + is((yield getStyle(testActor, "#div1", "border-top-width")), "", + "Should have the right border"); + is((yield getStyle(testActor, "#div1", "border-top-style")), "", + "Should have the right border"); + yield selectNode("#div1", inspector); + + let span = view.doc.querySelector(".boxmodel-border.boxmodel-top > span"); + is(span.textContent, 0, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "0", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("1", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "1", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div1", "border-top-width")), "1px", + "Should have the right border"); + is((yield getStyle(testActor, "#div1", "border-top-style")), "solid", + "Should have the right border"); + + EventUtils.synthesizeKey("VK_ESCAPE", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is((yield getStyle(testActor, "#div1", "border-top-width")), "", + "Should be the right padding."); + is((yield getStyle(testActor, "#div1", "border-top-style")), "", + "Should have the right border"); + is(span.textContent, 0, "Should have the right value in the box model."); +}); diff --git a/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_stylerules.js b/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_stylerules.js new file mode 100644 index 000000000..43346fa15 --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_editablemodel_stylerules.js @@ -0,0 +1,113 @@ +/* vim: set 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 units are displayed correctly when editing values in the box model +// and that values are retrieved and parsed correctly from the back-end + +const TEST_URI = "<style>" + + "div { margin: 10px; padding: 3px }" + + "#div1 { margin-top: 5px }" + + "#div2 { border-bottom: 1em solid black; }" + + "#div3 { padding: 2em; }" + + "</style>" + + "<div id='div1'></div><div id='div2'></div><div id='div3'></div>"; + +add_task(function* () { + yield addTab("data:text/html," + encodeURIComponent(TEST_URI)); + let {inspector, view, testActor} = yield openBoxModelView(); + + yield testUnits(inspector, view, testActor); + yield testValueComesFromStyleRule(inspector, view, testActor); + yield testShorthandsAreParsed(inspector, view, testActor); +}); + +function* testUnits(inspector, view, testActor) { + info("Test that entering units works"); + + is((yield getStyle(testActor, "#div1", "padding-top")), "", + "Should have the right padding"); + yield selectNode("#div1", inspector); + + let span = view.doc.querySelector(".boxmodel-padding.boxmodel-top > span"); + is(span.textContent, 3, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "3px", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("1", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + EventUtils.synthesizeKey("e", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is((yield getStyle(testActor, "#div1", "padding-top")), "", + "An invalid value is handled cleanly"); + + EventUtils.synthesizeKey("m", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "1em", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div1", "padding-top")), + "1em", "Should have updated the padding."); + + EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView); + + is((yield getStyle(testActor, "#div1", "padding-top")), "1em", + "Should be the right padding."); + is(span.textContent, 16, "Should have the right value in the box model."); +} + +function* testValueComesFromStyleRule(inspector, view, testActor) { + info("Test that we pick up the value from a higher style rule"); + + is((yield getStyle(testActor, "#div2", "border-bottom-width")), "", + "Should have the right border-bottom-width"); + yield selectNode("#div2", inspector); + + let span = view.doc.querySelector(".boxmodel-border.boxmodel-bottom > span"); + is(span.textContent, 16, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "1em", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("0", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + + is(editor.value, "0", "Should have the right value in the editor."); + is((yield getStyle(testActor, "#div2", "border-bottom-width")), "0px", + "Should have updated the border."); + + EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView); + + is((yield getStyle(testActor, "#div2", "border-bottom-width")), "0px", + "Should be the right border-bottom-width."); + is(span.textContent, 0, "Should have the right value in the box model."); +} + +function* testShorthandsAreParsed(inspector, view, testActor) { + info("Test that shorthand properties are parsed correctly"); + + is((yield getStyle(testActor, "#div3", "padding-right")), "", + "Should have the right padding"); + yield selectNode("#div3", inspector); + + let span = view.doc.querySelector(".boxmodel-padding.boxmodel-right > span"); + is(span.textContent, 32, "Should have the right value in the box model."); + + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + ok(editor, "Should have opened the editor."); + is(editor.value, "2em", "Should have the right value in the editor."); + + EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView); + + is((yield getStyle(testActor, "#div3", "padding-right")), "", + "Should be the right padding."); + is(span.textContent, 32, "Should have the right value in the box model."); +} diff --git a/devtools/client/inspector/components/test/browser_boxmodel_guides.js b/devtools/client/inspector/components/test/browser_boxmodel_guides.js new file mode 100644 index 000000000..612d9ace6 --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_guides.js @@ -0,0 +1,56 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Test that hovering over regions in the box-model shows the highlighter with +// the right options. +// Tests that actually check the highlighter is displayed and correct are in the +// devtools/inspector/test folder. This test only cares about checking that the +// box model view does call the highlighter, and it does so by mocking it. + +const STYLE = "div { position: absolute; top: 50px; left: 50px; " + + "height: 10px; width: 10px; border: 10px solid black; " + + "padding: 10px; margin: 10px;}"; +const HTML = "<style>" + STYLE + "</style><div></div>"; +const TEST_URL = "data:text/html;charset=utf-8," + encodeURIComponent(HTML); + +var highlightedNodeFront, highlighterOptions; + +add_task(function* () { + yield addTab(TEST_URL); + let {toolbox, inspector, view} = yield openBoxModelView(); + yield selectNode("div", inspector); + + // Mock the highlighter by replacing the showBoxModel method. + toolbox.highlighter.showBoxModel = function (nodeFront, options) { + highlightedNodeFront = nodeFront; + highlighterOptions = options; + }; + + let elt = view.doc.getElementById("boxmodel-margins"); + yield testGuideOnLayoutHover(elt, "margin", inspector, view); + + elt = view.doc.getElementById("boxmodel-borders"); + yield testGuideOnLayoutHover(elt, "border", inspector, view); + + elt = view.doc.getElementById("boxmodel-padding"); + yield testGuideOnLayoutHover(elt, "padding", inspector, view); + + elt = view.doc.getElementById("boxmodel-content"); + yield testGuideOnLayoutHover(elt, "content", inspector, view); +}); + +function* testGuideOnLayoutHover(elt, expectedRegion, inspector) { + info("Synthesizing mouseover on the boxmodel-view"); + EventUtils.synthesizeMouse(elt, 2, 2, {type: "mouseover"}, + elt.ownerDocument.defaultView); + + info("Waiting for the node-highlight event from the toolbox"); + yield inspector.toolbox.once("node-highlight"); + + is(highlightedNodeFront, inspector.selection.nodeFront, + "The right nodeFront was highlighted"); + is(highlighterOptions.region, expectedRegion, + "Region " + expectedRegion + " was highlighted"); +} diff --git a/devtools/client/inspector/components/test/browser_boxmodel_rotate-labels-on-sides.js b/devtools/client/inspector/components/test/browser_boxmodel_rotate-labels-on-sides.js new file mode 100644 index 000000000..954cd298b --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_rotate-labels-on-sides.js @@ -0,0 +1,49 @@ +/* vim: set 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 longer values are rotated on the side + +const res1 = [ + {selector: ".boxmodel-margin.boxmodel-top > span", value: 30}, + {selector: ".boxmodel-margin.boxmodel-left > span", value: "auto"}, + {selector: ".boxmodel-margin.boxmodel-bottom > span", value: 30}, + {selector: ".boxmodel-margin.boxmodel-right > span", value: "auto"}, + {selector: ".boxmodel-padding.boxmodel-top > span", value: 20}, + {selector: ".boxmodel-padding.boxmodel-left > span", value: 2000000}, + {selector: ".boxmodel-padding.boxmodel-bottom > span", value: 20}, + {selector: ".boxmodel-padding.boxmodel-right > span", value: 20}, + {selector: ".boxmodel-border.boxmodel-top > span", value: 10}, + {selector: ".boxmodel-border.boxmodel-left > span", value: 10}, + {selector: ".boxmodel-border.boxmodel-bottom > span", value: 10}, + {selector: ".boxmodel-border.boxmodel-right > span", value: 10}, +]; + +const TEST_URI = encodeURIComponent([ + "<style>", + "div { border:10px solid black; padding: 20px 20px 20px 2000000px; " + + "margin: 30px auto; }", + "</style>", + "<div></div>" +].join("")); +const LONG_TEXT_ROTATE_LIMIT = 3; + +add_task(function* () { + yield addTab("data:text/html," + TEST_URI); + let {inspector, view} = yield openBoxModelView(); + yield selectNode("div", inspector); + + for (let i = 0; i < res1.length; i++) { + let elt = view.doc.querySelector(res1[i].selector); + let isLong = elt.textContent.length > LONG_TEXT_ROTATE_LIMIT; + let classList = elt.parentNode.classList; + let canBeRotated = classList.contains("boxmodel-left") || + classList.contains("boxmodel-right"); + let isRotated = classList.contains("boxmodel-rotate"); + + is(canBeRotated && isLong, + isRotated, res1[i].selector + " correctly rotated."); + } +}); diff --git a/devtools/client/inspector/components/test/browser_boxmodel_sync.js b/devtools/client/inspector/components/test/browser_boxmodel_sync.js new file mode 100644 index 000000000..a896bfe06 --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_sync.js @@ -0,0 +1,44 @@ +/* vim: set 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 editing box model syncs with the rule view. + +const TEST_URI = "<p>hello</p>"; + +add_task(function* () { + yield addTab("data:text/html," + encodeURIComponent(TEST_URI)); + let {inspector, view} = yield openBoxModelView(); + + info("When a property is edited, it should sync in the rule view"); + + yield selectNode("p", inspector); + + info("Modify padding-bottom in box model view"); + let span = view.doc.querySelector(".boxmodel-padding.boxmodel-bottom > span"); + EventUtils.synthesizeMouseAtCenter(span, {}, view.doc.defaultView); + let editor = view.doc.querySelector(".styleinspector-propertyeditor"); + + EventUtils.synthesizeKey("7", {}, view.doc.defaultView); + yield waitForUpdate(inspector); + is(editor.value, "7", "Should have the right value in the editor."); + EventUtils.synthesizeKey("VK_RETURN", {}, view.doc.defaultView); + + let onRuleViewRefreshed = once(inspector, "rule-view-refreshed"); + let onRuleViewSelected = once(inspector.sidebar, "ruleview-selected"); + info("Select the rule view and check that the property was synced there"); + let ruleView = selectRuleView(inspector); + + info("Wait for the rule view to be selected"); + yield onRuleViewSelected; + + info("Wait for the rule view to be refreshed"); + yield onRuleViewRefreshed; + ok(true, "The rule view was refreshed"); + + let ruleEditor = getRuleViewRuleEditor(ruleView, 0); + let textProp = ruleEditor.rule.textProps[0]; + is(textProp.value, "7px", "The property has the right value"); +}); diff --git a/devtools/client/inspector/components/test/browser_boxmodel_tooltips.js b/devtools/client/inspector/components/test/browser_boxmodel_tooltips.js new file mode 100644 index 000000000..b65d2446a --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_tooltips.js @@ -0,0 +1,126 @@ +/* vim: set 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 the regions in the box model view have tooltips, and that individual +// values too. Also test that values that are set from a css rule have tooltips +// referencing the rule. + +const TEST_URI = "<style>" + + "#div1 { color: red; margin: 3em; }\n" + + "#div2 { border-bottom: 1px solid black; background: red; }\n" + + "html, body, #div3 { box-sizing: border-box; padding: 0 2em; }" + + "</style>" + + "<div id='div1'></div><div id='div2'></div><div id='div3'></div>"; + +// Test data for the tooltips over individual values. +// Each entry should contain: +// - selector: The selector for the node to be selected before starting to test +// - values: An array containing objects for each of the values that are defined +// by css rules. Each entry should contain: +// - name: the name of the property that is set by the css rule +// - ruleSelector: the selector of the rule +// - styleSheetLocation: the fileName:lineNumber +const VALUES_TEST_DATA = [{ + selector: "#div1", + values: [{ + name: "margin-top", + ruleSelector: "#div1", + styleSheetLocation: "inline:1" + }, { + name: "margin-right", + ruleSelector: "#div1", + styleSheetLocation: "inline:1" + }, { + name: "margin-bottom", + ruleSelector: "#div1", + styleSheetLocation: "inline:1" + }, { + name: "margin-left", + ruleSelector: "#div1", + styleSheetLocation: "inline:1" + }] +}, { + selector: "#div2", + values: [{ + name: "border-bottom-width", + ruleSelector: "#div2", + styleSheetLocation: "inline:2" + }] +}, { + selector: "#div3", + values: [{ + name: "padding-top", + ruleSelector: "html, body, #div3", + styleSheetLocation: "inline:3" + }, { + name: "padding-right", + ruleSelector: "html, body, #div3", + styleSheetLocation: "inline:3" + }, { + name: "padding-bottom", + ruleSelector: "html, body, #div3", + styleSheetLocation: "inline:3" + }, { + name: "padding-left", + ruleSelector: "html, body, #div3", + styleSheetLocation: "inline:3" + }] +}]; + +add_task(function* () { + yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + let {inspector, view} = yield openBoxModelView(); + + info("Checking the regions tooltips"); + + ok(view.doc.querySelector("#boxmodel-margins").hasAttribute("title"), + "The margin region has a tooltip"); + is(view.doc.querySelector("#boxmodel-margins").getAttribute("title"), "margin", + "The margin region has the correct tooltip content"); + + ok(view.doc.querySelector("#boxmodel-borders").hasAttribute("title"), + "The border region has a tooltip"); + is(view.doc.querySelector("#boxmodel-borders").getAttribute("title"), "border", + "The border region has the correct tooltip content"); + + ok(view.doc.querySelector("#boxmodel-padding").hasAttribute("title"), + "The padding region has a tooltip"); + is(view.doc.querySelector("#boxmodel-padding").getAttribute("title"), "padding", + "The padding region has the correct tooltip content"); + + ok(view.doc.querySelector("#boxmodel-content").hasAttribute("title"), + "The content region has a tooltip"); + is(view.doc.querySelector("#boxmodel-content").getAttribute("title"), "content", + "The content region has the correct tooltip content"); + + for (let {selector, values} of VALUES_TEST_DATA) { + info("Selecting " + selector + " and checking the values tooltips"); + yield selectNode(selector, inspector); + + info("Iterate over all values"); + for (let key in view.map) { + if (key === "position") { + continue; + } + + let name = view.map[key].property; + let expectedTooltipData = values.find(o => o.name === name); + let el = view.doc.querySelector(view.map[key].selector); + + ok(el.hasAttribute("title"), "The " + name + " value has a tooltip"); + + if (expectedTooltipData) { + info("The " + name + " value comes from a css rule"); + let expectedTooltip = name + "\n" + expectedTooltipData.ruleSelector + + "\n" + expectedTooltipData.styleSheetLocation; + is(el.getAttribute("title"), expectedTooltip, "The tooltip is correct"); + } else { + info("The " + name + " isn't set by a css rule"); + is(el.getAttribute("title"), name, "The tooltip is correct"); + } + } + } +}); diff --git a/devtools/client/inspector/components/test/browser_boxmodel_update-after-navigation.js b/devtools/client/inspector/components/test/browser_boxmodel_update-after-navigation.js new file mode 100644 index 000000000..cb5960229 --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_update-after-navigation.js @@ -0,0 +1,91 @@ +/* vim: set 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 the box model view continues to work after a page navigation and that +// it also works after going back + +const IFRAME1 = URL_ROOT + "doc_boxmodel_iframe1.html"; +const IFRAME2 = URL_ROOT + "doc_boxmodel_iframe2.html"; + +add_task(function* () { + yield addTab(IFRAME1); + let {inspector, view, testActor} = yield openBoxModelView(); + + yield testFirstPage(inspector, view, testActor); + + info("Navigate to the second page"); + yield testActor.eval(`content.location.href="${IFRAME2}"`); + yield inspector.once("markuploaded"); + + yield testSecondPage(inspector, view, testActor); + + info("Go back to the first page"); + yield testActor.eval("content.history.back();"); + yield inspector.once("markuploaded"); + + yield testBackToFirstPage(inspector, view, testActor); +}); + +function* testFirstPage(inspector, view, testActor) { + info("Test that the box model view works on the first page"); + + info("Selecting the test node"); + yield selectNode("p", inspector); + + info("Checking that the box model view shows the right value"); + let paddingElt = view.doc.querySelector(".boxmodel-padding.boxmodel-top > span"); + is(paddingElt.textContent, "50"); + + info("Listening for box model view changes and modifying the padding"); + let onUpdated = waitForUpdate(inspector); + yield setStyle(testActor, "p", "padding", "20px"); + yield onUpdated; + ok(true, "Box model view got updated"); + + info("Checking that the box model view shows the right value after update"); + is(paddingElt.textContent, "20"); +} + +function* testSecondPage(inspector, view, testActor) { + info("Test that the box model view works on the second page"); + + info("Selecting the test node"); + yield selectNode("p", inspector); + + info("Checking that the box model view shows the right value"); + let sizeElt = view.doc.querySelector(".boxmodel-size > span"); + is(sizeElt.textContent, "100" + "\u00D7" + "100"); + + info("Listening for box model view changes and modifying the size"); + let onUpdated = waitForUpdate(inspector); + yield setStyle(testActor, "p", "width", "200px"); + yield onUpdated; + ok(true, "Box model view got updated"); + + info("Checking that the box model view shows the right value after update"); + is(sizeElt.textContent, "200" + "\u00D7" + "100"); +} + +function* testBackToFirstPage(inspector, view, testActor) { + info("Test that the box model view works on the first page after going back"); + + info("Selecting the test node"); + yield selectNode("p", inspector); + + info("Checking that the box model view shows the right value, which is the" + + "modified value from step one because of the bfcache"); + let paddingElt = view.doc.querySelector(".boxmodel-padding.boxmodel-top > span"); + is(paddingElt.textContent, "20"); + + info("Listening for box model view changes and modifying the padding"); + let onUpdated = waitForUpdate(inspector); + yield setStyle(testActor, "p", "padding", "100px"); + yield onUpdated; + ok(true, "Box model view got updated"); + + info("Checking that the box model view shows the right value after update"); + is(paddingElt.textContent, "100"); +} diff --git a/devtools/client/inspector/components/test/browser_boxmodel_update-after-reload.js b/devtools/client/inspector/components/test/browser_boxmodel_update-after-reload.js new file mode 100644 index 000000000..7fc09bfa3 --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_update-after-reload.js @@ -0,0 +1,40 @@ +/* vim: set 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 the box model view continues to work after the page is reloaded + +add_task(function* () { + yield addTab(URL_ROOT + "doc_boxmodel_iframe1.html"); + let {inspector, view, testActor} = yield openBoxModelView(); + + info("Test that the box model view works on the first page"); + yield assertBoxModelView(inspector, view, testActor); + + info("Reload the page"); + yield testActor.reload(); + yield inspector.once("markuploaded"); + + info("Test that the box model view works on the reloaded page"); + yield assertBoxModelView(inspector, view, testActor); +}); + +function* assertBoxModelView(inspector, view, testActor) { + info("Selecting the test node"); + yield selectNode("p", inspector); + + info("Checking that the box model view shows the right value"); + let paddingElt = view.doc.querySelector(".boxmodel-padding.boxmodel-top > span"); + is(paddingElt.textContent, "50"); + + info("Listening for box model view changes and modifying the padding"); + let onUpdated = waitForUpdate(inspector); + yield setStyle(testActor, "p", "padding", "20px"); + yield onUpdated; + ok(true, "Box model view got updated"); + + info("Checking that the box model view shows the right value after update"); + is(paddingElt.textContent, "20"); +} diff --git a/devtools/client/inspector/components/test/browser_boxmodel_update-in-iframes.js b/devtools/client/inspector/components/test/browser_boxmodel_update-in-iframes.js new file mode 100644 index 000000000..50014ad1c --- /dev/null +++ b/devtools/client/inspector/components/test/browser_boxmodel_update-in-iframes.js @@ -0,0 +1,101 @@ +/* vim: set 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 the box model view for elements within iframes also updates when they +// change + +add_task(function* () { + yield addTab(URL_ROOT + "doc_boxmodel_iframe1.html"); + let {inspector, view, testActor} = yield openBoxModelView(); + + yield testResizingInIframe(inspector, view, testActor); + yield testReflowsAfterIframeDeletion(inspector, view, testActor); +}); + +function* testResizingInIframe(inspector, view, testActor) { + info("Test that resizing an element in an iframe updates its box model"); + + info("Selecting the nested test node"); + yield selectNodeInIframe2("div", inspector); + + info("Checking that the box model view shows the right value"); + let sizeElt = view.doc.querySelector(".boxmodel-size > span"); + is(sizeElt.textContent, "400\u00D7200"); + + info("Listening for box model view changes and modifying its size"); + let onUpdated = waitForUpdate(inspector); + yield setStyleInIframe2(testActor, "div", "width", "200px"); + yield onUpdated; + ok(true, "Box model view got updated"); + + info("Checking that the box model view shows the right value after update"); + is(sizeElt.textContent, "200\u00D7200"); +} + +function* testReflowsAfterIframeDeletion(inspector, view, testActor) { + info("Test reflows are still sent to the box model view after deleting an " + + "iframe"); + + info("Deleting the iframe2"); + yield removeIframe2(testActor); + yield inspector.once("inspector-updated"); + + info("Selecting the test node in iframe1"); + yield selectNodeInIframe1("p", inspector); + + info("Checking that the box model view shows the right value"); + let sizeElt = view.doc.querySelector(".boxmodel-size > span"); + is(sizeElt.textContent, "100\u00D7100"); + + info("Listening for box model view changes and modifying its size"); + let onUpdated = waitForUpdate(inspector); + yield setStyleInIframe1(testActor, "p", "width", "200px"); + yield onUpdated; + ok(true, "Box model view got updated"); + + info("Checking that the box model view shows the right value after update"); + is(sizeElt.textContent, "200\u00D7100"); +} + +function* selectNodeInIframe1(selector, inspector) { + let iframe1 = yield getNodeFront("iframe", inspector); + let node = yield getNodeFrontInFrame(selector, iframe1, inspector); + yield selectNode(node, inspector); +} + +function* selectNodeInIframe2(selector, inspector) { + let iframe1 = yield getNodeFront("iframe", inspector); + let iframe2 = yield getNodeFrontInFrame("iframe", iframe1, inspector); + let node = yield getNodeFrontInFrame(selector, iframe2, inspector); + yield selectNode(node, inspector); +} + +function* setStyleInIframe1(testActor, selector, propertyName, value) { + yield testActor.eval(` + content.document.querySelector("iframe") + .contentDocument.querySelector("${selector}") + .style.${propertyName} = "${value}"; + `); +} + +function* setStyleInIframe2(testActor, selector, propertyName, value) { + yield testActor.eval(` + content.document.querySelector("iframe") + .contentDocument + .querySelector("iframe") + .contentDocument.querySelector("${selector}") + .style.${propertyName} = "${value}"; + `); +} + +function* removeIframe2(testActor) { + yield testActor.eval(` + content.document.querySelector("iframe") + .contentDocument + .querySelector("iframe") + .remove(); + `); +} diff --git a/devtools/client/inspector/components/test/doc_boxmodel_iframe1.html b/devtools/client/inspector/components/test/doc_boxmodel_iframe1.html new file mode 100644 index 000000000..eef48ce07 --- /dev/null +++ b/devtools/client/inspector/components/test/doc_boxmodel_iframe1.html @@ -0,0 +1,3 @@ +<!DOCTYPE html> +<p style="padding:50px;color:#f06;">Root page</p> +<iframe src="doc_boxmodel_iframe2.html"></iframe> diff --git a/devtools/client/inspector/components/test/doc_boxmodel_iframe2.html b/devtools/client/inspector/components/test/doc_boxmodel_iframe2.html new file mode 100644 index 000000000..1f1b0463c --- /dev/null +++ b/devtools/client/inspector/components/test/doc_boxmodel_iframe2.html @@ -0,0 +1,3 @@ +<!DOCTYPE html> +<p style="width:100px;height:100px;background:red;">iframe 1</p> +<iframe src="data:text/html,<div style='width:400px;height:200px;background:yellow;'>iframe 2</div>"></iframe> diff --git a/devtools/client/inspector/components/test/head.js b/devtools/client/inspector/components/test/head.js new file mode 100644 index 000000000..fa86b5e9e --- /dev/null +++ b/devtools/client/inspector/components/test/head.js @@ -0,0 +1,87 @@ +/* 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/ */ +/* eslint no-unused-vars: [2, {"vars": "local"}] */ +/* import-globals-from ../../../framework/test/shared-head.js */ +/* import-globals-from ../../test/head.js */ +"use strict"; + +// 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); + +Services.prefs.setIntPref("devtools.toolbox.footer.height", 350); +registerCleanupFunction(() => { + Services.prefs.clearUserPref("devtools.toolbox.footer.height"); +}); + +/** + * Highlight a node and set the inspector's current selection to the node or + * the first match of the given css selector. + * @param {String|NodeFront} selectorOrNodeFront + * The selector for the node to be set, or the nodeFront + * @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 + */ +function* selectAndHighlightNode(selectorOrNodeFront, inspector) { + info("Highlighting and selecting the node " + selectorOrNodeFront); + + let nodeFront = yield getNodeFront(selectorOrNodeFront, inspector); + let updated = inspector.toolbox.once("highlighter-ready"); + inspector.selection.setNodeFront(nodeFront, "test-highlight"); + yield updated; +} + +/** + * Open the toolbox, with the inspector tool visible, and the computed view + * sidebar tab selected to display the box model view. + * @return a promise that resolves when the inspector is ready and the box model + * view is visible and ready + */ +function openBoxModelView() { + return openInspectorSidebarTab("computedview").then(data => { + // The actual highligher show/hide methods are mocked in box model tests. + // The highlighter is tested in devtools/inspector/test. + function mockHighlighter({highlighter}) { + highlighter.showBoxModel = function () { + return promise.resolve(); + }; + highlighter.hideBoxModel = function () { + return promise.resolve(); + }; + } + mockHighlighter(data.toolbox); + + return { + toolbox: data.toolbox, + inspector: data.inspector, + view: data.inspector.computedview.boxModelView, + testActor: data.testActor + }; + }); +} + +/** + * Wait for the boxmodel-view-updated event. + * @return a promise + */ +function waitForUpdate(inspector) { + return inspector.once("boxmodel-view-updated"); +} + +function getStyle(testActor, selector, propertyName) { + return testActor.eval(` + content.document.querySelector("${selector}") + .style.getPropertyValue("${propertyName}"); + `); +} + +function setStyle(testActor, selector, propertyName, value) { + return testActor.eval(` + content.document.querySelector("${selector}") + .style.${propertyName} = "${value}"; + `); +} |