Bug 1314670 - Rewrite the new search engine behaviors test to use async functionality. r=florian, a=test-only
authorMark Banner <standard8@mozilla.com>
Wed, 19 Jul 2017 16:22:02 +0100
changeset 423505 cb14f9a3b393cc9435fd1162e0258ad83c85b178
parent 423504 ab55f7d014e7d49cc9c3e9bd918f4adeafb74fc5
child 423506 da1b102d72027d843fcfacef79b621c66605d721
push id1517
push userjlorenzo@mozilla.com
push dateThu, 14 Sep 2017 16:50:54 +0000
treeherdermozilla-release@3b41fd564418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersflorian, test-only
bugs1314670
milestone56.0
Bug 1314670 - Rewrite the new search engine behaviors test to use async functionality. r=florian, a=test-only MozReview-Commit-ID: 396ci4r6ion
browser/components/search/test/browser_searchEngine_behaviors.js
--- a/browser/components/search/test/browser_searchEngine_behaviors.js
+++ b/browser/components/search/test/browser_searchEngine_behaviors.js
@@ -2,38 +2,85 @@
  * http://creativecommons.org/publicdomain/zero/1.0/ */
 
 /*
  * Test DuckDuckGo search plugin URLs
  */
 
 "use strict";
 
-const BROWSER_SEARCH_PREF = "browser.search.";
+function promiseStateChangeURI() {
+  return new Promise(resolve => {
+    let listener = {
+      onStateChange: function onStateChange(webProgress, req, flags, status) {
+        info("onStateChange");
+        // Only care about top-level document starts
+        let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
+                       Ci.nsIWebProgressListener.STATE_START;
+        if (!(flags & docStart) || !webProgress.isTopLevel)
+          return;
+
+        if (req.originalURI.spec == "about:blank")
+          return;
+
+        gBrowser.removeProgressListener(listener);
+
+        info("received document start");
+
+        Assert.ok(req instanceof Ci.nsIChannel, "req is a channel");
+
+        req.cancel(Components.results.NS_ERROR_FAILURE);
+
+        executeSoon(() => {
+          resolve(req.originalURI.spec);
+        });
+      }
+    }
 
+    gBrowser.addProgressListener(listener);
+  });
+}
 
