Bug 1313568 - Update CaptivePortalWatcher tests to work with per-window handling of captive portal UI. r=MattN draft
authorNihanth Subramanya <nhnt11@gmail.com>
Sat, 14 Jan 2017 04:24:43 +0530
changeset 464607 b827197f5f71d81c664ea556e47a5518d482a60d
parent 464606 c6c1321b591fdbd870ff40374477bbc05fbcb27c
child 464608 51bb545dcb072347a916210ce8c71b0711719076
push id42374
push usernhnt11@gmail.com
push dateSat, 21 Jan 2017 04:39:45 +0000
reviewersMattN
bugs1313568
milestone53.0a1
Bug 1313568 - Update CaptivePortalWatcher tests to work with per-window handling of captive portal UI. r=MattN MozReview-Commit-ID: LXjaP37l2dQ
browser/modules/test/browser_CaptivePortalWatcher.js
--- a/browser/modules/test/browser_CaptivePortalWatcher.js
+++ b/browser/modules/test/browser_CaptivePortalWatcher.js
@@ -14,30 +14,33 @@ const CANONICAL_URL = "data:text/plain;c
 const CANONICAL_URL_REDIRECTED = "data:text/plain;charset=utf-8,redirected";
 const PORTAL_NOTIFICATION_VALUE = "captive-portal-detected";
 
 add_task(function* setup() {
   yield SpecialPowers.pushPrefEnv({
     set: [["captivedetect.canonicalURL", CANONICAL_URL],
           ["captivedetect.canonicalContent", CANONICAL_CONTENT]],
   });
+  // We need to test behavior when a portal is detected when there is no browser
+  // window, but we can't close the default window opened by the test harness.
+  // Instead, we deactivate CaptivePortalWatcher in the default window and
+  // exclude it from RecentWindow.getMostRecentBrowserWindow in an attempt to
+  // mask its presence.
+  window.CaptivePortalWatcher.uninit();
+  RecentWindow._getMostRecentBrowserWindowCopy = RecentWindow.getMostRecentBrowserWindow;
+  let defaultWindow = window;
+  RecentWindow.getMostRecentBrowserWindow = () => {
+    let win = RecentWindow._getMostRecentBrowserWindowCopy();
+    if (win == defaultWindow) {
+      return null;
+    }
+    return win;
+  };
 });
 
