Bug 968727 - Move common test runner parts in external helper files. r=bgrins, a=test-only
authorPatrick Brosset <pbrosset@mozilla.com>
Wed, 26 Mar 2014 14:38:06 +0100
changeset 192932 a1a02bbf28e9373b80d196576281199b1f2b15d4
parent 192931 4c267ebca47de79eb5d237c9b44d9c9588dec70a
child 192933 d429abe1d569266e5fc8737edce7d52b28364d98
push id474
push userasasaki@mozilla.com
push dateMon, 02 Jun 2014 21:01:02 +0000
treeherdermozilla-release@967f4cf1b31c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgrins, test-only
bugs968727
milestone30.0a2
Bug 968727 - Move common test runner parts in external helper files. r=bgrins, a=test-only
browser/devtools/markupview/test/browser.ini
browser/devtools/markupview/test/browser_markupview_copy_image_data.js
browser/devtools/markupview/test/browser_markupview_css_completion_style_attribute.js
browser/devtools/markupview/test/browser_markupview_highlight_hover_01.js
browser/devtools/markupview/test/browser_markupview_highlight_hover_02.js
browser/devtools/markupview/test/browser_markupview_html_edit_01.js
browser/devtools/markupview/test/browser_markupview_html_edit_02.js
browser/devtools/markupview/test/browser_markupview_html_edit_03.js
browser/devtools/markupview/test/browser_markupview_image_tooltip.js
browser/devtools/markupview/test/browser_markupview_mutation_01.js
browser/devtools/markupview/test/browser_markupview_mutation_02.js
browser/devtools/markupview/test/browser_markupview_navigation.js
browser/devtools/markupview/test/browser_markupview_pagesize_01.js
browser/devtools/markupview/test/browser_markupview_pagesize_02.js
browser/devtools/markupview/test/browser_markupview_search_01.js
browser/devtools/markupview/test/browser_markupview_tag_edit_01.js
browser/devtools/markupview/test/browser_markupview_tag_edit_05.js
browser/devtools/markupview/test/browser_markupview_tag_edit_06.js
browser/devtools/markupview/test/browser_markupview_tag_edit_07.js
browser/devtools/markupview/test/head.js
browser/devtools/markupview/test/helper_attributes_test_runner.js
browser/devtools/markupview/test/helper_outerhtml_test_runner.js
--- a/browser/devtools/markupview/test/browser.ini
+++ b/browser/devtools/markupview/test/browser.ini
@@ -5,16 +5,18 @@ support-files =
   doc_markup_flashing.html
   doc_markup_mutation.html
   doc_markup_navigation.html
   doc_markup_pagesize_01.html
   doc_markup_pagesize_02.html
   doc_markup_search.html
   doc_markup_tooltip.png
   head.js
+  helper_attributes_test_runner.js
+  helper_outerhtml_test_runner.js
 
 [browser_markupview_copy_image_data.js]
 [browser_markupview_css_completion_style_attribute.js]
 [browser_markupview_highlight_hover_01.js]
 [browser_markupview_highlight_hover_02.js]
 [browser_markupview_html_edit_01.js]
 [browser_markupview_html_edit_02.js]
 [browser_markupview_html_edit_03.js]
