зеркало из https://github.com/mozilla/gecko-dev.git
295 строки
9.0 KiB
HTML
295 строки
9.0 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>Blocking pages from entering BFCache</title>
|
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
|
</head>
|
|
<body onload="">
|
|
<script>
|
|
|
|
const getUserMediaPrefs = {
|
|
set: [
|
|
["media.devices.insecure.enabled", true],
|
|
["media.getusermedia.insecure.enabled", true],
|
|
["media.navigator.permission.disabled", true],
|
|
],
|
|
};
|
|
const msePrefs = {
|
|
set: [
|
|
["media.mediasource.enabled", true],
|
|
["media.audio-max-decode-error", 0],
|
|
["media.video-max-decode-error", 0],
|
|
]
|
|
};
|
|
|
|
const blockBFCacheTests = [
|
|
{
|
|
name: "Request",
|
|
test: () => {
|
|
return new Promise((resolve) => {
|
|
const xhr = new XMLHttpRequest();
|
|
xhr.open("GET", "slow.sjs");
|
|
xhr.addEventListener("progress", () => { resolve(xhr); }, { once: true });
|
|
xhr.send();
|
|
});
|
|
},
|
|
},
|
|
{
|
|
name: "Background request",
|
|
test: () => {
|
|
return new Promise((resolve) => {
|
|
const xhr = new XMLHttpRequest();
|
|
xhr.open("GET", "slow.sjs");
|
|
xhr.addEventListener("readystatechange", () => { if (xhr.readyState == xhr.HEADERS_RECEIVED) resolve(xhr); });
|
|
xhr.send();
|
|
});
|
|
},
|
|
},
|
|
{
|
|
name: "getUserMedia",
|
|
prefs: getUserMediaPrefs,
|
|
test: () => {
|
|
return navigator.mediaDevices.getUserMedia({ audio: true, fake: true });
|
|
},
|
|
},
|
|
{
|
|
name: "RTCPeerConnection",
|
|
test: () => {
|
|
let pc = new RTCPeerConnection();
|
|
return pc.createOffer();
|
|
},
|
|
},
|
|
{
|
|
name: "MSE",
|
|
prefs: msePrefs,
|
|
test: () => {
|
|
const ms = new MediaSource();
|
|
const el = document.createElement("video");
|
|
el.src = URL.createObjectURL(ms);
|
|
el.preload = "auto";
|
|
return el;
|
|
},
|
|
},
|
|
{
|
|
name: "WebSpeech",
|
|
test: () => {
|
|
return new Promise((resolve) => {
|
|
const utterance = new SpeechSynthesisUtterance('bfcache');
|
|
utterance.lang = 'it-IT-noend';
|
|
utterance.addEventListener('start', () => { resolve(utterance); })
|
|
speechSynthesis.speak(utterance);
|
|
});
|
|
},
|
|
},
|
|
{
|
|
name: "WebVR",
|
|
prefs: {
|
|
set: [
|
|
["dom.vr.test.enabled", true],
|
|
["dom.vr.puppet.enabled", true],
|
|
["dom.vr.require-gesture", false],
|
|
],
|
|
},
|
|
test: () => {
|
|
return navigator.requestVRServiceTest();
|
|
}
|
|
},
|
|
];
|
|
|
|
if (SpecialPowers.Services.appinfo.fissionAutostart) {
|
|
blockBFCacheTests.push({
|
|
name: "Loading OOP iframe",
|
|
test: () => {
|
|
return new Promise((resolve) => {
|
|
const el = document.body.appendChild(document.createElement("iframe"));
|
|
el.id = "frame";
|
|
addEventListener("message", ({ data }) => {
|
|
if (data == "onload") {
|
|
resolve();
|
|
}
|
|
});
|
|
el.src = "https://example.com/tests/docshell/test/navigation/iframe_slow_onload.html";
|
|
});
|
|
},
|
|
waitForDone: () => {
|
|
SimpleTest.requestFlakyTimeout("Test has a loop in an onload handler that runs for 5000ms, we need to make sure the loop is done before moving to the next test.");
|
|
return new Promise(resolve => {
|
|
setTimeout(resolve, 5000);
|
|
});
|
|
},
|
|
});
|
|
}
|
|
|
|
const dontBlockBFCacheTests = [
|
|
{
|
|
name: "getUserMedia",
|
|
prefs: getUserMediaPrefs,
|
|
test: () => {
|
|
return navigator.mediaDevices.getUserMedia({ video: true, fake: true }).then(stream => {
|
|
stream.getTracks().forEach(track => track.stop());
|
|
return stream;
|
|
});
|
|
},
|
|
},
|
|
/*
|
|
Disabled because MediaKeys rely on being destroyed by the CC before they
|
|
notify their window, so the test would intermittently fail depending on
|
|
when the CC runs.
|
|
|
|
{
|
|
name: "MSE",
|
|
prefs: msePrefs,
|
|
test: () => {
|
|
return new Promise((resolve) => {
|
|
const ms = new MediaSource();
|
|
const el = document.createElement("video");
|
|
ms.addEventListener("sourceopen", () => { resolve(el) }, { once: true });
|
|
el.src = URL.createObjectURL(ms);
|
|
el.preload = "auto";
|
|
}).then(el => {
|
|
el.src = "";
|
|
return el;
|
|
});
|
|
},
|
|
},
|
|
*/
|
|
];
|
|
|
|
|
|
|
|
function executeTest() {
|
|
|
|
let bc = new BroadcastChannel("bfcache_blocking");
|
|
|
|
function promiseMessage(type) {
|
|
return new Promise((resolve, reject) => {
|
|
bc.addEventListener("message", (e) => {
|
|
if (e.data.type == type) {
|
|
resolve(e.data);
|
|
}
|
|
}, { once: true });
|
|
});
|
|
}
|
|
|
|
function promisePageShow(shouldBePersisted) {
|
|
return promiseMessage("pageshow").then(data => data.persisted == shouldBePersisted);
|
|
}
|
|
|
|
function promisePageShowFromBFCache(e) {
|
|
return promisePageShow(true);
|
|
}
|
|
|
|
function promisePageShowNotFromBFCache(e) {
|
|
return promisePageShow(false);
|
|
}
|
|
|
|
function runTests(testArray, shouldBlockBFCache) {
|
|
for (const { name, prefs = {}, test, waitForDone } of testArray) {
|
|
add_task(async function() {
|
|
await SpecialPowers.pushPrefEnv(prefs, async function() {
|
|
// Load a mostly blank page that we can communicate with over
|
|
// BroadcastChannel (though it will close the BroadcastChannel after
|
|
// receiving the next "load" message, to avoid blocking BFCache).
|
|
let loaded = promisePageShowNotFromBFCache();
|
|
window.open("file_blockBFCache.html", "", "noopener");
|
|
await loaded;
|
|
|
|
// Load the same page with a different URL.
|
|
loaded = promisePageShowNotFromBFCache();
|
|
bc.postMessage({ message: "load", url: `file_blockBFCache.html?${name}_${shouldBlockBFCache}` });
|
|
await loaded;
|
|
|
|
// Run test script in the second page.
|
|
bc.postMessage({ message: "runScript", fun: test.toString() });
|
|
await promiseMessage("runScriptDone");
|
|
|
|
// Go back to the first page (this should just come from the BFCache).
|
|
let goneBack = promisePageShowFromBFCache();
|
|
bc.postMessage({ message: "back" });
|
|
await goneBack;
|
|
|
|
// Go forward again to the second page and check that it does/doesn't come
|
|
// from the BFCache.
|
|
let goneForward = promisePageShow(!shouldBlockBFCache);
|
|
bc.postMessage({ message: "forward" });
|
|
let result = await goneForward;
|
|
ok(result, `Page ${shouldBlockBFCache ? "should" : "should not"} have been blocked from going into the BFCache (${name})`);
|
|
|
|
// If the test will keep running after navigation, then we need to make
|
|
// sure it's completely done before moving to the next test, to avoid
|
|
// interfering with any following tests. If waitForDone is defined then
|
|
// it'll return a Promise that we can use to wait for the end of the
|
|
// test.
|
|
if (waitForDone) {
|
|
await waitForDone();
|
|
}
|
|
|
|
// Do a similar test, but replace the bfcache test page with a new page,
|
|
// not a page coming from the session history.
|
|
|
|
// Load the same page with a different URL.
|
|
loaded = promisePageShowNotFromBFCache();
|
|
bc.postMessage({ message: "load", url: `file_blockBFCache.html?p2_${name}_${shouldBlockBFCache}` });
|
|
await loaded;
|
|
|
|
// Run the test script.
|
|
bc.postMessage({ message: "runScript", fun: test.toString() });
|
|
await promiseMessage("runScriptDone");
|
|
|
|
// Load a new page.
|
|
loaded = promisePageShowNotFromBFCache();
|
|
bc.postMessage({ message: "load", url: "file_blockBFCache.html" });
|
|
await loaded;
|
|
|
|
// Go back to the previous page and check that it does/doesn't come
|
|
// from the BFCache.
|
|
goneBack = promisePageShow(!shouldBlockBFCache);
|
|
bc.postMessage({ message: "back" });
|
|
result = await goneBack;
|
|
ok(result, `Page ${shouldBlockBFCache ? "should" : "should not"} have been blocked from going into the BFCache (${name})`);
|
|
|
|
if (waitForDone) {
|
|
await waitForDone();
|
|
}
|
|
|
|
bc.postMessage({ message: "close" });
|
|
|
|
SpecialPowers.popPrefEnv();
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
// If Fission is disabled, the pref is no-op.
|
|
SpecialPowers.pushPrefEnv({set: [["fission.bfcacheInParent", true]]}, () => {
|
|
runTests(blockBFCacheTests, true);
|
|
runTests(dontBlockBFCacheTests, false);
|
|
});
|
|
}
|
|
|
|
if (isXOrigin) {
|
|
// Bug 1746646: Make mochitests work with TCP enabled (cookieBehavior = 5)
|
|
// Acquire storage access permission here so that the BroadcastChannel used to
|
|
// communicate with the opened windows works in xorigin tests. Otherwise,
|
|
// the iframe containing this page is isolated from first-party storage access,
|
|
// which isolates BroadcastChannel communication.
|
|
SpecialPowers.wrap(document).notifyUserGestureActivation();
|
|
SpecialPowers.addPermission("storageAccessAPI", true, window.location.href).then(() => {
|
|
SpecialPowers.wrap(document).requestStorageAccess().then(() => {
|
|
SpecialPowers.pushPrefEnv({
|
|
set: [["privacy.partition.always_partition_third_party_non_cookie_storage", false]]
|
|
}).then(() => {
|
|
executeTest();
|
|
});
|
|
});
|
|
});
|
|
} else {
|
|
executeTest();
|
|
}
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|