Bug 1687526 - Change test_scrollRestoration.html to use BroadcastChannel, r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D105355
This commit is contained in:
Anny Gakhokidze 2021-02-16 20:38:10 +00:00
parent 0acb14c485
commit 50bc0db905
9 changed files with 425 additions and 170 deletions

View File

@ -1,153 +0,0 @@
<html>
<head>
<script>
var oldHistoryObject = null;
function test(event) {
if (!opener.scrollRestorationTest) {
opener.scrollRestorationTest = 0;
}
++opener.scrollRestorationTest;
switch (opener.scrollRestorationTest) {
case 1: {
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
opener.ok(history.scrollRestoration, "History object has scrollRestoration property.");
opener.is(history.scrollRestoration, "auto", "history.scrollRestoration's default value should be 'auto'.");
history.scrollRestoration = "foobar";
opener.is(history.scrollRestoration, "auto", "Invalid enum value should not change the value of an attribute.");
history.scrollRestoration = "manual";
opener.is(history.scrollRestoration, "manual", "Valid enum value should change the value of an attribute.");
history.scrollRestoration = "auto";
opener.is(history.scrollRestoration, "auto", "Valid enum value should change the value of an attribute.");
document.getElementById("bottom").scrollIntoView();
window.location.reload(false);
break;
}
case 2: {
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
opener.isnot(Math.round(window.scrollY), 0, "Should have restored scrolling.");
opener.is(history.scrollRestoration, "auto", "Should have the same scrollRestoration as before reload.");
history.scrollRestoration = "manual";
window.onunload = function() {}; // Disable bfcache.
window.location.reload(false);
break;
}
case 3: {
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
opener.is(window.scrollY, 0, "Should not have restored scrolling.");
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload.");
document.getElementById("bottom").scrollIntoView();
window.onunload = null; // Should get bfcache behavior.
window.opener.case3WaitForBlank();
window.location.href = "about:blank";
break;
}
case 4: {
opener.is(event.persisted, true, "Should have persisted session history entry.");
opener.isnot(Math.round(window.scrollY), 0, "Should have kept the old scroll position.");
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload.");
window.scrollTo(0, 0);
window.location.hash = "hash";
requestAnimationFrame(test);
break;
}
case 5: {
opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled to #hash.");
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation.");
window.onunload = function() {
opener.setTimeout("is(SpecialPowers.wrap(testWindow).history.scrollRestoration, 'auto'); SpecialPowers.wrap(testWindow).history.back();", 250);
}; // Disable bfcache.
window.location.href = "about:blank";
break;
}
case 6: {
opener.is(event.persisted, false, "Shouldn't have persisted session history entry.");
opener.is(window.scrollY, 0, "Shouldn't have kept the old scroll position.");
opener.is(history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation.");
history.scrollRestoration = "auto";
document.getElementById("bottom").scrollIntoView();
history.pushState({ state: "state1" }, "state1");
history.pushState({ state: "state2" }, "state2");
window.scrollTo(0, 0);
history.back();
setTimeout(test);
break;
}
case 7: {
opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled back to the state1's position");
opener.is(history.state.state, "state1", "Unexpected state.");
history.scrollRestoration = "manual";
document.getElementById("bottom").scrollIntoView();
history.pushState({ state: "state3" }, "state3");
history.pushState({ state: "state4" }, "state4");
window.scrollTo(0, 0);
history.back();
setTimeout(test);
break;
}
case 8: {
opener.is(Math.round(window.scrollY), 0, "Shouldn't have scrolled back to the state3's position");
opener.is(history.state.state, "state3", "Unexpected state.");
history.pushState({ state: "state5" }, "state5");
history.scrollRestoration = "auto";
document.getElementById("bottom").scrollIntoView();
opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled to 'bottom'.");
history.back();
setTimeout(test);
break;
}
case 9: {
window.scrollTo(0, 0);
history.forward();
setTimeout(test);
break;
}
case 10: {
opener.isnot(Math.round(window.scrollY), 0, "Should have scrolled back to the state5's position");
var ifr = document.createElement("iframe");
ifr.src = "data:text/html,";
document.body.appendChild(ifr);
ifr.onload = test;
break;
}
case 11: {
oldHistoryObject = SpecialPowers.wrap(event.target).contentWindow.history;
event.target.src = "about:blank";
break;
}
case 12: {
try {
oldHistoryObject.scrollRestoration;
opener.ok(false, "Should have thrown an exception.");
} catch (ex) {
opener.isnot(ex, null, "Did get an exception");
}
try {
oldHistoryObject.scrollRestoration = "auto";
opener.ok(false, "Should have thrown an exception.");
} catch (ex) {
opener.isnot(ex, null, "Did get an exception");
}
opener.finishTest();
break;
}
}
}
window.addEventListener("pageshow",
function(e) {
setTimeout(test, 0, e);
});
</script>
</head>
<body>
<div style="border: 1px solid black; height: 5000px;">
&nbsp;</div>
<div id="bottom">Hello world</div>
<a href="#hash" name="hash">hash</a>
</body>
</html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<script>
var bc = new BroadcastChannel("navigate");
window.onload = () => {
bc.onmessage = (event) => {
if (event.data.command == "navigate") {
window.location = event.data.location;
bc.close();
}
if (event.data.command == "back") {
history.back();
bc.close();
}
}
bc.postMessage({command: "loaded", scrollRestoration: history.scrollRestoration});
}
</script>

View File

@ -0,0 +1,63 @@
<html>
<head>
<script>
var oldHistoryObject = null;
var bc = new BroadcastChannel("bug1155730_part1");
bc.onmessage = (msgEvent) => {
var msg = msgEvent.data;
var command = msg.command;
if (command == "test") {
var currentCase = msg.currentCase;
test(currentCase);
}
}
function test(currentCase) {
var assertIs = [];
var assertOk = [];
var assertIsNot = [];
switch (currentCase) {
case 1: {
assertOk.push([history.scrollRestoration, "History object has scrollRestoration property."]);
assertIs.push([history.scrollRestoration, "auto", "history.scrollRestoration's default value should be 'auto'."]);
history.scrollRestoration = "foobar";
assertIs.push([history.scrollRestoration, "auto", "Invalid enum value should not change the value of an attribute."]);
history.scrollRestoration = "manual";
assertIs.push([history.scrollRestoration, "manual", "Valid enum value should change the value of an attribute."]);
history.scrollRestoration = "auto";
assertIs.push([history.scrollRestoration, "auto", "Valid enum value should change the value of an attribute."]);
bc.postMessage({command: "asserts", currentCase, assertIs, assertOk});
document.getElementById("bottom").scrollIntoView();
window.location.reload(false);
break;
}
case 2: {
assertIsNot.push([Math.round(window.scrollY), 0, "Should have restored scrolling."]);
assertIs.push([history.scrollRestoration, "auto", "Should have the same scrollRestoration as before reload."]);
history.scrollRestoration = "manual";
bc.postMessage({command: "asserts", currentCase, assertIs, assertIsNot});
window.location.reload(false);
break;
}
case 3: {
assertIs.push([window.scrollY, 0, "Should not have restored scrolling."]);
assertIs.push([history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload."]);
bc.postMessage({command: "asserts", currentCase, assertIs});
bc.close();
window.close();
break;
}
}
}
window.onpageshow = (event) => {
bc.postMessage({command: "pageshow", persisted: event.persisted});
}
</script>
</head>
<body>
<div style="border: 1px solid black; height: 5000px;">
&nbsp;</div>
<div id="bottom">Hello world</div>
<a href="#hash" name="hash">hash</a>
</body>
</html>

View File

@ -0,0 +1 @@
Cache-control: no-store

View File

@ -0,0 +1,57 @@
<html>
<head>
<script>
var bc = new BroadcastChannel("bug1155730_part2");
bc.onmessage = (msgEvent) => {
var msg = msgEvent.data;
var command = msg.command;
if (command == "test") {
var currentCase = msg.currentCase;
test(currentCase);
}
}
function test(currentCase) {
var assertIs = [];
var assertIsNot = [];
switch (currentCase) {
case 1: {
history.scrollRestoration = "manual";
document.getElementById("bottom").scrollIntoView();
window.location.href = "file_scrollRestoration_navigate.html";
break;
}
case 2: {
assertIsNot.push([Math.round(window.scrollY), 0, "Should have kept the old scroll position."]);
assertIs.push([history.scrollRestoration, "manual", "Should have the same scrollRestoration as before reload."]);
bc.postMessage({command: "asserts", currentCase, assertIs, assertIsNot, assert2: "assert2"});
window.scrollTo(0, 0);
window.location.hash = "hash";
bc.postMessage({command: "nextCase"});
requestAnimationFrame(() => {
test(currentCase + 1);
});
break;
}
case 3: {
assertIsNot.push([Math.round(window.scrollY), 0, "Should have scrolled to #hash."]);
assertIs.push([history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation."]);
bc.postMessage({command: "asserts", currentCase, assertIs, assertIsNot});
bc.close();
window.close();
break;
}
}
}
window.onpageshow = (event) => {
bc.postMessage({command: "pageshow", persisted: event.persisted});
}
</script>
</head>
<body>
<div style="border: 1px solid black; height: 5000px;">
&nbsp;</div>
<div id="bottom">Hello world</div>
<a href="#hash" name="hash">hash</a>
</body>
</html>

View File

@ -0,0 +1,156 @@
<html>
<head>
<script>
var oldHistoryObject = null;
var currCaseForIframe = 0;
var bc = new BroadcastChannel("bug1155730_part3");
bc.onmessage = (msgEvent) => {
var msg = msgEvent.data;
var command = msg.command;
if (command == "test") {
var currentCase = msg.currentCase;
test(currentCase);
}
}
// If onpopstate event takes place, check if we need to call 'test()'
var callTest = false;
var nextCase = 0;
window.onpopstate = (e) => {
if (callTest) {
callTest = false;
setTimeout(() => {
test(nextCase);
});
}
}
function test(currentCase) {
var assertIs = [];
var assertOk = [];
var assertIsNot = [];
switch (currentCase) {
case 1: {
history.scrollRestoration = "manual";
window.location.hash = "hash";
bc.postMessage({command: "nextCase"});
requestAnimationFrame(() => {
test(currentCase + 1);
});
break;
}
case 2: {
assertIsNot.push([Math.round(window.scrollY), 0, "Should have scrolled to #hash."]);
assertIs.push([history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation."]);
bc.postMessage({command: "asserts", currentCase, assertIs, assertIsNot});
window.location.href = "file_scrollRestoration_navigate.html";
break;
}
case 3: {
assertIs.push([window.scrollY, 0, "Shouldn't have kept the old scroll position."]);
assertIs.push([history.scrollRestoration, "manual", "Should have the same scrollRestoration mode as before fragment navigation."]);
bc.postMessage({command: "asserts", currentCase, assertIs});
history.scrollRestoration = "auto";
document.getElementById("bottom").scrollIntoView();
history.pushState({ state: "state1" }, "state1");
history.pushState({ state: "state2" }, "state2");
window.scrollTo(0, 0);
bc.postMessage({command: "nextCase"});
callTest = true;
nextCase = currentCase + 1;
history.back(); // go back to state 1
break;
}
case 4: {
assertIsNot.push([Math.round(window.scrollY), 0, "Should have scrolled back to the state1's position"]);
assertIs.push([history.state.state, "state1", "Unexpected state."]);
bc.postMessage({command: "asserts", currentCase, assertIs, assertIsNot});
history.scrollRestoration = "manual";
document.getElementById("bottom").scrollIntoView();
history.pushState({ state: "state3" }, "state3");
history.pushState({ state: "state4" }, "state4");
window.scrollTo(0, 0);
bc.postMessage({command: "nextCase"});
callTest = true;
nextCase = currentCase + 1;
history.back(); // go back to state 3
break;
}
case 5: {
assertIs.push([Math.round(window.scrollY), 0, "Shouldn't have scrolled back to the state3's position"]);
assertIs.push([history.state.state, "state3", "Unexpected state."]);
history.pushState({ state: "state5" }, "state5");
history.scrollRestoration = "auto";
document.getElementById("bottom").scrollIntoView();
assertIsNot.push([Math.round(window.scrollY), 0, "Should have scrolled to 'bottom'."]);
bc.postMessage({command: "asserts", currentCase, assertIs, assertIsNot});
bc.postMessage({command: "nextCase"});
callTest = true;
nextCase = currentCase + 1;
history.back(); // go back to state 4
break;
}
case 6: {
window.scrollTo(0, 0);
bc.postMessage({command: "nextCase"});
callTest = true;
nextCase = currentCase + 1;
history.forward();
break;
}
case 7: {
assertIsNot.push([Math.round(window.scrollY), 0, "Should have scrolled back to the state5's position"]);
bc.postMessage({command: "asserts", currentCase, assertIsNot});
var ifr = document.createElement("iframe");
ifr.src = "data:text/html,";
document.body.appendChild(ifr);
bc.postMessage({command: "nextCase"});
currCaseForIframe = currentCase + 1;
ifr.onload = () => {
test(currCaseForIframe);
};
break;
}
case 8: {
oldHistoryObject = SpecialPowers.wrap(document.getElementsByTagName("iframe")[0]).contentWindow.history;
bc.postMessage({command: "nextCase"});
currCaseForIframe++;
document.getElementsByTagName("iframe")[0].src = "about:blank";
break;
}
case 9: {
try {
oldHistoryObject.scrollRestoration;
assertOk.push([false, "Should have thrown an exception."]);
} catch (ex) {
assertOk.push([ex != null, "Did get an exception"]);
}
try {
oldHistoryObject.scrollRestoration = "auto";
assertOk.push([false, "Should have thrown an exception."]);
} catch (ex) {
assertOk.push([ex != null, "Did get an exception"]);
}
bc.postMessage({command: "asserts", currentCase, assertOk});
bc.postMessage({command: "finishing"});
bc.close();
window.close();
break;
}
}
}
window.onpageshow = (event) => {
bc.postMessage({command: "pageshow", persisted: event.persisted});
}
</script>
</head>
<body>
<div style="border: 1px solid black; height: 5000px;">
&nbsp;</div>
<div id="bottom">Hello world</div>
<a href="#hash" name="hash">hash</a>
</body>
</html>

View File

@ -0,0 +1 @@
Cache-control: no-store

View File

@ -19,7 +19,6 @@ support-files =
file_fragment_handling_during_load_frame2.sjs
file_nested_frames.html
file_nested_frames_innerframe.html
file_scrollRestoration.html
file_shiftReload_and_pushState.html
file_static_and_dynamic_1.html
frame0.html
@ -61,6 +60,12 @@ support-files =
test_bug145971.html
file_bug1609475.html
file_bug1379762-1.html
file_scrollRestoration_navigate.html
file_scrollRestoration_part1_nobfcache.html
file_scrollRestoration_part1_nobfcache.html^headers^
file_scrollRestoration_part2_bfcache.html
file_scrollRestoration_part3_nobfcache.html
file_scrollRestoration_part3_nobfcache.html^headers^
[test_aboutblank_change_process.html]
[test_bug13871.html]

View File

@ -19,23 +19,131 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=
SimpleTest.waitForExplicitFinish();
SimpleTest.requestFlakyTimeout("untriaged");
var testWindow;
function assertCheck(data) {
if (data.assertIs) {
for (const args of data.assertIs) {
is(args[0], args[1], args[2]);
}
}
if (data.assertOk) {
for (const args of data.assertOk) {
ok(args[0], args[1]);
}
}
if (data.assertIsNot) {
for (const args of data.assertIsNot) {
isnot(args[0], args[1], args[2]);
}
}
}
var bc1, currentCase = 0;
function test1() {
bc1 = new BroadcastChannel("bug1155730_part1");
bc1.onmessage = (msgEvent) => {
var msg = msgEvent.data;
var command = msg.command;
if (command == "pageshow") {
currentCase++;
var persisted = msg.persisted;
is(persisted, false, "Shouldn't have persisted session history entry.");
bc1.postMessage({command: "test", currentCase});
} else if (command == "asserts") {
is(msg.currentCase, currentCase, "correct case");
info(`Checking asserts for case ${msg.currentCase}`);
assertCheck(msg);
if (currentCase == 3) {
// move on to the next test
bc1.close();
test2();
}
}
}
window.open("file_scrollRestoration_part1_nobfcache.html", "", "width=360,height=480,noopener");
}
var bc2, bc2navigate;
function test2() {
currentCase = 0;
bc2 = new BroadcastChannel("bug1155730_part2");
bc2.onmessage = (msgEvent) => {
var msg = msgEvent.data;
var command = msg.command;
if (command == "pageshow") {
currentCase++;
var persisted = msg.persisted;
switch (currentCase) {
case 1:
is(persisted, false, "Shouldn't have persisted session history entry.");
break;
case 2:
is(persisted, true, "Should have persisted session history entry.");
}
bc2.postMessage({command: "test", currentCase});
} else if (command == "asserts") {
is(msg.currentCase, currentCase, "correct case");
info(`Checking asserts for case ${msg.currentCase}`);
assertCheck(msg);
if (currentCase == 3) {
// move on to the next test
bc2.close();
test3();
}
} else if (command == "nextCase") {
currentCase++;
}
}
bc2navigate = new BroadcastChannel("navigate");
bc2navigate.onmessage = (event) => {
if (event.data.command == "loaded") {
bc2navigate.postMessage({command: "back"})
bc2navigate.close();
}
}
window.open("file_scrollRestoration_part2_bfcache.html", "", "width=360,height=480,noopener");
}
var bc3, bc3navigate;
function test3() {
currentCase = 0;
bc3 = new BroadcastChannel("bug1155730_part3");
bc3.onmessage = (msgEvent) => {
var msg = msgEvent.data;
var command = msg.command;
if (command == "pageshow") {
currentCase++;
if (currentCase == 3) {
var persisted = msg.persisted;
is(persisted, false, "Shouldn't have persisted session history entry.");
}
bc3.postMessage({command: "test", currentCase});
} else if (command == "asserts") {
is(msg.currentCase, currentCase, "correct case");
info(`Checking asserts for case ${msg.currentCase}`);
assertCheck(msg);
} else if (command == "nextCase") {
currentCase++;
} else if (command == "finishing") {
bc3.close();
SimpleTest.finish();
}
}
bc3navigate = new BroadcastChannel("navigate");
bc3navigate.onmessage = (event) => {
if (event.data.command == "loaded") {
is(event.data.scrollRestoration, 'auto', "correct scroll restoration");
bc3navigate.postMessage({command: "back"})
bc3navigate.close();
}
}
window.open("file_scrollRestoration_part3_nobfcache.html", "", "width=360,height=480,noopener");
}
function runTest() {
testWindow = window.open("file_scrollRestoration.html", "", "width=360,height=480");
testWindow.onunload = function() { }; // to prevent bfcache
}
async function case3WaitForBlank() {
let loaded = SimpleTest.promiseWaitForCondition(() => {
return testWindow.location.href == "about:blank";
});
await loaded;
SpecialPowers.wrap(testWindow).history.back();
}
function finishTest() {
testWindow.close();
SimpleTest.finish();
test1();
}
</script>