Bug 1253655 - Get rid of CPOWs in some commandline tests; r=jsnajdr draft
authorPatrick Brosset <pbrosset@mozilla.com>
Fri, 16 Sep 2016 14:48:15 +0200
changeset 415161 0a9e2edb5b72e2ec88adfd3d0f96efdf7d6f57e5
parent 415160 eb72df647d6c22eb0c8a5ff7ef01c61e3873d3b5
child 531552 347385e1360d3dff7860ae4347695936a3295a0f
push id29803
push userbmo:pbrosset@mozilla.com
push dateMon, 19 Sep 2016 18:39:43 +0000
reviewersjsnajdr
bugs1253655
milestone51.0a1
Bug 1253655 - Get rid of CPOWs in some commandline tests; r=jsnajdr MozReview-Commit-ID: qbKJKI7uAP
devtools/client/commandline/test/browser_cmd_csscoverage_startstop.js
devtools/client/commandline/test/browser_cmd_media.js
devtools/client/commandline/test/browser_cmd_pagemod_export.js
devtools/client/commandline/test/helpers.js
devtools/client/debugger/test/mochitest/browser_dbg_cmd-break.js
--- a/devtools/client/commandline/test/browser_cmd_csscoverage_startstop.js
+++ b/devtools/client/commandline/test/browser_cmd_csscoverage_startstop.js
@@ -32,27 +32,28 @@ add_task(function* () {
 /**
  * Visit all the pages in the test
  */
 function* navigate(usage, options) {
   yield usage.start(options.chromeWindow, options.target);
 
   ok(usage.isRunning(), "csscoverage is running");
 
-  let load1Promise = helpers.listenOnce(options.browser, "load", true);
-
-  yield helpers.navigate(PAGE_1, options);
+  // Load page 1.
+  options.browser.loadURI(PAGE_1);
+  // And wait until page 1 and page 2 (an iframe inside page 1) are both loaded.
+  yield Promise.all([
+    BrowserTestUtils.browserLoaded(options.browser, false, PAGE_1),
+    BrowserTestUtils.browserLoaded(options.browser, true, PAGE_2)
+  ]);
+  is(options.browser.currentURI.spec, PAGE_1, "page 1 loaded");
 
-  // Wait for the test pages to auto-cycle
-  yield load1Promise;
-  is(options.window.location.href, PAGE_1, "page 1 loaded");
-
-  // Page 2 is a frame in page 1. JS in the page navigates to page 3.
-  yield helpers.listenOnce(options.browser, "load", true);
-  is(options.window.location.href, PAGE_3, "page 3 loaded");
+  // page 2 has JS that navigates to page 3 after a timeout.
+  yield BrowserTestUtils.browserLoaded(options.browser, false, PAGE_3);
+  is(options.browser.currentURI.spec, PAGE_3, "page 3 loaded");
 
   let toolboxReady = gDevTools.once("toolbox-ready");
 
   yield usage.stop();
 
   ok(!usage.isRunning(), "csscoverage not is running");
 
   yield toolboxReady;
--- a/devtools/client/commandline/test/browser_cmd_media.js
+++ b/devtools/client/commandline/test/browser_cmd_media.js
@@ -38,41 +38,43 @@ var tests = {
         check: {
           args: {
             type: { value: "braille"}
           }
         },
         exec: {
           output: ""
         },
-        post: function () {
-          let body = options.window.document.body;
-          let style = options.window.getComputedStyle(body);
-          is(style.backgroundColor, "rgb(255, 255, 0)", "media correctly emulated");
-        }
+        post: Task.async(function* () {
+          yield ContentTask.spawn(options.browser, {}, function* () {
+            let color = content.getComputedStyle(content.document.body).backgroundColor;
+            is(color, "rgb(255, 255, 0)", "media correctly emulated");
+          });
+        })
       }
     ]);
   },
 
   testEndMediaEmulation: function (options) {
     return helpers.audit(options, [
       {
         setup: function () {
           let mDV = options.browser.markupDocumentViewer;
           mDV.emulateMedium("embossed");
           return helpers.setInput(options, "media reset");
         },
         exec: {
           output: ""
         },
-        post: function () {
-          let body = options.window.document.body;
-          let style = options.window.getComputedStyle(body);
-          is(style.backgroundColor, "rgb(255, 255, 255)", "media reset");
-        }
+        post: Task.async(function* () {
+          yield ContentTask.spawn(options.browser, {}, function* () {
+            let color = content.getComputedStyle(content.document.body).backgroundColor;
+            is(color, "rgb(255, 255, 255)", "media reset");
+          });
+        })
       }
     ]);
   }
 };
 
 function test() {
   return Task.spawn(function* () {
     let options = yield helpers.openTab(TEST_URI);
--- a/devtools/client/commandline/test/browser_cmd_pagemod_export.js
+++ b/devtools/client/commandline/test/browser_cmd_pagemod_export.js
@@ -9,48 +9,61 @@ const TEST_URI = "http://example.com/bro
 function test() {
   return Task.spawn(spawnTest).then(finish, helpers.handleError);
 }
 
 function* spawnTest() {
   let options = yield helpers.openTab(TEST_URI);
   yield helpers.openToolbar(options);
 
-  const documentElement = options.document.documentElement;
-  const initialHtml = documentElement.innerHTML;
+  function getHTML() {
+    return ContentTask.spawn(options.browser, {}, function* () {
+      return content.document.documentElement.innerHTML;
+    });
+  }
+
+  const initialHtml = yield getHTML();
+
   function resetContent() {
-    options.document.documentElement.innerHTML = initialHtml;
+    return ContentTask.spawn(options.browser, initialHtml, function* (html) {
+      content.document.documentElement.innerHTML = html;
+    });
   }
 
   // Test exporting HTML
-  let oldOpen = options.window.open;
-  let openURL = "";
-  options.window.open = function (url) {
-    // The URL is a data: URL that contains the document source
-    openURL = decodeURIComponent(url);
-  };
+  yield ContentTask.spawn(options.browser, {}, function* () {
+    content.wrappedJSObject.oldOpen = content.open;
+    content.wrappedJSObject.openURL = "";
+    content.wrappedJSObject.open = function (url) {
+      // The URL is a data: URL that contains the document source
+      content.wrappedJSObject.openURL = decodeURIComponent(url);
+    };
+  });
 
   yield helpers.audit(options, [
     {
       setup:    "export html",
       skipIf: true,
       check: {
         input:  "export html",
         hints:             " [destination]",
         markup: "VVVVVVVVVVV",
         status: "VALID",
       },
       exec: {
         output: ""
       },
-      post: function () {
-        isnot(openURL.indexOf('<html lang="en">'), -1, "export html works: <html>");
-        isnot(openURL.indexOf("<title>GCLI"), -1, "export html works: <title>");
-        isnot(openURL.indexOf('<p id="someid">#'), -1, "export html works: <p>");
-      }
+      post: Task.async(function* () {
+        yield ContentTask.spawn(options.browser, {}, function* () {
+          let openURL =  content.wrappedJSObject.openURL;
+          isnot(openURL.indexOf('<html lang="en">'), -1, "export html works: <html>");
+          isnot(openURL.indexOf("<title>GCLI"), -1, "export html works: <title>");
+          isnot(openURL.indexOf('<p id="someid">#'), -1, "export html works: <p>");
+        });
+      })
     },
     {
       setup:    "export html stdout",
       check: {
         input:  "export html stdout",
         hints:                    "",
         markup: "VVVVVVVVVVVVVVVVVV",
         status: "VALID",
@@ -63,18 +76,21 @@ function* spawnTest() {
           /<html lang="en">/,
           /<title>GCLI/,
           /<p id="someid">#/
         ]
       }
     }
   ]);
 
-  options.window.open = oldOpen;
-  oldOpen = undefined;
+  yield ContentTask.spawn(options.browser, {}, function* () {
+    content.wrappedJSObject.open = content.wrappedJSObject.oldOpen;
+    delete content.wrappedJSObject.openURL;
+    delete content.wrappedJSObject.oldOpen;
+  });
 
   // Test 'pagemod replace'
   yield helpers.audit(options, [
     {
       setup: "pagemod replace",
       check: {
         input:  "pagemod replace",
         hints:                 " <search> <replace> [ignoreCase] [selector] [root] [attrOnly] [contentOnly] [attributes]",
@@ -109,92 +125,94 @@ function* spawnTest() {
         status: "VALID"
       }
     },
     {
       setup: "pagemod replace sOme foOBar",
       exec: {
         output: /^[^:]+: 13\. [^:]+: 0\. [^:]+: 0\.\s*$/
       },
-      post: function () {
-        is(documentElement.innerHTML, initialHtml, "no change in the page");
-      }
+      post: Task.async(function* () {
+        let html = yield getHTML();
+        is(html, initialHtml, "no change in the page");
+      })
     },
     {
       setup: "pagemod replace sOme foOBar true",
       exec: {
         output: /^[^:]+: 13\. [^:]+: 2\. [^:]+: 2\.\s*$/
       },
-      post: function () {
-        let html = documentElement.innerHTML;
+      post: Task.async(function* () {
+        let html = yield getHTML();
 
         isnot(html.indexOf('<p class="foOBarclass">.foOBarclass'), -1,
               ".someclass changed to .foOBarclass");
         isnot(html.indexOf('<p id="foOBarid">#foOBarid'), -1,
               "#someid changed to #foOBarid");
 
-        resetContent();
-      }
+        yield resetContent();
+      })
     },
     {
       setup: "pagemod replace some foobar --contentOnly",
       exec: {
         output: /^[^:]+: 13\. [^:]+: 2\. [^:]+: 0\.\s*$/
       },
-      post: function () {
-        let html = documentElement.innerHTML;
+      post: Task.async(function* () {
+        let html = yield getHTML();
 
         isnot(html.indexOf('<p class="someclass">.foobarclass'), -1,
               ".someclass changed to .foobarclass (content only)");
         isnot(html.indexOf('<p id="someid">#foobarid'), -1,
               "#someid changed to #foobarid (content only)");
 
-        resetContent();
-      }
+        yield resetContent();
+      })
     },
     {
       setup: "pagemod replace some foobar --attrOnly",
       exec: {
         output: /^[^:]+: 13\. [^:]+: 0\. [^:]+: 2\.\s*$/
       },
-      post: function () {
-        let html = documentElement.innerHTML;
+      post: Task.async(function* () {
+        let html = yield getHTML();
 
         isnot(html.indexOf('<p class="foobarclass">.someclass'), -1,
               ".someclass changed to .foobarclass (attr only)");
         isnot(html.indexOf('<p id="foobarid">#someid'), -1,
               "#someid changed to #foobarid (attr only)");
 
-        resetContent();
-      }
+        yield resetContent();
+      })
     },
     {
       setup: "pagemod replace some foobar --root head",
       exec: {
         output: /^[^:]+: 2\. [^:]+: 0\. [^:]+: 0\.\s*$/
       },
-      post: function () {
-        is(documentElement.innerHTML, initialHtml, "nothing changed");
-      }
+      post: Task.async(function* () {
+        let html = yield getHTML();
+        is(html, initialHtml, "nothing changed");
+      })
     },
     {
       setup: "pagemod replace some foobar --selector .someclass,div,span",
       exec: {
         output: /^[^:]+: 4\. [^:]+: 1\. [^:]+: 1\.\s*$/
       },
-      post: function () {
-        let html = documentElement.innerHTML;
+      post: Task.async(function* () {
+        let html = yield getHTML();
 
         isnot(html.indexOf('<p class="foobarclass">.foobarclass'), -1,
               ".someclass changed to .foobarclass");
         isnot(html.indexOf('<p id="someid">#someid'), -1,
               "#someid did not change");
 
-        resetContent();
-      }
+        yield resetContent();
+      })
     },
   ]);
 
   // Test 'pagemod remove element'
   yield helpers.audit(options, [
     {
       setup: "pagemod remove",
       check: {
@@ -222,76 +240,78 @@ function* spawnTest() {
         status: "VALID"
       },
     },
     {
       setup: "pagemod remove element p",
       exec: {
         output: /^[^:]+: 3\. [^:]+: 3\.\s*$/
       },
-      post: function () {
-        let html = documentElement.innerHTML;
+      post: Task.async(function* () {
+        let html = yield getHTML();
 
         is(html.indexOf('<p class="someclass">'), -1, "p.someclass removed");
         is(html.indexOf('<p id="someid">'), -1, "p#someid removed");
         is(html.indexOf("<p><strong>"), -1, "<p> wrapping <strong> removed");
         isnot(html.indexOf("<span>"), -1, "<span> not removed");
 
-        resetContent();
-      }
+        yield resetContent();
+      })
     },
     {
       setup: "pagemod remove element p head",
       exec: {
         output: /^[^:]+: 0\. [^:]+: 0\.\s*$/
       },
-      post: function () {
-        is(documentElement.innerHTML, initialHtml, "nothing changed in the page");
-      }
+      post: Task.async(function* () {
+        let html = yield getHTML();
+        is(html, initialHtml, "nothing changed in the page");
+      })
     },
     {
       setup: "pagemod remove element p --ifEmptyOnly",
       exec: {
         output: /^[^:]+: 3\. [^:]+: 0\.\s*$/
       },
-      post: function () {
-        is(documentElement.innerHTML, initialHtml, "nothing changed in the page");
-      }
+      post: Task.async(function* () {
+        let html = yield getHTML();
+        is(html, initialHtml, "nothing changed in the page");
+      })
     },
     {
       setup: "pagemod remove element meta,title --ifEmptyOnly",
       exec: {
         output: /^[^:]+: 2\. [^:]+: 1\.\s*$/
       },
-      post: function () {
-        let html = documentElement.innerHTML;
+      post: Task.async(function* () {
+        let html = yield getHTML();
 
         is(html.indexOf("<meta charset="), -1, "<meta> removed");
         isnot(html.indexOf("<title>"), -1, "<title> not removed");
 
-        resetContent();
-      }
+        yield resetContent();
+      })
     },
     {
       setup: "pagemod remove element p --stripOnly",
       exec: {
         output: /^[^:]+: 3\. [^:]+: 3\.\s*$/
       },
-      post: function () {
-        let html = documentElement.innerHTML;
+      post: Task.async(function* () {
+        let html = yield getHTML();
 
         is(html.indexOf('<p class="someclass">'), -1, "p.someclass removed");
         is(html.indexOf('<p id="someid">'), -1, "p#someid removed");
         is(html.indexOf("<p><strong>"), -1, "<p> wrapping <strong> removed");
         isnot(html.indexOf(".someclass"), -1, ".someclass still exists");
         isnot(html.indexOf("#someid"), -1, "#someid still exists");
         isnot(html.indexOf("<strong>p"), -1, "<strong> still exists");
 
-        resetContent();
-      }
+        yield resetContent();
+      })
     },
   ]);
 
   // Test 'pagemod remove attribute'
   yield helpers.audit(options, [
     {
       setup: "pagemod remove attribute",
       check: {
@@ -329,64 +349,69 @@ function* spawnTest() {
         });
       }
     },
     {
       setup: "pagemod remove attribute foo bar",
       exec: {
         output: /^[^:]+: 0\. [^:]+: 0\.\s*$/
       },
-      post: function () {
-        is(documentElement.innerHTML, initialHtml, "nothing changed in the page");
-      }
+      post: Task.async(function* () {
+        let html = yield getHTML();
+        is(html, initialHtml, "nothing changed in the page");
+      })
     },
     {
       setup: "pagemod remove attribute foo p",
       exec: {
         output: /^[^:]+: 3\. [^:]+: 0\.\s*$/
       },
-      post: function () {
-        is(documentElement.innerHTML, initialHtml, "nothing changed in the page");
-      }
+      post: Task.async(function* () {
+        let html = yield getHTML();
+        is(html, initialHtml, "nothing changed in the page");
+      })
     },
     {
       setup: "pagemod remove attribute id p,span",
       exec: {
         output: /^[^:]+: 5\. [^:]+: 1\.\s*$/
       },
-      post: function () {
-        is(documentElement.innerHTML.indexOf('<p id="someid">#someid'), -1,
-           "p#someid attribute removed");
-        isnot(documentElement.innerHTML.indexOf("<p>#someid"), -1,
-           "p with someid content still exists");
+      post: Task.async(function* () {
+        let html = yield getHTML();
 
-        resetContent();
-      }
+        is(html.indexOf('<p id="someid">#someid'), -1, "p#someid attribute removed");
+        isnot(html.indexOf("<p>#someid"), -1, "p with someid content still exists");
+
+        yield resetContent();
+      })
     },
     {
       setup: "pagemod remove attribute Class p",
       exec: {
         output: /^[^:]+: 3\. [^:]+: 0\.\s*$/
       },
-      post: function () {
-        is(documentElement.innerHTML, initialHtml, "nothing changed in the page");
-      }
+      post: Task.async(function* () {
+        let html = yield getHTML();
+        is(html, initialHtml, "nothing changed in the page");
+      })
     },
     {
       setup: "pagemod remove attribute Class p --ignoreCase",
       exec: {
         output: /^[^:]+: 3\. [^:]+: 1\.\s*$/
       },
-      post: function () {
-        is(documentElement.innerHTML.indexOf('<p class="someclass">.someclass'), -1,
+      post: Task.async(function* () {
+        let html = yield getHTML();
+
+        is(html.indexOf('<p class="someclass">.someclass'), -1,
            "p.someclass attribute removed");
-        isnot(documentElement.innerHTML.indexOf("<p>.someclass"), -1,
+        isnot(html.indexOf("<p>.someclass"), -1,
            "p with someclass content still exists");
 
-        resetContent();
-      }
+        yield resetContent();
+      })
     },
   ]);
 
   // Shutdown
   yield helpers.closeToolbar(options);
   yield helpers.closeTab(options);
 }
--- a/devtools/client/commandline/test/helpers.js
+++ b/devtools/client/commandline/test/helpers.js
@@ -102,17 +102,16 @@ var { helpers, assert } = (function () {
  * promise to indicate that the tab can be cleared up. (To be formal, we call
  * Promise.resolve() on the return value of the callback function)
  *
  * The options used by addTab include:
  * - chromeWindow: XUL window parent of created tab. a.k.a 'window' in mochitest
  * - tab: The new XUL tab element, as returned by gBrowser.addTab()
  * - target: The debug target as defined by the devtools framework
  * - browser: The XUL browser element for the given tab
- * - window: Content window for the created tab. a.k.a 'content' in mochitest
  * - isFirefox: Always true. Allows test sharing with GCLI
  *
  * Normally addTab will create an options object containing the values as
  * described above. However these options can be customized by the third
  * 'options' parameter. This has the ability to customize the value of
  * chromeWindow or isFirefox, and to add new properties.
  *
  * @param url The URL for the new tab
@@ -128,29 +127,23 @@ var { helpers, assert } = (function () {
 
     var tabbrowser = options.chromeWindow.gBrowser;
     options.tab = tabbrowser.addTab();
     tabbrowser.selectedTab = options.tab;
     options.browser = tabbrowser.getBrowserForTab(options.tab);
     options.target = TargetFactory.forTab(options.tab);
 
     var loaded = helpers.listenOnce(options.browser, "load", true).then(function (ev) {
-      options.document = options.browser.contentDocument;
-      options.window = options.document.defaultView;
-
       var reply = callback.call(null, options);
 
       return Promise.resolve(reply).then(null, function (error) {
         ok(false, error);
       }).then(function () {
         tabbrowser.removeTab(options.tab);
 
-        delete options.window;
-        delete options.document;
-
         delete options.target;
         delete options.browser;
         delete options.tab;
 
         delete options.chromeWindow;
         delete options.isFirefox;
       });
     });
@@ -163,18 +156,16 @@ var { helpers, assert } = (function () {
  * Open a new tab
  * @param url Address of the page to open
  * @param options Object to which we add properties describing the new tab. The
  * following properties are added:
  * - chromeWindow
  * - tab
  * - browser
  * - target
- * - document
- * - window
  * @return A promise which resolves to the options object when the 'load' event
  * happens on the new tab
  */
   helpers.openTab = function (url, options) {
     waitForExplicitFinish();
 
     options = options || {};
     options.chromeWindow = options.chromeWindow || window;
@@ -192,19 +183,16 @@ var { helpers, assert } = (function () {
 /**
  * Undo the effects of |helpers.openTab|
  * @param options The options object passed to |helpers.openTab|
  * @return A promise resolved (with undefined) when the tab is closed
  */
   helpers.closeTab = function (options) {
     options.chromeWindow.gBrowser.removeTab(options.tab);
 
-    delete options.window;
-    delete options.document;
-
     delete options.target;
     delete options.browser;
     delete options.tab;
 
     delete options.chromeWindow;
     delete options.isFirefox;
 
     return Promise.resolve(undefined);
@@ -229,34 +217,30 @@ var { helpers, assert } = (function () {
       options.requisition = toolbar.requisition;
       return options;
     });
   };
 
 /**
  * Navigate the current tab to a URL
  */
-  helpers.navigate = function (url, options) {
+  helpers.navigate = Task.async(function* (url, options) {
     options = options || {};
     options.chromeWindow = options.chromeWindow || window;
     options.tab = options.tab || options.chromeWindow.gBrowser.selectedTab;
 
     var tabbrowser = options.chromeWindow.gBrowser;
     options.browser = tabbrowser.getBrowserForTab(options.tab);
 
-    var promise = helpers.listenOnce(options.browser, "load", true).then(function () {
-      options.document = options.browser.contentDocument;
-      options.window = options.document.defaultView;
-      return options;
-    });
+    let onLoaded = BrowserTestUtils.browserLoaded(options.browser);
+    options.browser.loadURI(url);
+    yield onLoaded;
 
-    options.browser.contentWindow.location = url;
-
-    return promise;
-  };
+    return options;
+  });
 
 /**
  * Undo the effects of |helpers.openToolbar|
  * @param options The options object passed to |helpers.openToolbar|
  * @return A promise resolved (with undefined) when the toolbar is closed
  */
   helpers.closeToolbar = function (options) {
     return options.chromeWindow.DeveloperToolbar.hide().then(function () {
--- a/devtools/client/debugger/test/mochitest/browser_dbg_cmd-break.js
+++ b/devtools/client/debugger/test/mochitest/browser_dbg_cmd-break.js
@@ -48,33 +48,35 @@ function test() {
           hints:                " <file> <line>",
           markup: "VVVVVVVVVVVVVV",
           status: "ERROR"
         }
       }]);
 
       yield helpers.audit(aOptions, [{
         name: "open toolbox",
-        setup: function () {
-          return initDebugger(gBrowser.selectedTab).then(([aTab, aDebuggee, aPanel]) => {
-            // Spin the event loop before causing the debuggee to pause, to allow
-            // this function to return first.
-            executeSoon(() => aDebuggee.firstCall());
+        setup: Task.async(function* () {
+          let [aTab, aDebuggee, aPanel] = yield initDebugger(gBrowser.selectedTab);
+
+          // Spin the event loop before causing the debuggee to pause, to allow this
+          // function to return first.
+          executeSoon(() => aDebuggee.firstCall());
+
+          yield waitForSourceAndCaretAndScopes(aPanel, ".html", 1);
 
-            return waitForSourceAndCaretAndScopes(aPanel, ".html", 1).then(() => {
-              gPanel = aPanel;
-              gDebugger = gPanel.panelWin;
-              gThreadClient = gPanel.panelWin.gThreadClient;
-              gLineNumber = "" + aOptions.window.wrappedJSObject.gLineNumber;
-              gSources = gDebugger.DebuggerView.Sources;
+          gPanel = aPanel;
+          gDebugger = gPanel.panelWin;
+          gThreadClient = gPanel.panelWin.gThreadClient;
+          gLineNumber = yield ContentTask.spawn(aOptions.browser, {}, function* () {
+            return "" + content.wrappedJSObject.gLineNumber;
+          });
+          gSources = gDebugger.DebuggerView.Sources;
 
-              expectedActorObj.value = getSourceActor(gSources, TAB_URL);
-            });
-          });
-        },
+          expectedActorObj.value = getSourceActor(gSources, TAB_URL);
+        }),
         post: function () {
           ok(gThreadClient, "Debugger client exists.");
           is(gLineNumber, 14, "gLineNumber is correct.");
         },
       }]);
 
       yield helpers.audit(aOptions, [{
         name: "break add line .../doc_cmd-break.html 14",