Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Errors

"use strict";
const META_PAGE =
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
const HEADER_PAGE =
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
const TARGET_PAGE =
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
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.startLoadingURIString(
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.startLoadingURIString(
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 [redirectLabel, refreshLabel] = await document.l10n.formatValues([
{ id: "refresh-blocked-redirect-label" },
{ id: "refresh-blocked-refresh-label" },
]);
is(
notification.messageText.textContent.trim(),
redirectLabel,
"Should be showing the redirect message"
);
// Next, attempt a refresh
await attemptFakeRefresh(browser, false);
is(
notification.messageText.textContent.trim(),
refreshLabel,
"Should be showing the refresh message"
);
}
);
});