--- a/browser/devtools/markupview/test/browser_markupview_copy_image_data.js
+++ b/browser/devtools/markupview/test/browser_markupview_copy_image_data.js
@@ -1,12 +1,14 @@
 /* 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 image nodes have the "copy data-uri" contextual menu item enabled
 // and that clicking it puts the image data into the clipboard
 
 const PAGE_CONTENT = [
   '<div></div>',
   '<img class="data" src="data:image/png;base64,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" />',
   '<canvas class="canvas" width="600" height="600"></canvas>'
 ].join("\n");
--- a/browser/devtools/markupview/test/browser_markupview_css_completion_style_attribute.js
+++ b/browser/devtools/markupview/test/browser_markupview_css_completion_style_attribute.js
@@ -1,11 +1,13 @@
 /* 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 CSS state is correctly determined and the corresponding suggestions are
 // displayed. i.e. CSS property suggestions are shown when cursor is like:
 // ```style="di|"``` where | is the cursor; And CSS value suggestion is
 // displayed when the cursor is like: ```style="display:n|"``` properly. No
 // suggestions should ever appear when the attribute is not a style attribute.
 // The correctness and cycling of the suggestions is covered in the ruleview
 // tests.
--- a/browser/devtools/markupview/test/browser_markupview_highlight_hover_01.js
+++ b/browser/devtools/markupview/test/browser_markupview_highlight_hover_01.js
@@ -1,12 +1,14 @@
 /* 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 when first hovering over a node and immediately after selecting it
 // by clicking on it leaves the highlighter visible for as long as the mouse is
 // over the node
 
 let test = asyncTest(function*() {
   let {inspector} = yield addTab("data:text/html,<p>It's going to be legen....</p>").then(openInspector);
   let p = getNode("p");
 
--- a/browser/devtools/markupview/test/browser_markupview_highlight_hover_02.js
+++ b/browser/devtools/markupview/test/browser_markupview_highlight_hover_02.js
@@ -1,12 +1,14 @@
 /* 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 when after an element is selected and highlighted on hover, if the
 // mouse leaves the markup-view and comes back again on the same element, that
 // the highlighter is shown again on the node
 
 let test = asyncTest(function*() {
   let {inspector} = yield addTab("data:text/html,<p>Select me!</p>").then(openInspector);
 
   info("hover over the <p> line in the markup-view so that it's the currently hovered node");
--- a/browser/devtools/markupview/test/browser_markupview_html_edit_01.js
+++ b/browser/devtools/markupview/test/browser_markupview_html_edit_01.js
@@ -1,14 +1,18 @@
 /* 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 outerHTML edition via the markup-view
 
+loadHelperScript("helper_outerhtml_test_runner.js");
+
 const TEST_DATA = [
   {
     selector: "#one",
     oldHTML: '<div id="one">First <em>Div</em></div>',
     newHTML: '<div id="one">First Div</div>',
     validate: function(pageNode, selectedNode) {
       is(pageNode.textContent, "First Div", "New div has expected text content");
       ok(!getNode("#one em"), "No em remaining")
--- a/browser/devtools/markupview/test/browser_markupview_html_edit_02.js
+++ b/browser/devtools/markupview/test/browser_markupview_html_edit_02.js
@@ -1,14 +1,18 @@
 /* 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 outerHTML edition via the markup-view
 
+loadHelperScript("helper_outerhtml_test_runner.js");
+
 const TEST_DATA = [
   {
     selector: "#badMarkup1",
     oldHTML: '<div id="badMarkup1">badMarkup1</div>',
     newHTML: '<div id="badMarkup1">badMarkup1</div> hanging</div>',
     validate: function(pageNode, selectedNode) {
       is(pageNode, selectedNode, "Original element is selected");
 
--- a/browser/devtools/markupview/test/browser_markupview_html_edit_03.js
+++ b/browser/devtools/markupview/test/browser_markupview_html_edit_03.js
@@ -1,12 +1,14 @@
 /* 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 outerHTML editing keybindings work as expected and that *special*
 // elements like <html>, <body> and <head> can be edited correctly.
 
 const TEST_URL = "data:text/html," +
   "<!DOCTYPE html>" +
   "<head><meta charset='utf-8' /></head>" +
   "<body>" +
   "<div id=\"keyboard\"></div>" +
--- a/browser/devtools/markupview/test/browser_markupview_image_tooltip.js
+++ b/browser/devtools/markupview/test/browser_markupview_image_tooltip.js
@@ -1,12 +1,14 @@
 /* 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 image preview tooltips are shown on img and canvas tags in the
 // markup-view and that the tooltip actually contains an image and shows the
 // right dimension label
 
 const PAGE_CONTENT = [
   '<img class="local" src="chrome://branding/content/about-logo.png" />',
   '<img class="data" src="data:image/png;base64,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" />',
   '<img class="remote" src="' + TEST_URL_ROOT + 'doc_markup_tooltip.png" />',
--- a/browser/devtools/markupview/test/browser_markupview_mutation_01.js
+++ b/browser/devtools/markupview/test/browser_markupview_mutation_01.js
@@ -1,20 +1,20 @@
 /* vim: set ts=2 et sw=2 tw=80: */
 /* Any copyright is dedicated to the Public Domain.
  http://creativecommons.org/publicdomain/zero/1.0/ */
 
