Bug 1246291 - Beef up RefreshBlocker regression tests. r?Mossop draft
authorMike Conley <mconley@mozilla.com>
Wed, 17 Feb 2016 15:57:14 -0500
changeset 332050 0cc14cdbc441715354e6ed6ebc3b4b6f2f6e925a
parent 331872 acc64ced47f8a18f3f545ea8284c9cefb7c194fb
child 514529 2f3bcf60ef24cb435931c9a6709aac1964dcedbd
push id11146
push usermconley@mozilla.com
push dateFri, 19 Feb 2016 03:21:06 +0000
reviewersMossop
bugs1246291
milestone47.0a1
Bug 1246291 - Beef up RefreshBlocker regression tests. r?Mossop MozReview-Commit-ID: 99gakrP6vKh
browser/base/content/test/general/browser.ini
browser/base/content/test/general/browser_refreshBlocker.js
browser/base/content/test/general/refresh_header.sjs
browser/base/content/test/general/refresh_meta.sjs
--- a/browser/base/content/test/general/browser.ini
+++ b/browser/base/content/test/general/browser.ini
@@ -366,16 +366,19 @@ skip-if = (os == 'linux') || (e10s && de
 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]
+support-files =
+  refresh_header.sjs
+  refresh_meta.sjs
 [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]
--- a/browser/base/content/test/general/browser_refreshBlocker.js
+++ b/browser/base/content/test/general/browser_refreshBlocker.js
@@ -1,92 +1,135 @@
 "use strict";
 
-const PAGE = "http://example.org/browser/browser/base/content/test/general/dummy_page.html";
+const META_PAGE = "http://example.org/browser/browser/base/content/test/general/refresh_meta.sjs"
+const HEADER_PAGE = "http://example.org/browser/browser/base/content/test/general/refresh_header.sjs"
+const TARGET_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) {
+function* attemptFakeRefresh(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();
     }
+
+    // The RefreshBlocker will wait until onLocationChange has
+    // been fired before it will show any notifications (see bug
+    // 1246291), so we cause this to occur manually here.
+    content.location = URI.spec + "#foo";
   });
 }
 
 /**
  * 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,
+    url: TARGET_PAGE,
   }, function*(browser) {
     // By default, we should be able to reload the page.
-    yield attemptRefresh(browser, true);
+    yield attemptFakeRefresh(browser, true);
 
     yield pushPrefs(["accessibility.blockautorefresh", true]);
 
     let notificationPromise =
       BrowserTestUtils.waitForNotificationBar(gBrowser, browser,
                                               "refresh-blocked");
 
-    yield attemptRefresh(browser, false);
+    yield attemptFakeRefresh(browser, false);
 
     yield notificationPromise;
 
     yield pushPrefs(["accessibility.blockautorefresh", false]);
 
     // Page reloads should go through again.
-    yield attemptRefresh(browser, true);
+    yield attemptFakeRefresh(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.
+ * Attempts a "real" refresh by opening a tab, and then sending it to
+ * an SJS page that will attempt to cause a refresh. This will also pass
+ * a delay amount to the SJS page. The refresh should be blocked, and
+ * the notification should be shown. Once shown, the "Allow" button will
+ * be clicked, and the refresh will go through. Finally, the helper will
+ * close the tab and resolve the Promise.
+ *
+ * @param refreshPage (string)
+ *        The SJS page to use. Use META_PAGE for the <meta> tag refresh
+ *        case. Use HEADER_PAGE for the HTTP header case.
+ * @param delay (int)
+ *        The amount, in ms, for the page to wait before attempting the
+ *        refresh.
+ *
+ * @returns Promise
  */
