Bug 1055464 - Regression tests. r=Mossop
authorMike Conley <mconley@mozilla.com>
Fri, 05 Feb 2016 16:28:53 -0500
changeset 329596 cb036027df84e7e547bf3f9614b71857e5059741
parent 329595 954e2015504392e23118e1ad71506b7e6d7aed78
child 329612 a6c1554af2a73011ceb09c1ce5a55999b2c70e21
push id10558
push usermconley@mozilla.com
push dateMon, 08 Feb 2016 18:36:50 +0000
reviewersMossop
bugs1055464
milestone47.0a1
Bug 1055464 - Regression tests. r=Mossop
browser/base/content/test/general/browser.ini
browser/base/content/test/general/browser_refreshBlocker.js
testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -363,16 +363,17 @@ skip-if = (os == 'linux') || (e10s && de
 [browser_printpreview.js]
 skip-if = buildapp == 'mulet' || e10s # Bug 1101973 - breaks the next test in e10s, and may be responsible for later timeout after logging "Error: Channel closing: too late to send/recv, messages will be lost"
 [browser_private_browsing_window.js]
 skip-if = buildapp == 'mulet'
 [browser_private_no_prompt.js]
 skip-if = buildapp == 'mulet'
 [browser_purgehistory_clears_sh.js]
 [browser_PageMetaData_pushstate.js]
+[browser_refreshBlocker.js]
 [browser_relatedTabs.js]
 [browser_remoteTroubleshoot.js]
 support-files =
   test_remoteTroubleshoot.html
 [browser_remoteWebNavigation_postdata.js]
 [browser_removeTabsToTheEnd.js]
 [browser_removeUnsafeProtocolsFromURLBarPaste.js]
 [browser_restore_isAppTab.js]
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/browser_refreshBlocker.js
@@ -0,0 +1,92 @@
+"use strict";
+
+const PAGE = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
+const PREF = "accessibility.blockautorefresh";
+
+/**
+ * Goes into the content, and simulates a meta-refresh header at a very
+ * low level, and checks to see if it was blocked. This will always cancel
+ * the refresh, regardless of whether or not the refresh was blocked.
+ *
+ * @param browser (<xul:browser>)
+ *        The browser to test for refreshing.
+ * @param expectRefresh (bool)
+ *        Whether or not we expect the refresh attempt to succeed.
+ * @returns Promise
+ */
+function* attemptRefresh(browser, expectRefresh) {
+  yield ContentTask.spawn(browser, expectRefresh, function*(expectRefresh) {
+    let URI = docShell.QueryInterface(Ci.nsIWebNavigation).currentURI;
+    let refresher = docShell.QueryInterface(Ci.nsIRefreshURI);
+    refresher.refreshURI(URI, 0, false, true);
+
+    is(refresher.refreshPending, expectRefresh,
+       "Got the right refreshPending state");
+
+    if (refresher.refreshPending) {
+      // Cancel the pending refresh
+      refresher.cancelRefreshURITimers();
+    }
+  });
+}
+
+/**
+ * Tests that we can enable the blocking pref and block a refresh
+ * from occurring while showing a notification bar. Also tests that
+ * when we disable the pref, that refreshes can go through again.
+ */
+add_task(function* test_can_enable_and_block() {
+  yield BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: PAGE,
+  }, function*(browser) {
+    // By default, we should be able to reload the page.
+    yield attemptRefresh(browser, true);
+
+    yield pushPrefs(["accessibility.blockautorefresh", true]);
+
+    let notificationPromise =
+      BrowserTestUtils.waitForNotificationBar(gBrowser, browser,
+                                              "refresh-blocked");
+
+    yield attemptRefresh(browser, false);
+
+    yield notificationPromise;
+
+    yield pushPrefs(["accessibility.blockautorefresh", false]);
+
+    // Page reloads should go through again.
+    yield attemptRefresh(browser, true);
+  });
+});
+
+/**
+ * Tests that when a refresh is blocked that we show a notification
+ * bar, and that when we click on the "Allow" button, the refresh
+ * can then go through.
+ */
+add_task(function* test_can_allow_refresh() {
+  yield BrowserTestUtils.withNewTab({
+    gBrowser,
+    url: PAGE,
+  }, function*(browser) {
+    yield pushPrefs(["accessibility.blockautorefresh", true]);
+
+    let notificationPromise =
+      BrowserTestUtils.waitForNotificationBar(gBrowser, browser,
+                                              "refresh-blocked");
+
+    yield attemptRefresh(browser, false);
+    let notification = yield notificationPromise;
+
+    // Then click the button to submit the crash report.
+    let buttons = notification.querySelectorAll(".notification-button");
+    is(buttons.length, 1, "Should have one button.");
+
+    // Prepare a Promise that should resolve when the refresh goes through
+    let refreshPromise = BrowserTestUtils.browserLoaded(browser);
+    buttons[0].click();
+
+    yield refreshPromise;
+  });
+});
--- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
+++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
@@ -789,9 +789,41 @@ this.BrowserTestUtils = {
         if (conditionPassed) {
           clearInterval(intervalID);
           resolve();
         }
         tries++;
       }, interval);
     });
   },
+
+  /**
+   * Waits for a <xul:notification> with a particular value to appear
+   * for the <xul:notificationbox> of the passed in browser.
+   *
+   * @param tabbrowser (<xul:tabbrowser>)
+   *        The gBrowser that hosts the browser that should show
+   *        the notification. For most tests, this will probably be
+   *        gBrowser.
+   * @param browser (<xul:browser>)
+   *        The browser that should be showing the notification.
+   * @param notificationValue (string)
+   *        The "value" of the notification, which is often used as
+   *        a unique identifier. Example: "plugin-crashed".
+   * @return Promise
+   *        Resolves to the <xul:notification> that is being shown.
+   */
+  waitForNotificationBar(tabbrowser, browser, notificationValue) {
+    let notificationBox = tabbrowser.getNotificationBox(browser);
+    return new Promise((resolve) => {
+      let check = (event) => {
+        return event.target.value == notificationValue;
+      };
+
+      BrowserTestUtils.waitForEvent(notificationBox, "AlertActive",
+                                    false, check).then((event) => {
+        // The originalTarget of the AlertActive on a notificationbox
+        // will be the notification itself.
+        resolve(event.originalTarget);
+      });
+    });
+  },
 };