-function test() {
+function promiseContentSearchReady(browser) {
+  return ContentTask.spawn(browser, {}, async function(args) {
+    return new Promise(resolve => {
+      content.addEventListener("ContentSearchService", function listener(aEvent) {
+        if (aEvent.detail.type == "State") {
+          content.removeEventListener("ContentSearchService", listener);
+          resolve();
+        }
+      });
+    });
+  });
+}
+
+add_task(async function() {
+  let previouslySelectedEngine = Services.search.currentEngine;
+
+  registerCleanupFunction(function() {
+    Services.search.currentEngine = previouslySelectedEngine;
+  });
+
+  await testSearchEngine();
+});
+
+async function testSearchEngine() {
   let engine = Services.search.getEngineByName("DuckDuckGo");
   ok(engine, "DuckDuckGo is installed");
 
-  let previouslySelectedEngine = Services.search.currentEngine;
   Services.search.currentEngine = engine;
   engine.alias = "d";
 
   let base = "https://duckduckgo.com/?q=foo";
-  let url;
 
   // Test search URLs (including purposes).
-  url = engine.getSubmission("foo").uri.spec;
-  is(url, base + "&t=ffsb", "Check search URL for 'foo'");
+  let url = engine.getSubmission("foo").uri.spec;
+  Assert.equal(url, base + "&t=ffsb", "Check search URL for 'foo'");
 
-  waitForExplicitFinish();
-
-  var gCurrTest;
-  var gTests = [
+  let engineTests = [
     {
       name: "context menu search",
       searchURL: base + "&t=ffcm",
       run() {
         // Simulate a contextmenu search
         // FIXME: This is a bit "low-level"...
         BrowserSearch.loadSearch("foo", false, "contextmenu");
       }
@@ -67,95 +114,47 @@ function test() {
           sb.value = "";
         });
         EventUtils.synthesizeKey("VK_RETURN", {});
       }
     },
     {
       name: "new tab search",
       searchURL: base + "&t=ffnt",
-      run() {
-        function doSearch(doc) {
-          // Re-add the listener, and perform a search
-          gBrowser.addProgressListener(listener);
-          let input = doc.querySelector("input[id*=search-]");
+      async preTest(tab) {
+        let browser = tab.linkedBrowser
+        await BrowserTestUtils.loadURI(browser, "about:newtab");
+        await BrowserTestUtils.browserLoaded(browser);
+
+        await promiseContentSearchReady(browser);
+      },
+      async run(tab) {
+        await ContentTask.spawn(tab.linkedBrowser, {}, async function(args) {
+          let input = content.document.querySelector("input[id*=search-]");
           input.focus();
           input.value = "foo";
-          EventUtils.synthesizeKey("VK_RETURN", {});
-        }
-
-        // load about:newtab, but remove the listener first so it doesn't
-        // get in the way
-        gBrowser.removeProgressListener(listener);
-        gBrowser.loadURI("about:newtab");
-        info("Waiting for about:newtab load");
-        tab.linkedBrowser.addEventListener("load", function load(loadEvent) {
-          if (loadEvent.originalTarget != tab.linkedBrowser.contentDocumentAsCPOW ||
-              loadEvent.target.location.href == "about:blank") {
-            info("skipping spurious load event");
-            return;
-          }
-          tab.linkedBrowser.removeEventListener("load", load, true);
-
-          // Observe page setup
-          let win = gBrowser.contentWindowAsCPOW;
-          info("Waiting for newtab search init");
-          win.addEventListener("ContentSearchService", function done(contentSearchServiceEvent) {
-            info("Got newtab search event " + contentSearchServiceEvent.detail.type);
-            if (contentSearchServiceEvent.detail.type == "State") {
-              win.removeEventListener("ContentSearchService", done);
-              // Let gSearch respond to the event before continuing.
-              executeSoon(() => doSearch(win.document));
-            }
-          });
-        }, true);
+        });
+        EventUtils.synthesizeKey("VK_RETURN", {});
       }
     }
   ];
 
-  function nextTest() {
-    if (gTests.length) {
-      gCurrTest = gTests.shift();
-      info("Running : " + gCurrTest.name);
-      executeSoon(gCurrTest.run);
-    } else {
-      finish();
+  let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser);
+
+  for (let test of engineTests) {
+    info(`Running: ${test.name}`);
+
+    if (test.preTest) {
+      await test.preTest(tab);
     }
+
+    let stateChangePromise = promiseStateChangeURI();
+
+    await test.run(tab);
+
+    let receivedURI = await stateChangePromise;
+
+    Assert.equal(receivedURI, test.searchURL);
   }
 
-  let tab = gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser);
-
-  let listener = {
-    onStateChange: function onStateChange(webProgress, req, flags, status) {
-      info("onStateChange");
-      // Only care about top-level document starts
-      let docStart = Ci.nsIWebProgressListener.STATE_IS_DOCUMENT |
-                     Ci.nsIWebProgressListener.STATE_START;
-      if (!(flags & docStart) || !webProgress.isTopLevel)
-        return;
-
-      if (req.originalURI.spec == "about:blank")
-        return;
-
-      info("received document start");
-
-      ok(req instanceof Ci.nsIChannel, "req is a channel");
-      is(req.originalURI.spec, gCurrTest.searchURL, "search URL was loaded");
-      info("Actual URI: " + req.URI.spec);
-
-      req.cancel(Components.results.NS_ERROR_FAILURE);
-
-      executeSoon(nextTest);
-    }
-  }
-
-  registerCleanupFunction(function() {
-    engine.alias = undefined;
-    gBrowser.removeProgressListener(listener);
-    gBrowser.removeTab(tab);
-    Services.search.currentEngine = previouslySelectedEngine;
-  });
-
-  tab.linkedBrowser.addEventListener("load", function() {
-    gBrowser.addProgressListener(listener);
-    nextTest();
-  }, {capture: true, once: true});
+  engine.alias = undefined;
+  await BrowserTestUtils.removeTab(tab);
 }