Skip to content

Commit

Permalink
WPT: test srcdoc + session history interactions
Browse files Browse the repository at this point in the history
See discussion in whatwg/html#6809.

Bug: 1344417
Change-Id: Iec66ca607fab98d37fbaddba26c2428ab65bd70e
  • Loading branch information
domenic authored and chromium-wpt-export-bot committed Jul 25, 2022
1 parent 3aadc8d commit 719de39
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>changing srcdoc to a different srcdoc</title>
<link rel="help" href="https://github.com/whatwg/html/issues/6809#issuecomment-905677979">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../resources/helpers.js"></script>

<script>
"use strict";

// Note: bfcache won't mess with any windows with openers, so it doesn't
// interfere with these tests.

promise_test(async t => {
// Set up a window whose iframe contains [normal page, srcdoc] entries.
const w = await openWindow("../../resources/has-common-blank-iframe.html", t);
const iframe = w.document.querySelector("iframe");

await waitToAvoidReplace(t);
iframe.srcdoc = srcdocThatPostsParentOpener("srcdoc1");
await waitForMessage(iframe.contentWindow);

assert_equals(w.history.length, 2);

// Now navigate to a different srcdoc
iframe.srcdoc = srcdocThatPostsParentOpener("srcdoc2");

// Test that it's a replace.
await waitForMessage(iframe.contentWindow);
assert_equals(w.history.length, 2,
"history.length must not change since it was a replace");
assert_equals(
iframe.contentDocument.querySelector("p").textContent,
"srcdoc2",
"Sanity check: the srcdoc document did indeed update"
);
}, "changing srcdoc does a replace navigation since the URL is still " +
"about:srcdoc");

promise_test(async t => {
// Set up a window whose iframe contains [normal page, srcdoc] entries.
const w = await openWindow("../../resources/has-common-blank-iframe.html", t);
const iframe = w.document.querySelector("iframe");

await waitToAvoidReplace(t);
iframe.srcdoc = srcdocThatPostsParentOpener("srcdoc1");
await waitForMessage(iframe.contentWindow);

assert_equals(w.history.length, 2);

// Now navigate to about:srcdoc#yo
iframe.contentWindow.location.href = "about:srcdoc#yo";
assert_equals(iframe.contentWindow.location.href, "about:srcdoc#yo");
assert_equals(w.history.length, 3);

// Now navigate to a different srcdoc
iframe.srcdoc = srcdocThatPostsParentOpener("srcdoc2");

// Test that it's a push back to about:srcdoc.
await waitForMessage(iframe.contentWindow);
assert_equals(
w.history.length,
4,
"history.length must increase since it was a push"
);
assert_equals(iframe.contentWindow.location.href, "about:srcdoc");
assert_equals(
iframe.contentDocument.querySelector("p").textContent,
"srcdoc2",
"Sanity check: the srcdoc document did indeed update"
);

// Test that we can go back to about:srcdoc#yo.
w.history.back();
await waitForMessage(iframe.contentWindow);
assert_equals(iframe.contentWindow.location.href, "about:srcdoc#yo");
assert_equals(
iframe.contentDocument.querySelector("p").textContent,
"srcdoc1",
"srcdoc content must be restored from history"
);
}, "changing srcdoc to about:srcdoc#yo then another srcdoc does two push " +
"navigations and we can navigate back");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>srcdoc history entries</title>
<link rel="help" href="https://github.com/whatwg/html/issues/6809">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../resources/helpers.js"></script>

<script>
"use strict";

// Note: bfcache won't mess with any windows with openers, so it doesn't
// interfere with these tests.