-/**
- * Tests that various mutations to the dom update the markup view correctly.
- * The test for comparing the markup view to the real dom is a bit weird:
- * - Select the text in the markup view
- * - Parse that as innerHTML in a document we've created for the purpose.
- * - Remove extraneous whitespace in that tree
- * - Compare it to the real dom with isEqualNode.
- */
+"use strict";
+
+// Tests that various mutations to the dom update the markup view correctly.
+// The test for comparing the markup view to the real dom is a bit weird:
+// - Select the text in the markup view
+// - Parse that as innerHTML in a document we've created for the purpose.
+// - Remove extraneous whitespace in that tree
+// - Compare it to the real dom with isEqualNode.
 
 const TEST_URL = TEST_URL_ROOT + "doc_markup_mutation.html";
 // All the mutation types we want to test.
 const TEST_DATA = [
   {
     desc: "Adding an attribute",
     test: () => {
       let node1 = getNode("#node1");
--- a/browser/devtools/markupview/test/browser_markupview_mutation_02.js
+++ b/browser/devtools/markupview/test/browser_markupview_mutation_02.js
@@ -1,12 +1,14 @@
 /* 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 markup-containers in the markup-view do flash when their
 // corresponding DOM nodes mutate
 
 const TEST_URL = TEST_URL_ROOT + "doc_markup_flashing.html";
 // The test data contains a list of mutations to test.
 // Each item is an object:
 // - desc: a description of the test step, for better logging
 // - mutate: a function that should make changes to the content DOM
--- a/browser/devtools/markupview/test/browser_markupview_navigation.js
+++ b/browser/devtools/markupview/test/browser_markupview_navigation.js
@@ -1,12 +1,14 @@
 /* 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 markup-view nodes can be navigated to with the keyboard
 
 const TEST_URL = TEST_URL_ROOT + "doc_markup_navigation.html";
 const TEST_DATA = [
   ["pageup", "*doctype*"],
   ["down", "html"],
   ["down", "head"],
   ["down", "body"],
--- a/browser/devtools/markupview/test/browser_markupview_pagesize_01.js
+++ b/browser/devtools/markupview/test/browser_markupview_pagesize_01.js
@@ -1,12 +1,14 @@
 /* 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";
+
 // Tests that the markup view loads only as many nodes as specified by the
 // devtools.markup.pagesize preference.
 
 Services.prefs.setIntPref("devtools.markup.pagesize", 5);
 
 const TEST_URL = TEST_URL_ROOT + "doc_markup_pagesize_01.html";
 const TEST_DATA = [{
   desc: "Select the last item",
--- a/browser/devtools/markupview/test/browser_markupview_pagesize_02.js
+++ b/browser/devtools/markupview/test/browser_markupview_pagesize_02.js
@@ -1,12 +1,14 @@
 /* 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";
+
 // Tests that the markup view loads only as many nodes as specified
 // by the devtools.markup.pagesize preference and that pressing the "show all nodes"
 // actually shows the nodes
 
 const TEST_URL = TEST_URL_ROOT + "doc_markup_pagesize_02.html";
 
 // Make sure nodes are hidden when there are more than 5 in a row
 Services.prefs.setIntPref("devtools.markup.pagesize", 5);
--- a/browser/devtools/markupview/test/browser_markupview_search_01.js
+++ b/browser/devtools/markupview/test/browser_markupview_search_01.js
@@ -1,12 +1,14 @@
 /* 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 searching for nodes using the selector-search input expands and
 // selects the right nodes in the markup-view, even when those nodes are deeply
 // nested (and therefore not attached yet when the markup-view is initialized).
 
 const TEST_URL = TEST_URL_ROOT + "doc_markup_search.html";
 
 let test = asyncTest(function*() {
   let {inspector, toolbox} = yield addTab(TEST_URL).then(openInspector);
--- a/browser/devtools/markupview/test/browser_markupview_tag_edit_01.js
+++ b/browser/devtools/markupview/test/browser_markupview_tag_edit_01.js
@@ -1,16 +1,18 @@
 /* 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 various markup-containers' attribute fields
 
+loadHelperScript("helper_attributes_test_runner.js");
+
 const TEST_URL = TEST_URL_ROOT + "doc_markup_edit.html";
 let TEST_DATA = [{
   desc: "Change an attribute",
   node: "#node1",
   originalAttributes: {
     id: "node1",
     class: "node1"
   },
--- a/browser/devtools/markupview/test/browser_markupview_tag_edit_05.js
+++ b/browser/devtools/markupview/test/browser_markupview_tag_edit_05.js
@@ -1,22 +1,23 @@
-/* Any copyright", " is dedicated to the Public Domain.
-http://creativecommons.org/publicdomain/zero/1.0/ */
+/* 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";
 
-/**
- * Tests that adding various types of attributes to nodes in the markup-view
- * works as expected. Also checks that the changes are properly undoable and
- * redoable. For each step in the test, we:
- * - Create a new DIV
- * - Make the change, check that the change was made as we expect
- * - Undo the change, check that the node is back in its original state
- * - Redo the change, check that the node change was made again correctly.
- */
+// Tests that adding various types of attributes to nodes in the markup-view
+// works as expected. Also checks that the changes are properly undoable and
+// redoable. For each step in the test, we:
+// - Create a new DIV
+// - Make the change, check that the change was made as we expect
+// - Undo the change, check that the node is back in its original state
+// - Redo the change, check that the node change was made again correctly.
+
+loadHelperScript("helper_attributes_test_runner.js");
 
 let TEST_URL = "data:text/html,<div>markup-view attributes addition test</div>";
 let TEST_DATA = [{
   desc: "Add an attribute value without closing \"",
   text: 'style="display: block;',
   expectedAttributes: {
     style: "display: block;"
   }
--- a/browser/devtools/markupview/test/browser_markupview_tag_edit_06.js
+++ b/browser/devtools/markupview/test/browser_markupview_tag_edit_06.js
@@ -1,22 +1,23 @@
-/* Any copyright", " is dedicated to the Public Domain.
-http://creativecommons.org/publicdomain/zero/1.0/ */
+/* 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";
 
-/**
- * Tests that adding various types of attributes to nodes in the markup-view
- * works as expected. Also checks that the changes are properly undoable and
- * redoable. For each step in the test, we:
- * - Create a new DIV
- * - Make the change, check that the change was made as we expect
- * - Undo the change, check that the node is back in its original state
- * - Redo the change, check that the node change was made again correctly.
- */
+// Tests that adding various types of attributes to nodes in the markup-view
+// works as expected. Also checks that the changes are properly undoable and
+// redoable. For each step in the test, we:
+// - Create a new DIV
+// - Make the change, check that the change was made as we expect
+// - Undo the change, check that the node is back in its original state
+// - Redo the change, check that the node change was made again correctly.
+
+loadHelperScript("helper_attributes_test_runner.js");
 
 let TEST_URL = "data:text/html,<div>markup-view attributes addition test</div>";
 let TEST_DATA = [{
   desc: "Mixed single and double quotes",
   text: "name=\"hi\" maxlength='not a number'",
   expectedAttributes: {
     maxlength: "not a number",
     name: "hi"
--- a/browser/devtools/markupview/test/browser_markupview_tag_edit_07.js
+++ b/browser/devtools/markupview/test/browser_markupview_tag_edit_07.js
@@ -1,16 +1,19 @@
-/* Any copyright", " is dedicated to the Public Domain.
-http://creativecommons.org/publicdomain/zero/1.0/ */
+/* 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";
 
 // One more test testing various add-attributes configurations
 // Some of the test data below asserts that long attributes get collapsed
 
+loadHelperScript("helper_attributes_test_runner.js");
+
 const LONG_ATTRIBUTE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ-ABCDEFGHIJKLMNOPQRSTUVWXYZ-ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ-ABCDEFGHIJKLMNOPQRSTUVWXYZ-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 const LONG_ATTRIBUTE_COLLAPSED = "ABCDEFGHIJKLMNOPQRSTUVWXYZ-ABCDEFGHIJKLMNOPQRSTUVWXYZ-ABCDEF\u2026UVWXYZ-ABCDEFGHIJKLMNOPQRSTUVWXYZ-ABCDEFGHIJKLMNOPQRSTUVWXYZ";
 const DATA_URL_INLINE_STYLE='color: red; background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC");';
 const DATA_URL_INLINE_STYLE_COLLAPSED='color: red; background: url("data:image/png;base64,iVBORw0KG\u2026NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC");';
 const DATA_URL_ATTRIBUTE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAABlBMVEUAAAD///+l2Z/dAAAAM0lEQVR4nGP4/5/h/1+G/58ZDrAz3D/McH8yw83NDDeNGe4Ug9C9zwz3gVLMDA/A6P9/AFGGFyjOXZtQAAAAAElFTkSuQmCC";
 const DATA_URL_ATTRIBUTE_COLLAPSED = "data:image/png;base64,iVBORw0K\u20269/AFGGFyjOXZtQAAAAAElFTkSuQmCC";
 
 let TEST_URL = "data:text/html,<div>markup-view attributes addition test</div>";
--- a/browser/devtools/markupview/test/head.js
+++ b/browser/devtools/markupview/test/head.js
@@ -67,16 +67,32 @@ function addTab(url) {
     }, content);
   }, true);
   content.location = url;
 
   return def.promise;
 }
 
 /**
+ * Some tests may need to import one or more of the test helper scripts.
+ * A test helper script is simply a js file that contains common test code that
+ * is either not common-enough to be in head.js, or that is located in a separate
+ * directory.
+ * The script will be loaded synchronously and in the test's scope.
+ * @param {String} filePath The file path, relative to the current directory.
+ *                 Examples:
+ *                 - "helper_attributes_test_runner.js"
+ *                 - "../../../commandline/test/helpers.js"
+ */
+function loadHelperScript(filePath) {
+  let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
+  Services.scriptloader.loadSubScript(testDir + "/" + filePath, this);
+}
+
+/**
  * Reload the current page
  * @return a promise that resolves when the inspector has emitted the event
  * new-root
  */
 function reloadPage(inspector) {
   info("Reloading the page");
   let newRoot = inspector.once("new-root");
   content.location.reload();
@@ -331,234 +347,8 @@ function getSelectorSearchBox(inspector)
  */
 function searchUsingSelectorSearch(selector, inspector) {
   info("Entering \"" + selector + "\" into the selector-search input field");
   let field = getSelectorSearchBox(inspector);
   field.focus();
   field.value = selector;
   EventUtils.sendKey("return", inspector.panelWin);
 }
-
-/**
- * Run a series of add-attributes tests.
- * This function will iterate over the provided tests array and run each test.
- * Each test's goal is to provide some text to be entered into the test node's
- * new-attribute field and check that the given attributes have been created.
- * After each test has run, the markup-view's undo command will be called and
- * the test runner will check if all the new attributes are gone.
- * @param {Array} tests See runAddAttributesTest for the structure
- * @param {DOMNode|String} nodeOrSelector The node or node selector
- * corresponding to an element on the current test page that has *no attributes*
- * when the test starts. It will be used to add and remove attributes.
- * @param {InspectorPanel} inspector The instance of InspectorPanel currently
- * opened
- * @return a promise that resolves when the tests have run
- */
-function runAddAttributesTests(tests, nodeOrSelector, inspector) {
-  info("Running " + tests.length + " add-attributes tests");
-  return Task.spawn(function*() {
-    info("Selecting the test node");
-    let div = getNode("div");
-    yield selectNode(div, inspector);
-
-    for (let test of tests) {
-      yield runAddAttributesTest(test, div, inspector);
-    }
-
-    yield inspector.once("inspector-updated");
-  });
-}
-
-/**
- * Run a single add-attribute test.
- * See runAddAttributesTests for a description.
- * @param {Object} test A test object should contain the following properties:
- *        - desc {String} a textual description for that test, to help when
- *        reading logs
- *        - text {String} the string to be inserted into the new attribute field
- *        - expectedAttributes {Object} a key/value pair object that will be
- *        used to check the attributes on the test element
- *        - validate {Function} optional extra function that will be called after
- *        the attributes have been added and which should be used to assert some
- *        more things this test runner might not be checking. The function will
- *        be called with the following arguments:
- *          - {DOMNode} The element being tested
- *          - {MarkupContainer} The corresponding container in the markup-view
- *          - {InspectorPanel} The instance of the InspectorPanel opened
- * @param {DOMNode|String} nodeOrSelector The node or node selector
- * corresponding to the test element
- * @param {InspectorPanel} inspector The instance of InspectorPanel currently
- * opened
- */
-function* runAddAttributesTest(test, nodeOrSelector, inspector) {
-  let element = getNode(nodeOrSelector);
-
-  info("Starting add-attribute test: " + test.desc);
-  yield addNewAttributes(element, test.text, inspector);
-
-  info("Assert that the attribute(s) has/have been applied correctly");
-  assertAttributes(element, test.expectedAttributes);
-
-  if (test.validate) {
-    test.validate(element, getContainerForRawNode(element, inspector), inspector);
-  }
-
-  info("Undo the change");
-  yield undoChange(inspector);
-
-  info("Assert that the attribute(s) has/have been removed correctly");
-  assertAttributes(element, {});
-}
-
-/**
- * Run a series of edit-attributes tests.
- * This function will iterate over the provided tests array and run each test.
- * Each test's goal is to locate a given element on the current test page, assert
- * its current attributes, then provide the name of one of them and a value to
- * be set into it, and then check if the new attributes are correct.
- * After each test has run, the markup-view's undo and redo commands will be
- * called and the test runner will assert again that the attributes are correct.
- * @param {Array} tests See runEditAttributesTest for the structure
- * @param {InspectorPanel} inspector The instance of InspectorPanel currently
- * opened
- * @return a promise that resolves when the tests have run
- */
-function runEditAttributesTests(tests, inspector) {
-  info("Running " + tests.length + " edit-attributes tests");
-  return Task.spawn(function*() {
-    info("Expanding all nodes in the markup-view");
-    yield inspector.markup.expandAll();
-
-    for (let test of tests) {
-      yield runEditAttributesTest(test, inspector);
-    }
-
-    yield inspector.once("inspector-updated");
-  });
-}
-
-/**
- * Run a single edit-attribute test.
- * See runEditAttributesTests for a description.
- * @param {Object} test A test object should contain the following properties:
- *        - desc {String} a textual description for that test, to help when
- *        reading logs
- *        - node {String} a css selector that will be used to select the node
- *        which will be tested during this iteration
- *        - originalAttributes {Object} a key/value pair object that will be
- *        used to check the attributes of the node before the test runs
- *        - name {String} the name of the attribute to focus the editor for
- *        - value {String} the new value to be typed in the focused editor
- *        - expectedAttributes {Object} a key/value pair object that will be
- *        used to check the attributes on the test element
- * @param {InspectorPanel} inspector The instance of InspectorPanel currently
- * opened
- */
-function* runEditAttributesTest(test, inspector) {
-  info("Starting edit-attribute test: " + test.desc);
-
-  info("Selecting the test node " + test.node);
-  yield selectNode(test.node, inspector);
-
-  info("Asserting that the node has the right attributes to start with");
-  assertAttributes(test.node, test.originalAttributes);
-
-  info("Editing attribute " + test.name + " with value " + test.value);
-
-  let container = getContainerForRawNode(test.node, inspector);
-  ok(container && container.editor, "The markup-container for " + test.node +
-    " was found");
-
-  info("Listening for the markupmutation event");
-  let nodeMutated = inspector.once("markupmutation");
-  let attr = container.editor.attrs[test.name].querySelector(".editable");
-  setEditableFieldValue(attr, test.value, inspector);
-  yield nodeMutated;
-
-  info("Asserting the new attributes after edition");
-  assertAttributes(test.node, test.expectedAttributes);
-
-  info("Undo the change and assert that the attributes have been changed back");
-  yield undoChange(inspector);
-  assertAttributes(test.node, test.originalAttributes);
-
-  info("Redo the change and assert that the attributes have been changed again");
-  yield redoChange(inspector);
-  assertAttributes(test.node, test.expectedAttributes);
-}
-
-/**
- * Run a series of edit-outer-html tests.
- * This function will iterate over the provided tests array and run each test.
- * Each test's goal is to provide a node (a selector) and a new outer-HTML to be
- * inserted in place of the current one for that node.
- * This test runner will wait for the mutation event to be fired and will check
- * a few things. Each test may also provide its own validate function to perform
- * assertions and verify that the new outer html is correct.
- * @param {Array} tests See runEditOuterHTMLTest for the structure
- * @param {InspectorPanel} inspector The instance of InspectorPanel currently
- * opened
- * @return a promise that resolves when the tests have run
- */
-function runEditOuterHTMLTests(tests, inspector) {
-  info("Running " + tests.length + " edit-outer-html tests");
-  return Task.spawn(function* () {
-    for (let step of TEST_DATA) {
-      yield runEditOuterHTMLTest(step, inspector);
-    }
-  });
-}
-
-/**
- * Run a single edit-outer-html test.
- * See runEditOuterHTMLTests for a description.
- * @param {Object} test A test object should contain the following properties:
- *        - selector {String} a css selector targeting the node to edit
- *        - oldHTML {String}
- *        - newHTML {String}
- *        - validate {Function} will be executed when the edition test is done,
- *        after the new outer-html has been inserted. Should be used to verify
- *        the actual DOM, see if it corresponds to the newHTML string provided
- * @param {InspectorPanel} inspector The instance of InspectorPanel currently
- * opened
- */
-function* runEditOuterHTMLTest(test, inspector) {
-  info("Running an edit outerHTML test on '" + test.selector + "'");
-  yield selectNode(test.selector, inspector);
-  let oldNodeFront = inspector.selection.nodeFront;
-
-  info("Listening for the markupmutation event");
-  // This event fires once the outerHTML is set, with a target as the parent node and a type of "childList".
-  let mutated = inspector.once("markupmutation");
-  info("Editing the outerHTML");
-  inspector.markup.updateNodeOuterHTML(inspector.selection.nodeFront, test.newHTML, test.oldHTML);
-  let mutations = yield mutated;
-  ok(true, "The markupmutation event has fired, mutation done");
-
-  info("Check to make the sure the correct mutation event was fired, and that the parent is selected");
-  let nodeFront = inspector.selection.nodeFront;
-  let mutation = mutations[0];
-  let isFromOuterHTML = mutation.removed.some(n => n === oldNodeFront);
-
-  ok(isFromOuterHTML, "The node is in the 'removed' list of the mutation");
-  is(mutation.type, "childList", "Mutation is a childList after updating outerHTML");
-  is(mutation.target, nodeFront, "Parent node is selected immediately after setting outerHTML");
-
-  // Wait for node to be reselected after outerHTML has been set
-  yield inspector.selection.once("new-node");
-
-  // Typically selectedNode will === pageNode, but if a new element has been injected in front
-  // of it, this will not be the case.  If this happens.
-  let selectedNode = inspector.selection.node;
-  let nodeFront = inspector.selection.nodeFront;
-  let pageNode = getNode(test.selector);
-
-  if (test.validate) {
-    test.validate(pageNode, selectedNode);
-  } else {
-    is(pageNode, selectedNode, "Original node (grabbed by selector) is selected");
-    is(pageNode.outerHTML, test.newHTML, "Outer HTML has been updated");
-  }
-
-  // Wait for the inspector to be fully updated to avoid causing errors by
-  // abruptly closing hanging requests when the test ends
-  yield inspector.once("inspector-updated");
-}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/markupview/test/helper_attributes_test_runner.js
@@ -0,0 +1,151 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Run a series of add-attributes tests.
+ * This function will iterate over the provided tests array and run each test.
+ * Each test's goal is to provide some text to be entered into the test node's
+ * new-attribute field and check that the given attributes have been created.
+ * After each test has run, the markup-view's undo command will be called and
+ * the test runner will check if all the new attributes are gone.
+ * @param {Array} tests See runAddAttributesTest for the structure
+ * @param {DOMNode|String} nodeOrSelector The node or node selector
+ * corresponding to an element on the current test page that has *no attributes*
+ * when the test starts. It will be used to add and remove attributes.
+ * @param {InspectorPanel} inspector The instance of InspectorPanel currently
+ * opened
+ * @return a promise that resolves when the tests have run
+ */
+function runAddAttributesTests(tests, nodeOrSelector, inspector) {
+  info("Running " + tests.length + " add-attributes tests");
+  return Task.spawn(function*() {
+    info("Selecting the test node");
+    let div = getNode("div");
+    yield selectNode(div, inspector);
+
+    for (let test of tests) {
+      yield runAddAttributesTest(test, div, inspector);
+    }
+
+    yield inspector.once("inspector-updated");
+  });
+}
+
+/**
+ * Run a single add-attribute test.
+ * See runAddAttributesTests for a description.
+ * @param {Object} test A test object should contain the following properties:
+ *        - desc {String} a textual description for that test, to help when
+ *        reading logs
+ *        - text {String} the string to be inserted into the new attribute field
+ *        - expectedAttributes {Object} a key/value pair object that will be
+ *        used to check the attributes on the test element
+ *        - validate {Function} optional extra function that will be called after
+ *        the attributes have been added and which should be used to assert some
+ *        more things this test runner might not be checking. The function will
+ *        be called with the following arguments:
+ *          - {DOMNode} The element being tested
+ *          - {MarkupContainer} The corresponding container in the markup-view
+ *          - {InspectorPanel} The instance of the InspectorPanel opened
+ * @param {DOMNode|String} nodeOrSelector The node or node selector
+ * corresponding to the test element
+ * @param {InspectorPanel} inspector The instance of InspectorPanel currently
+ * opened
+ */
+function* runAddAttributesTest(test, nodeOrSelector, inspector) {
+  let element = getNode(nodeOrSelector);
+
+  info("Starting add-attribute test: " + test.desc);
+  yield addNewAttributes(element, test.text, inspector);
+
+  info("Assert that the attribute(s) has/have been applied correctly");
+  assertAttributes(element, test.expectedAttributes);
+
+  if (test.validate) {
+    test.validate(element, getContainerForRawNode(element, inspector), inspector);
+  }
+
+  info("Undo the change");
+  yield undoChange(inspector);
+
+  info("Assert that the attribute(s) has/have been removed correctly");
+  assertAttributes(element, {});
+}
+
+/**
+ * Run a series of edit-attributes tests.
+ * This function will iterate over the provided tests array and run each test.
+ * Each test's goal is to locate a given element on the current test page, assert
+ * its current attributes, then provide the name of one of them and a value to
+ * be set into it, and then check if the new attributes are correct.
+ * After each test has run, the markup-view's undo and redo commands will be
+ * called and the test runner will assert again that the attributes are correct.
+ * @param {Array} tests See runEditAttributesTest for the structure
+ * @param {InspectorPanel} inspector The instance of InspectorPanel currently
+ * opened
+ * @return a promise that resolves when the tests have run
+ */
+function runEditAttributesTests(tests, inspector) {
+  info("Running " + tests.length + " edit-attributes tests");
+  return Task.spawn(function*() {
+    info("Expanding all nodes in the markup-view");
+    yield inspector.markup.expandAll();
+
+    for (let test of tests) {
+      yield runEditAttributesTest(test, inspector);
+    }
+
+    yield inspector.once("inspector-updated");
+  });
+}
+
+/**
+ * Run a single edit-attribute test.
+ * See runEditAttributesTests for a description.
+ * @param {Object} test A test object should contain the following properties:
+ *        - desc {String} a textual description for that test, to help when
+ *        reading logs
+ *        - node {String} a css selector that will be used to select the node
+ *        which will be tested during this iteration
+ *        - originalAttributes {Object} a key/value pair object that will be
+ *        used to check the attributes of the node before the test runs
+ *        - name {String} the name of the attribute to focus the editor for
+ *        - value {String} the new value to be typed in the focused editor
+ *        - expectedAttributes {Object} a key/value pair object that will be
+ *        used to check the attributes on the test element
+ * @param {InspectorPanel} inspector The instance of InspectorPanel currently
+ * opened
+ */
+function* runEditAttributesTest(test, inspector) {
+  info("Starting edit-attribute test: " + test.desc);
+
+  info("Selecting the test node " + test.node);
+  yield selectNode(test.node, inspector);
+
+  info("Asserting that the node has the right attributes to start with");
+  assertAttributes(test.node, test.originalAttributes);
+
+  info("Editing attribute " + test.name + " with value " + test.value);
+
+  let container = getContainerForRawNode(test.node, inspector);
+  ok(container && container.editor, "The markup-container for " + test.node +
+    " was found");
+
+  info("Listening for the markupmutation event");
+  let nodeMutated = inspector.once("markupmutation");
+  let attr = container.editor.attrs[test.name].querySelector(".editable");
+  setEditableFieldValue(attr, test.value, inspector);
+  yield nodeMutated;
+
+  info("Asserting the new attributes after edition");
+  assertAttributes(test.node, test.expectedAttributes);
+
+  info("Undo the change and assert that the attributes have been changed back");
+  yield undoChange(inspector);
+  assertAttributes(test.node, test.originalAttributes);
+
+  info("Redo the change and assert that the attributes have been changed again");
+  yield redoChange(inspector);
+  assertAttributes(test.node, test.expectedAttributes);
+}
new file mode 100644
--- /dev/null
+++ b/browser/devtools/markupview/test/helper_outerhtml_test_runner.js
@@ -0,0 +1,81 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Run a series of edit-outer-html tests.
+ * This function will iterate over the provided tests array and run each test.
+ * Each test's goal is to provide a node (a selector) and a new outer-HTML to be
+ * inserted in place of the current one for that node.
+ * This test runner will wait for the mutation event to be fired and will check
+ * a few things. Each test may also provide its own validate function to perform
+ * assertions and verify that the new outer html is correct.
+ * @param {Array} tests See runEditOuterHTMLTest for the structure
+ * @param {InspectorPanel} inspector The instance of InspectorPanel currently
+ * opened
+ * @return a promise that resolves when the tests have run
+ */
+function runEditOuterHTMLTests(tests, inspector) {
+  info("Running " + tests.length + " edit-outer-html tests");
+  return Task.spawn(function* () {
+    for (let step of TEST_DATA) {
+      yield runEditOuterHTMLTest(step, inspector);
+    }
+  });
+}
+
+/**
+ * Run a single edit-outer-html test.
+ * See runEditOuterHTMLTests for a description.
+ * @param {Object} test A test object should contain the following properties:
+ *        - selector {String} a css selector targeting the node to edit
+ *        - oldHTML {String}
+ *        - newHTML {String}
+ *        - validate {Function} will be executed when the edition test is done,
+ *        after the new outer-html has been inserted. Should be used to verify
+ *        the actual DOM, see if it corresponds to the newHTML string provided
+ * @param {InspectorPanel} inspector The instance of InspectorPanel currently
+ * opened
+ */
+function* runEditOuterHTMLTest(test, inspector) {
+  info("Running an edit outerHTML test on '" + test.selector + "'");
+  yield selectNode(test.selector, inspector);
+  let oldNodeFront = inspector.selection.nodeFront;
+
+  info("Listening for the markupmutation event");
+  // This event fires once the outerHTML is set, with a target as the parent node and a type of "childList".
+  let mutated = inspector.once("markupmutation");
+  info("Editing the outerHTML");
+  inspector.markup.updateNodeOuterHTML(inspector.selection.nodeFront, test.newHTML, test.oldHTML);
+  let mutations = yield mutated;
+  ok(true, "The markupmutation event has fired, mutation done");
+
+  info("Check to make the sure the correct mutation event was fired, and that the parent is selected");
+  let nodeFront = inspector.selection.nodeFront;
+  let mutation = mutations[0];
+  let isFromOuterHTML = mutation.removed.some(n => n === oldNodeFront);
+
+  ok(isFromOuterHTML, "The node is in the 'removed' list of the mutation");
+  is(mutation.type, "childList", "Mutation is a childList after updating outerHTML");
+  is(mutation.target, nodeFront, "Parent node is selected immediately after setting outerHTML");
+
+  // Wait for node to be reselected after outerHTML has been set
+  yield inspector.selection.once("new-node");
+
+  // Typically selectedNode will === pageNode, but if a new element has been injected in front
+  // of it, this will not be the case.  If this happens.
+  let selectedNode = inspector.selection.node;
+  let nodeFront = inspector.selection.nodeFront;
+  let pageNode = getNode(test.selector);
+
+  if (test.validate) {
+    test.validate(pageNode, selectedNode);
+  } else {
+    is(pageNode, selectedNode, "Original node (grabbed by selector) is selected");
+    is(pageNode.outerHTML, test.newHTML, "Outer HTML has been updated");
+  }
+
+  // Wait for the inspector to be fully updated to avoid causing errors by
+  // abruptly closing hanging requests when the test ends
+  yield inspector.once("inspector-updated");
+}