-/**
- * We can't close the original window opened by mochitest without failing, so
- * override RecentWindow.getMostRecentBrowserWindow to make CaptivePortalWatcher
- * think there's no window.
- */
-function* portalDetectedNoBrowserWindow() {
-  let getMostRecentBrowserWindow = RecentWindow.getMostRecentBrowserWindow;
-  RecentWindow.getMostRecentBrowserWindow = () => {};
-  yield portalDetected();
-  RecentWindow.getMostRecentBrowserWindow = getMostRecentBrowserWindow;
-}
-
 function* portalDetected() {
   Services.obs.notifyObservers(null, "captive-portal-login", null);
   yield BrowserTestUtils.waitForCondition(() => {
     return cps.state == cps.LOCKED_PORTAL;
   }, "Waiting for Captive Portal Service to update state after portal detected.");
 }
 
 function* freePortal(aSuccess) {
@@ -51,24 +54,24 @@ function* freePortal(aSuccess) {
 function* openWindowAndWaitForPortalUI(aLongRecheck) {
   // CaptivePortalWatcher triggers a recheck when a window gains focus. If
   // the time taken for the check to complete is under PORTAL_RECHECK_DELAY_MS,
   // a tab with the login page is opened and selected. If it took longer,
   // no tab is opened. It's not reliable to time things in an async test,
   // so use a delay threshold of -1 to simulate a long recheck (so that any
   // amount of time is considered excessive), and a very large threshold to
   // simulate a short recheck.
-  CaptivePortalWatcher.PORTAL_RECHECK_DELAY_MS = aLongRecheck ? -1 : 1000000;
+  Preferences.set("captivedetect.portalRecheckDelayMS", aLongRecheck ? -1 : 1000000);
 
-  let win = yield BrowserTestUtils.openNewBrowserWindow();
+  let win = yield openWindowAndWaitForFocus();
 
   // After a new window is opened, CaptivePortalWatcher asks for a recheck, and
   // waits for it to complete. We need to manually tell it a recheck completed.
   yield BrowserTestUtils.waitForCondition(() => {
-    return CaptivePortalWatcher._waitingForRecheck;
+    return win.CaptivePortalWatcher._waitingForRecheck;
   }, "Waiting for CaptivePortalWatcher to trigger a recheck.");
   Services.obs.notifyObservers(null, "captive-portal-check-complete", null);
 
   let notification = ensurePortalNotification(win);
 
   if (aLongRecheck) {
     ensureNoPortalTab(win);
     testShowLoginPageButtonVisibility(notification, "visible");
@@ -143,100 +146,112 @@ function waitForXulWindowVisible() {
 }
 
 function* closeWindowAndWaitForXulWindowVisible(win) {
   let p = waitForXulWindowVisible();
   yield BrowserTestUtils.closeWindow(win);
   yield p;
 }
 
+/**
+ * BrowserTestUtils.openNewBrowserWindow() does not guarantee the newly
+ * opened window has received focus when the promise resolves, so we
+ * have to manually wait every time.
+ */
+function* openWindowAndWaitForFocus() {
+  let win = yield BrowserTestUtils.openNewBrowserWindow();
+  yield SimpleTest.promiseFocus(win);
+  return win;
+}
+
 // Each of the test cases below is run twice: once for login-success and once
 // for login-abort (aSuccess set to true and false respectively).
 let testCasesForBothSuccessAndAbort = [
   /**
    * A portal is detected when there's no browser window, then a browser
    * window is opened, then the portal is freed.
    * The portal tab should be added and focused when the window is
    * opened, and closed automatically when the success event is fired.
    * The captive portal notification should be shown when the window is
    * opened, and closed automatically when the success event is fired.
    */
   function* test_detectedWithNoBrowserWindow_Open(aSuccess) {
-    yield portalDetectedNoBrowserWindow();
+    yield portalDetected();
     let win = yield openWindowAndWaitForPortalUI();
     yield freePortal(aSuccess);
     ensureNoPortalTab(win);
     ensureNoPortalNotification(win);
     yield closeWindowAndWaitForXulWindowVisible(win);
   },
 
   /**
    * A portal is detected when there's no browser window, then a browser
    * window is opened, then the portal is freed.
    * The recheck triggered when the browser window is opened takes a
    * long time. No portal tab should be added.
    * The captive portal notification should be shown when the window is
    * opened, and closed automatically when the success event is fired.
    */
   function* test_detectedWithNoBrowserWindow_LongRecheck(aSuccess) {
-    yield portalDetectedNoBrowserWindow();
+    yield portalDetected();
     let win = yield openWindowAndWaitForPortalUI(true);
     yield freePortal(aSuccess);
     ensureNoPortalTab(win);
     ensureNoPortalNotification(win);
     yield closeWindowAndWaitForXulWindowVisible(win);
   },
 
   /**
    * A portal is detected when there's no browser window, and the
    * portal is freed before a browser window is opened. No portal
    * UI should be shown when a browser window is opened.
    */
   function* test_detectedWithNoBrowserWindow_GoneBeforeOpen(aSuccess) {
-    yield portalDetectedNoBrowserWindow();
+    yield portalDetected();
     yield freePortal(aSuccess);
-    let win = yield BrowserTestUtils.openNewBrowserWindow();
+    let win = yield openWindowAndWaitForFocus();
     // Wait for a while to make sure no UI is shown.
     yield new Promise(resolve => {
       setTimeout(resolve, 1000);
     });
     ensureNoPortalTab(win);
     ensureNoPortalNotification(win);
     yield closeWindowAndWaitForXulWindowVisible(win);
   },
 
   /**
    * A portal is detected when a browser window has focus. No portal tab should
    * be opened. A notification bar should be displayed in all browser windows.
    */
   function* test_detectedWithFocus(aSuccess) {
-    let win1 = RecentWindow.getMostRecentBrowserWindow();
-    let win2 = yield BrowserTestUtils.openNewBrowserWindow();
+    let win1 = yield openWindowAndWaitForFocus();
+    let win2 = yield openWindowAndWaitForFocus();
     yield portalDetected();
     ensureNoPortalTab(win1);
     ensureNoPortalTab(win2);
     ensurePortalNotification(win1);
     ensurePortalNotification(win2);
     yield freePortal(aSuccess);
     ensureNoPortalNotification(win1);
     ensureNoPortalNotification(win2);
     yield closeWindowAndWaitForXulWindowVisible(win2);
+    yield closeWindowAndWaitForXulWindowVisible(win1);
   },
 ];
 
 let singleRunTestCases = [
   /**
    * A portal is detected when there's no browser window,
    * then a browser window is opened, and the portal is logged into
    * and redirects to a different page. The portal tab should be added
    * and focused when the window is opened, and left open after login
    * since it redirected.
    */
   function* test_detectedWithNoBrowserWindow_Redirect() {
-    yield portalDetectedNoBrowserWindow();
+    yield portalDetected();
     let win = yield openWindowAndWaitForPortalUI();
     let browser = win.gBrowser.selectedTab.linkedBrowser;
     let loadPromise =
       BrowserTestUtils.browserLoaded(browser, false, CANONICAL_URL_REDIRECTED);
     BrowserTestUtils.loadURI(browser, CANONICAL_URL_REDIRECTED);
     yield loadPromise;
     yield freePortal(true);
     ensurePortalTab(win);
@@ -246,17 +261,17 @@ let singleRunTestCases = [
 
   /**
    * Test the various expected behaviors of the "Show Login Page" button
    * in the captive portal notification. The button should be visible for
    * all tabs except the captive portal tab, and when clicked, should
    * ensure a captive portal tab is open and select it.
    */
   function* test_showLoginPageButton() {
-    let win = RecentWindow.getMostRecentBrowserWindow();
+    let win = yield openWindowAndWaitForFocus();
     yield portalDetected();
     let notification = ensurePortalNotification(win);
     testShowLoginPageButtonVisibility(notification, "visible");
 
     function testPortalTabSelectedAndButtonNotVisible() {
       is(win.gBrowser.selectedTab, tab, "The captive portal tab should be selected.");
       testShowLoginPageButtonVisibility(notification, "hidden");
     }
@@ -297,19 +312,26 @@ let singleRunTestCases = [
     win.gBrowser.selectedTab = anotherTab;
     testShowLoginPageButtonVisibility(notification, "visible");
     tab = yield clickButtonAndExpectNewPortalTab();
 
     yield BrowserTestUtils.removeTab(anotherTab);
     yield freePortal(true);
     ensureNoPortalTab(win);
     ensureNoPortalNotification(win);
+    yield closeWindowAndWaitForXulWindowVisible(win);
   },
 ];
 
 for (let testcase of testCasesForBothSuccessAndAbort) {
   add_task(testcase.bind(null, true));
   add_task(testcase.bind(null, false));
 }
 
 for (let testcase of singleRunTestCases) {
   add_task(testcase);
 }
+
+add_task(function* cleanUp() {
+  RecentWindow.getMostRecentBrowserWindow = RecentWindow._getMostRecentBrowserWindowCopy;
+  delete RecentWindow._getMostRecentBrowserWindowCopy;
+  window.CaptivePortalWatcher.init();
+});