Bug 1315969 - Update captive portal tests to not expect background tabs. r=MattN a=jcristau
authorNihanth Subramanya <nhnt11@gmail.com>
Fri, 11 Nov 2016 15:36:49 +0530
changeset 352847 392d293b5169b5cda8b84d8a6955702664a969d0
parent 352846 bf7877a40fe66b43c031b19aff4920418c1dbd01
child 352848 34a3558cce8dbfca622fd39fa3988f86dc49a040
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMattN, jcristau
bugs1315969
milestone52.0a2
Bug 1315969 - Update captive portal tests to not expect background tabs. r=MattN a=jcristau MozReview-Commit-ID: 7LOjRTSYvJl
browser/modules/CaptivePortalWatcher.jsm
browser/modules/test/browser_CaptivePortalWatcher.js
--- a/browser/modules/CaptivePortalWatcher.jsm
+++ b/browser/modules/CaptivePortalWatcher.jsm
@@ -1,53 +1,58 @@
 /* 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/. */
 
 "use strict";
 
 const { classes: Cc, interfaces: Ci, utils: Cu } = Components;
-/**
- * This constant is chosen to be large enough for a portal recheck to complete,
- * and small enough that the delay in opening a tab isn't too noticeable.
- * Please see comments for _delayedAddCaptivePortalTab for more details.
- */
-const PORTAL_RECHECK_DELAY_MS = 150;
-
-// This is the value used to identify the captive portal notification.
-const PORTAL_NOTIFICATION_VALUE = "captive-portal-detected";
 
 this.EXPORTED_SYMBOLS = [ "CaptivePortalWatcher" ];
 
 Cu.import("resource://gre/modules/Services.jsm");
 Cu.import("resource://gre/modules/Timer.jsm");
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 Cu.import("resource:///modules/RecentWindow.jsm");
 
 XPCOMUtils.defineLazyServiceGetter(this, "cps",
                                    "@mozilla.org/network/captive-portal-service;1",
                                    "nsICaptivePortalService");
 
 this.CaptivePortalWatcher = {
+  /**
+   * This constant is chosen to be large enough for a portal recheck to complete,
+   * and small enough that the delay in opening a tab isn't too noticeable.
+   * Please see comments for _delayedCaptivePortalDetected for more details.
+   */
+  PORTAL_RECHECK_DELAY_MS: 150,
+
+  // This is the value used to identify the captive portal notification.
+  PORTAL_NOTIFICATION_VALUE: "captive-portal-detected",
+
   // This holds a weak reference to the captive portal tab so that we
   // don't leak it if the user closes it.
   _captivePortalTab: null,
 
   // This holds a weak reference to the captive portal notification.
   _captivePortalNotification: null,
 
   _initialized: false,
 
   /**
    * If a portal is detected when we don't have focus, we first wait for focus
-   * and then add the tab after a small delay. This is set to true while we wait
-   * so that in the unlikely event that we receive another notification while
-   * waiting, we can avoid adding a second tab.
+   * and then add the tab if, after a recheck, the portal is still active. This
+   * is set to true while we wait so that in the unlikely event that we receive
+   * another notification while waiting, we don't do things twice.
    */
-  _waitingToAddTab: false,
+  _delayedCaptivePortalDetectedInProgress: false,
+
+  // In the situation above, this is set to true while we wait for the recheck.
+  // This flag exists so that tests can appropriately simulate a recheck.
+  _waitingForRecheck: false,
 
   get canonicalURL() {
     return Services.prefs.getCharPref("captivedetect.canonicalURL");
   },
 
   init() {
     Services.obs.addObserver(this, "captive-portal-login", false);
     Services.obs.addObserver(this, "captive-portal-login-abort", false);
@@ -77,33 +82,33 @@ this.CaptivePortalWatcher = {
       case "captive-portal-login":
         this._captivePortalDetected();
         break;
       case "captive-portal-login-abort":
       case "captive-portal-login-success":
         this._captivePortalGone();
         break;
       case "xul-window-visible":
-        this._delayedAddCaptivePortalTab();
+        this._delayedCaptivePortalDetected();
         break;
     }
   },
 
   _captivePortalDetected() {
-    if (this._waitingToAddTab) {
+    if (this._delayedCaptivePortalDetectedInProgress) {
       return;
     }
 
     let win = RecentWindow.getMostRecentBrowserWindow();
     // If there's no browser window or none have focus, open and show the
     // tab when we regain focus. This is so that if a different application was
     // focused, when the user (re-)focuses a browser window, we open the tab
     // immediately in that window so they can login before continuing to browse.
     if (!win || win != Services.ww.activeWindow) {
-      this._waitingToAddTab = true;
+      this._delayedCaptivePortalDetectedInProgress = true;
       Services.obs.addObserver(this, "xul-window-visible", false);
       return;
     }
 
     this._showNotification(win);
   },
 
   _ensureCaptivePortalTab(win) {
@@ -122,56 +127,59 @@ this.CaptivePortalWatcher = {
     return tab;
   },
 
   /**
    * Called after we regain focus if we detect a portal while a browser window
    * doesn't have focus. Triggers a portal recheck to reaffirm state, and adds
    * the tab if needed after a short delay to allow the recheck to complete.
    */
-  _delayedAddCaptivePortalTab() {
-    if (!this._waitingToAddTab) {
+  _delayedCaptivePortalDetected() {
+    if (!this._delayedCaptivePortalDetectedInProgress) {
       return;
     }
 
     let win = RecentWindow.getMostRecentBrowserWindow();
     if (win != Services.ww.activeWindow) {
       // The window that got focused was not a browser window.
       return;
     }
     Services.obs.removeObserver(this, "xul-window-visible");
 
     // Trigger a portal recheck. The user may have logged into the portal via
     // another client, or changed networks.
     cps.recheckCaptivePortal();
+    this._waitingForRecheck = true;
     let requestTime = Date.now();
 
     let self = this;
     Services.obs.addObserver(function observer() {
+      let time = Date.now() - requestTime;
       Services.obs.removeObserver(observer, "captive-portal-check-complete");
-      self._waitingToAddTab = false;
+      self._waitingForRecheck = false;
+      self._delayedCaptivePortalDetectedInProgress = false;
       if (cps.state != cps.LOCKED_PORTAL) {
         // We're free of the portal!
         return;
       }
 
       self._showNotification(win);
-      if (Date.now() - requestTime <= PORTAL_RECHECK_DELAY_MS) {
+      if (time <= self.PORTAL_RECHECK_DELAY_MS) {
         // The amount of time elapsed since we requested a recheck (i.e. since
         // the browser window was focused) was small enough that we can add and
         // focus a tab with the login page with no noticeable delay.
         self._ensureCaptivePortalTab(win);
       }
     }, "captive-portal-check-complete", false);
   },
 
   _captivePortalGone() {
-    if (this._waitingToAddTab) {
+    if (this._delayedCaptivePortalDetectedInProgress) {
       Services.obs.removeObserver(this, "xul-window-visible");
-      this._waitingToAddTab = false;
+      this._delayedCaptivePortalDetectedInProgress = false;
     }
 
     this._removeNotification();
 
     if (!this._captivePortalTab) {
       return;
     }
 
@@ -244,17 +252,17 @@ this.CaptivePortalWatcher = {
     let closeHandler = (aEventName) => {
       if (aEventName != "removed") {
         return;
       }
       win.gBrowser.tabContainer.removeEventListener("TabSelect", this);
     };
 
     let nb = win.document.getElementById("high-priority-global-notificationbox");
-    let n = nb.appendNotification(message, PORTAL_NOTIFICATION_VALUE, "",
+    let n = nb.appendNotification(message, this.PORTAL_NOTIFICATION_VALUE, "",
                                   nb.PRIORITY_INFO_MEDIUM, buttons, closeHandler);
 
     this._captivePortalNotification = Cu.getWeakReference(n);
 
     win.gBrowser.tabContainer.addEventListener("TabSelect", this);
   },
 
   _removeNotification() {
--- a/browser/modules/test/browser_CaptivePortalWatcher.js
+++ b/browser/modules/test/browser_CaptivePortalWatcher.js
@@ -1,12 +1,19 @@
 "use strict";
 
 Components.utils.import("resource:///modules/RecentWindow.jsm");
 
+XPCOMUtils.defineLazyModuleGetter(this, "CaptivePortalWatcher",
+  "resource:///modules/CaptivePortalWatcher.jsm");
+
+XPCOMUtils.defineLazyServiceGetter(this, "cps",
+                                   "@mozilla.org/network/captive-portal-service;1",
+                                   "nsICaptivePortalService");
+
 const CANONICAL_CONTENT = "success";
 const CANONICAL_URL = "data:text/plain;charset=utf-8," + CANONICAL_CONTENT;
 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],
@@ -17,52 +24,73 @@ add_task(function* setup() {
 /**
  * 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 = () => {};
-  Services.obs.notifyObservers(null, "captive-portal-login", null);
+  yield portalDetected();
   RecentWindow.getMostRecentBrowserWindow = getMostRecentBrowserWindow;
 }
 
-function* openWindowAndWaitForPortalTabAndNotification() {
+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) {
+  Services.obs.notifyObservers(null,
+    "captive-portal-login-" + (aSuccess ? "success" : "abort"), null);
+  yield BrowserTestUtils.waitForCondition(() => {
+    return cps.state != cps.LOCKED_PORTAL;
+  }, "Waiting for Captive Portal Service to update state after portal freed.");
+}
+
+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;
+
   let win = yield BrowserTestUtils.openNewBrowserWindow();
-  // Thanks to things being async, at this point we now have a new browser window
-  // but the portal notification and tab may or may not have opened. So first we
-  // check if there's already a portal notification, and if not, wait.
-  let notification = win.document.getElementById("high-priority-global-notificationbox")
-                        .getNotificationWithValue(PORTAL_NOTIFICATION_VALUE);
-  if (!notification) {
-    notification =
-      yield BrowserTestUtils.waitForGlobalNotificationBar(win, PORTAL_NOTIFICATION_VALUE);
+
+  // 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;
+  }, "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");
+    return win;
   }
-  // Then we see if there's already a portal tab. If it's open, it'll be the second one.
+
   let tab = win.gBrowser.tabs[1];
-  if (!tab || tab.linkedBrowser.currentURI.spec != CANONICAL_URL) {
-    // The tab either hasn't been opened yet or it hasn't loaded the portal URL.
-    // Waiting for a location change in the tabbrowser covers both cases.
+  if (tab.linkedBrowser.currentURI.spec != CANONICAL_URL) {
+    // The tab should load the canonical URL, wait for it.
     yield BrowserTestUtils.waitForLocationChange(win.gBrowser, CANONICAL_URL);
-    // At this point the portal tab should be the second tab. If there is still
-    // no second tab, something is wrong, and the selectedTab test below will fail.
-    tab = win.gBrowser.tabs[1];
   }
   is(win.gBrowser.selectedTab, tab,
     "The captive portal tab should be open and selected in the new window.");
   testShowLoginPageButtonVisibility(notification, "hidden");
   return win;
 }
 
-function freePortal(aSuccess) {
-  Services.obs.notifyObservers(null,
-    "captive-portal-login-" + (aSuccess ? "success" : "abort"), null);
-}
-
 function ensurePortalTab(win) {
   // For the tests that call this function, it's enough to ensure there
   // are two tabs in the window - the default tab and the portal tab.
   is(win.gBrowser.tabs.length, 2,
     "There should be a captive portal tab in the window.");
 }
 
 function ensurePortalNotification(win) {
@@ -119,229 +147,159 @@ function* closeWindowAndWaitForXulWindow
   yield BrowserTestUtils.closeWindow(win);
   yield p;
 }
 
 // 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.
+   * 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();
-    let win = yield openWindowAndWaitForPortalTabAndNotification();
-    freePortal(aSuccess);
+    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();
+    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
-   * tab should be added when a browser window is opened.
+   * UI should be shown when a browser window is opened.
    */
   function* test_detectedWithNoBrowserWindow_GoneBeforeOpen(aSuccess) {
     yield portalDetectedNoBrowserWindow();
-    freePortal(aSuccess);
+    yield freePortal(aSuccess);
     let win = yield BrowserTestUtils.openNewBrowserWindow();
-    // Wait for a while to make sure no tab is opened.
+    // 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. A portal tab should be
-   * opened in the background in the focused browser window. If the portal is
-   * freed when the tab isn't focused, the tab should be closed automatically.
+   * A portal is detected when a browser window has focus. No portal tab should
+   * be opened. A notification bar should be displayed in the focused window.
    */
   function* test_detectedWithFocus(aSuccess) {
     let win = RecentWindow.getMostRecentBrowserWindow();
-    let p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
-    Services.obs.notifyObservers(null, "captive-portal-login", null);
-    let tab = yield p;
-    ensurePortalTab(win);
-    ensurePortalNotification(win);
-    isnot(win.gBrowser.selectedTab, tab,
-      "The captive portal tab should be open in the background in the current window.");
-    freePortal(aSuccess);
+    yield portalDetected();
     ensureNoPortalTab(win);
-    ensureNoPortalNotification(win);
-  },
-
-  /**
-   * A portal is detected when a browser window has focus. A portal tab should be
-   * opened in the background in the focused browser window. If the portal is
-   * freed when the tab has focus, the tab should be closed automatically.
-   */
-  function* test_detectedWithFocus_selectedTab(aSuccess) {
-    let win = RecentWindow.getMostRecentBrowserWindow();
-    let p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
-    Services.obs.notifyObservers(null, "captive-portal-login", null);
-    let tab = yield p;
-    ensurePortalTab(win);
     ensurePortalNotification(win);
-    isnot(win.gBrowser.selectedTab, tab,
-      "The captive portal tab should be open in the background in the current window.");
-    win.gBrowser.selectedTab = tab;
-    freePortal(aSuccess);
-    ensureNoPortalTab(win);
+    yield freePortal(aSuccess);
     ensureNoPortalNotification(win);
   },
 ];
 
 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();
-    let win = yield openWindowAndWaitForPortalTabAndNotification();
+    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;
-    freePortal(true);
+    yield freePortal(true);
     ensurePortalTab(win);
     ensureNoPortalNotification(win);
     yield closeWindowAndWaitForXulWindowVisible(win);
   },
 
   /**
-   * A portal is detected when a browser window has focus. A portal tab should be
-   * opened in the background in the focused browser window. If the portal is
-   * freed when the tab isn't focused, the tab should be closed automatically,
-   * even if the portal has redirected to a URL other than CANONICAL_URL.
-   */
-  function* test_detectedWithFocus_redirectUnselectedTab() {
-    let win = RecentWindow.getMostRecentBrowserWindow();
-    let p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
-    Services.obs.notifyObservers(null, "captive-portal-login", null);
-    let tab = yield p;
-    ensurePortalTab(win);
-    ensurePortalNotification(win);
-    isnot(win.gBrowser.selectedTab, tab,
-      "The captive portal tab should be open in the background in the current window.");
-    let browser = tab.linkedBrowser;
-    let loadPromise =
-      BrowserTestUtils.browserLoaded(browser, false, CANONICAL_URL_REDIRECTED);
-    BrowserTestUtils.loadURI(browser, CANONICAL_URL_REDIRECTED);
-    yield loadPromise;
-    freePortal(true);
-    ensureNoPortalTab(win);
-    ensureNoPortalNotification(win);
-  },
-
-  /**
-   * A portal is detected when a browser window has focus. A portal tab should be
-   * opened in the background in the focused browser window. If the portal is
-   * freed when the tab has focus, and it has redirected to another page, the
-   * tab should be kept open.
-   */
-  function* test_detectedWithFocus_redirectSelectedTab() {
-    let win = RecentWindow.getMostRecentBrowserWindow();
-    let p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
-    Services.obs.notifyObservers(null, "captive-portal-login", null);
-    let tab = yield p;
-    ensurePortalNotification(win);
-    isnot(win.gBrowser.selectedTab, tab,
-      "The captive portal tab should be open in the background in the current window.");
-    win.gBrowser.selectedTab = tab;
-    let browser = tab.linkedBrowser;
-    let loadPromise =
-      BrowserTestUtils.browserLoaded(browser, false, CANONICAL_URL_REDIRECTED);
-    BrowserTestUtils.loadURI(browser, CANONICAL_URL_REDIRECTED);
-    yield loadPromise;
-    freePortal(true);
-    ensurePortalTab(win);
-    ensureNoPortalNotification(win);
-    yield BrowserTestUtils.removeTab(tab);
-  },
-
-  /**
    * 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 p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
-    Services.obs.notifyObservers(null, "captive-portal-login", null);
-    let tab = yield p;
+    yield portalDetected();
     let notification = ensurePortalNotification(win);
-    isnot(win.gBrowser.selectedTab, tab,
-      "The captive portal tab should be open in the background in the current window.");
     testShowLoginPageButtonVisibility(notification, "visible");
 
     function testPortalTabSelectedAndButtonNotVisible() {
       is(win.gBrowser.selectedTab, tab, "The captive portal tab should be selected.");
       testShowLoginPageButtonVisibility(notification, "hidden");
     }
 
-    // Select the captive portal tab. The button should hide.
-    let otherTab = win.gBrowser.selectedTab;
-    win.gBrowser.selectedTab = tab;
-    testShowLoginPageButtonVisibility(notification, "hidden");
+    let button = notification.querySelector("button.notification-button");
+    function* clickButtonAndExpectNewPortalTab() {
+      let p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
+      button.click();
+      let tab = yield p;
+      is(win.gBrowser.selectedTab, tab, "The captive portal tab should be selected.");
+      return tab;
+    }
 
-    // Select the other tab. The button should become visible.
-    win.gBrowser.selectedTab = otherTab;
-    testShowLoginPageButtonVisibility(notification, "visible");
-
-    // Simulate clicking the button. The portal tab should be selected and
-    // the button should hide.
-    let button = notification.querySelector("button.notification-button");
-    button.click();
+    // Simulate clicking the button. The portal tab should be opened and
+    // selected and the button should hide.
+    let tab = yield clickButtonAndExpectNewPortalTab();
     testPortalTabSelectedAndButtonNotVisible();
 
     // Close the tab. The button should become visible.
     yield BrowserTestUtils.removeTab(tab);
     ensureNoPortalTab(win);
     testShowLoginPageButtonVisibility(notification, "visible");
 
-    function* clickButtonAndExpectNewPortalTab() {
-      p = BrowserTestUtils.waitForNewTab(win.gBrowser, CANONICAL_URL);
-      button.click();
-      tab = yield p;
-      is(win.gBrowser.selectedTab, tab, "The captive portal tab should be selected.");
-    }
-
     // When the button is clicked, a new portal tab should be opened and
     // selected.
-    yield clickButtonAndExpectNewPortalTab();
+    tab = yield clickButtonAndExpectNewPortalTab();
 
     // Open another arbitrary tab. The button should become visible. When it's clicked,
     // the portal tab should be selected.
     let anotherTab = yield BrowserTestUtils.openNewForegroundTab(win.gBrowser);
     testShowLoginPageButtonVisibility(notification, "visible");
     button.click();
     is(win.gBrowser.selectedTab, tab, "The captive portal tab should be selected.");
 
     // Close the portal tab and select the arbitrary tab. The button should become
     // visible and when it's clicked, a new portal tab should be opened.
     yield BrowserTestUtils.removeTab(tab);
     win.gBrowser.selectedTab = anotherTab;
     testShowLoginPageButtonVisibility(notification, "visible");
-    yield clickButtonAndExpectNewPortalTab();
+    tab = yield clickButtonAndExpectNewPortalTab();
 
     yield BrowserTestUtils.removeTab(anotherTab);
-    freePortal(true);
+    yield freePortal(true);
     ensureNoPortalTab(win);
     ensureNoPortalNotification(win);
   },
 ];
 
 for (let testcase of testCasesForBothSuccessAndAbort) {
   add_task(testcase.bind(null, true));
   add_task(testcase.bind(null, false));