promise_test(async t => {
// Set up a window whose iframe contains
// [normal page, srcdoc, normal page, srcdoc] entries.
const w = await openWindow("/common/blank.html", t);
const iframe = await addIframe("/common/blank.html?iframe", w.document);

assert_equals(w.history.length, 1);

await waitToAvoidReplace(t);
iframe.srcdoc = srcdocThatPostsParentOpener("srcdoc1");
assert_equals(w.history.length, 1, "srcdoc navigation must not be sync");

await waitForMessage(iframe.contentWindow);
assert_equals(w.history.length, 2);

await waitToAvoidReplace(t);
const middleURL = (new URL(
"../../resources/post-top-opener-on-load.html", location.href)).href;
iframe.contentWindow.location.href = middleURL;

await waitForMessage(iframe.contentWindow);
assert_equals(w.history.length, 3);

await waitToAvoidReplace(t);
iframe.srcdoc = srcdocThatPostsParentOpener("srcdoc2");
assert_equals(w.history.length, 3, "srcdoc navigation must not be sync");

await waitForMessage(iframe.contentWindow);
assert_equals(w.history.length, 4);

// Now test traversal.
w.history.back();
await waitForMessage(iframe.contentWindow);
assert_equals(iframe.contentWindow.location.href, middleURL);

await waitToAvoidReplace(t);

w.history.back();
await waitForMessage(iframe.contentWindow);
assert_equals(iframe.contentWindow.location.href, "about:srcdoc");
assert_equals(
iframe.contentDocument.querySelector("p").textContent,
"srcdoc1",
"srcdoc contents must be restored from history, not from the current " +
"value ('srcdoc2') of the content attribute"
);
}, "srcdoc history entries: the iframe itself navigates");

promise_test(async t => {
// Set up a window whose iframe contains [normal page, srcdoc] entries.
const w = await openWindow("../../resources/has-common-blank-iframe.html", t);
const iframe = w.document.querySelector("iframe");

assert_equals(w.history.length, 1);

await waitToAvoidReplace(t);
iframe.srcdoc = srcdocThatPostsParentOpener("srcdoc1");
assert_equals(w.history.length, 1, "srcdoc navigation must not be sync");

await waitForMessage(iframe.contentWindow);
assert_equals(w.history.length, 2);

// Now navigate the window itself.
w.location.href = "../../resources/post-top-opener-on-load.html";
await waitForMessage(w);
assert_equals(w.history.length, 3);

// Now test traversal.
w.history.back();
await waitForMessage(/* cannot easily get the source; assume it's correct */);
const iframeAgain = w.document.querySelector("iframe");

assert_equals(iframeAgain.contentWindow.location.href, "about:srcdoc");
assert_equals(
iframeAgain.contentDocument.querySelector("p").textContent,
"srcdoc1",
"srcdoc contents must be restored from history, not from the current " +
"value of the (not-existing) content attribute"
);
}, "srcdoc history entries: the container window navigates");
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<!DOCTYPE html>
<iframe src="/common/blank.html"></iframe>
53 changes: 53 additions & 0 deletions html/browsers/browsing-the-web/resources/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
window.openWindow = (url, t) => {
const w = window.open(url);
t?.add_cleanup(() => w.close());

return new Promise(resolve => {
w.addEventListener("load", () => resolve(w), { once: true });
});
};

window.addIframe = async (url = "/common/blank.html", doc = document) => {
const iframe = doc.createElement("iframe");
iframe.src = url;
doc.body.append(iframe);

return new Promise(resolve => {
iframe.addEventListener("load", () => resolve(iframe), { once: true });
});
};

window.waitToAvoidReplace = t => {
return new Promise(resolve => t.step_timeout(resolve, 0));
};

window.waitForMessage = expectedSource => {
return new Promise(resolve => {
window.addEventListener("message", ({ source, data }) => {
// We allow expectedSource === undefined for rare cases where you cannot
// get a handle to the source, e.g., the expected source is an iframe and
// you are doing a navigation that creates the iframe. This should be used
// sparingly.
if (source === expectedSource || expectedSource === undefined) {
resolve(data);
}
});
});
};

window.waitForHashchange = w => {
return new Promise(resolve => {
w.addEventListener("hashchange", () => resolve(), { once: true });
});
};

window.srcdocThatPostsParentOpener = text => {
return `
<p>${text}</p>
<script>
window.onload = () => {
window.top.opener.postMessage('ready', '*');
};
<\/script>
`;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<!DOCTYPE html>
<script>
window.onload = () => {
window.top.opener.postMessage("ready", "*");
};
</script>

0 comments on commit 719de39

Please sign in to comment.