-add_task(function* test_can_allow_refresh() {
+function* testRealRefresh(refreshPage, delay) {
   yield BrowserTestUtils.withNewTab({
     gBrowser,
-    url: PAGE,
+    url: "about:blank",
   }, function*(browser) {
     yield pushPrefs(["accessibility.blockautorefresh", true]);
 
-    let notificationPromise =
-      BrowserTestUtils.waitForNotificationBar(gBrowser, browser,
-                                              "refresh-blocked");
+    browser.loadURI(refreshPage + "?p=" + TARGET_PAGE + "&d=" + delay);
+    yield BrowserTestUtils.browserLoaded(browser);
 
-    yield attemptRefresh(browser, false);
-    let notification = yield notificationPromise;
+    // Once browserLoaded resolves, all nsIWebProgressListener callbacks
+    // should have fired, so the notification should be visible.
+    let notificationBox = gBrowser.getNotificationBox(browser);
+    let notification = notificationBox.currentNotification;
 
-    // Then click the button to submit the crash report.
+    ok(notification, "Notification should be visible");
+    is(notification.value, "refresh-blocked",
+       "Should be showing the right notification");
+
+    // Then click the button to allow the refresh.
     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;
   });
+}
+
+/**
+ * Tests the meta-tag case for both short and longer delay times.
+ */
+add_task(function* test_can_allow_refresh() {
+  yield testRealRefresh(META_PAGE, 0);
+  yield testRealRefresh(META_PAGE, 100);
+  yield testRealRefresh(META_PAGE, 500);
 });
+
+/**
+ * Tests that when a HTTP header case for both short and longer
+ * delay times.
+ */
+add_task(function* test_can_block_refresh_from_header() {
+  yield testRealRefresh(HEADER_PAGE, 0);
+  yield testRealRefresh(HEADER_PAGE, 100);
+  yield testRealRefresh(HEADER_PAGE, 500);
+});
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/refresh_header.sjs
@@ -0,0 +1,24 @@
+/**
+ * Will cause an auto-refresh to the URL provided in the query string
+ * after some delay using the refresh HTTP header.
+ *
+ * Expects the query string to be in the format:
+ *
+ * ?p=[URL of the page to redirect to]&d=[delay]
+ *
+ * Example:
+ *
+ * ?p=http%3A%2F%2Fexample.org%2Fbrowser%2Fbrowser%2Fbase%2Fcontent%2Ftest%2Fgeneral%2Frefresh_meta.sjs&d=200
+ */
+function handleRequest(request, response) {
+  Components.utils.importGlobalProperties(["URLSearchParams"]);
+  let query = new URLSearchParams(request.queryString);
+
+  let page = query.get("p");
+  let delay = query.get("d");
+
+  response.setHeader("Content-Type", "text/html", false);
+  response.setStatusLine(request.httpVersion, "200", "Found");
+  response.setHeader("refresh", `${delay}; url=${page}`);
+  response.write("OK");
+}
\ No newline at end of file
new file mode 100644
--- /dev/null
+++ b/browser/base/content/test/general/refresh_meta.sjs
@@ -0,0 +1,36 @@
+/**
+ * Will cause an auto-refresh to the URL provided in the query string
+ * after some delay using a <meta> tag.
+ *
+ * Expects the query string to be in the format:
+ *
+ * ?p=[URL of the page to redirect to]&d=[delay]
+ *
+ * Example:
+ *
+ * ?p=http%3A%2F%2Fexample.org%2Fbrowser%2Fbrowser%2Fbase%2Fcontent%2Ftest%2Fgeneral%2Frefresh_meta.sjs&d=200
+ */
+function handleRequest(request, response) {
+  Components.utils.importGlobalProperties(["URLSearchParams"]);
+  let query = new URLSearchParams(request.queryString);
+
+  let page = query.get("p");
+  let delay = query.get("d");
+
+  let html = `<!DOCTYPE HTML>
+              <html>
+              <head>
+              <meta charset='utf-8'>
+              <META http-equiv='refresh' content='${delay}; url=${page}'>
+              <title>Gonna refresh you, folks.</title>
+              </head>
+              <body>
+              <h1>Wait for it...</h1>
+              </body>
+              </html>`;
+
+  response.setHeader("Content-Type", "text/html", false);
+  response.setStatusLine(request.httpVersion, "200", "Found");
+  response.setHeader("Cache-Control", "no-cache", false);
+  response.write(html);
+}
\ No newline at end of file