diff options
Diffstat (limited to 'browser/base/content/test/general/browser_refreshBlocker.js')
-rw-r--r-- | browser/base/content/test/general/browser_refreshBlocker.js | 209 |
1 files changed, 209 insertions, 0 deletions
diff --git a/browser/base/content/test/general/browser_refreshBlocker.js b/browser/base/content/test/general/browser_refreshBlocker.js new file mode 100644 index 0000000000..0052282257 --- /dev/null +++ b/browser/base/content/test/general/browser_refreshBlocker.js @@ -0,0 +1,209 @@ +"use strict"; + +const META_PAGE = + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + "http://example.org/browser/browser/base/content/test/general/refresh_meta.sjs"; +const HEADER_PAGE = + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + "http://example.org/browser/browser/base/content/test/general/refresh_header.sjs"; +const TARGET_PAGE = + // eslint-disable-next-line @microsoft/sdl/no-insecure-url + "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 + */ +async function attemptFakeRefresh(browser, expectRefresh) { + await SpecialPowers.spawn( + browser, + [expectRefresh], + async function (contentExpectRefresh) { + let URI = docShell.QueryInterface(Ci.nsIWebNavigation).currentURI; + let refresher = docShell.QueryInterface(Ci.nsIRefreshURI); + refresher.refreshURI(URI, null, 0); + + Assert.equal( + refresher.refreshPending, + contentExpectRefresh, + "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(async function test_can_enable_and_block() { + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: TARGET_PAGE, + }, + async function (browser) { + // By default, we should be able to reload the page. + await attemptFakeRefresh(browser, true); + + await pushPrefs(["accessibility.blockautorefresh", true]); + + let notificationPromise = BrowserTestUtils.waitForNotificationBar( + gBrowser, + browser, + "refresh-blocked" + ); + + await attemptFakeRefresh(browser, false); + + await notificationPromise; + + await pushPrefs(["accessibility.blockautorefresh", false]); + + // Page reloads should go through again. + await attemptFakeRefresh(browser, true); + } + ); +}); + +/** + * 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 + */ +async function testRealRefresh(refreshPage, delay) { + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: "about:blank", + }, + async function (browser) { + await pushPrefs(["accessibility.blockautorefresh", true]); + + BrowserTestUtils.loadURIString( + browser, + refreshPage + "?p=" + TARGET_PAGE + "&d=" + delay + ); + await BrowserTestUtils.browserLoaded(browser); + + // Once browserLoaded resolves, all nsIWebProgressListener callbacks + // should have fired, so the notification should be visible. + let notificationBox = gBrowser.getNotificationBox(browser); + let notification = notificationBox.currentNotification; + + ok(notification, "Notification should be visible"); + is( + notification.getAttribute("value"), + "refresh-blocked", + "Should be showing the right notification" + ); + + // Then click the button to allow the refresh. + let buttons = notification.buttonContainer.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(); + + await refreshPromise; + } + ); +} + +/** + * Tests the meta-tag case for both short and longer delay times. + */ +add_task(async function test_can_allow_refresh() { + await testRealRefresh(META_PAGE, 0); + await testRealRefresh(META_PAGE, 100); + await testRealRefresh(META_PAGE, 500); +}); + +/** + * Tests that when a HTTP header case for both short and longer + * delay times. + */ +add_task(async function test_can_block_refresh_from_header() { + await testRealRefresh(HEADER_PAGE, 0); + await testRealRefresh(HEADER_PAGE, 100); + await testRealRefresh(HEADER_PAGE, 500); +}); + +/** + * Tests that we can update a notification when multiple reload/redirect + * attempts happen. + */ +add_task(async function test_can_update_notification() { + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: "about:blank", + }, + async function (browser) { + await pushPrefs(["accessibility.blockautorefresh", true]); + + // First, attempt a redirect + BrowserTestUtils.loadURIString( + browser, + META_PAGE + "?d=0&p=" + TARGET_PAGE + ); + await BrowserTestUtils.browserLoaded(browser); + + // Once browserLoaded resolves, all nsIWebProgressListener callbacks + // should have fired, so the notification should be visible. + let notificationBox = gBrowser.getNotificationBox(browser); + let notification = notificationBox.currentNotification; + + let message = notification.messageText.querySelector("span"); + is( + message.dataset.l10nId, + "refresh-blocked-redirect-label", + "Should be showing the redirect message" + ); + + // Next, attempt a refresh + await attemptFakeRefresh(browser, false); + + message = notification.messageText.querySelector("span"); + is( + message.dataset.l10nId, + "refresh-blocked-refresh-label", + "Should be showing the refresh message" + ); + } + ); +}); |