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
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3759061
Reviewed-by: Arthur Sonzogni <arthursonzogni@chromium.org>
Commit-Queue: Domenic Denicola <domenic@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1028593}
  • Loading branch information
domenic authored and Chromium LUCI CQ committed Jul 27, 2022
1 parent 27fa2d1 commit 1d65f97
Show file tree
Hide file tree
Showing 7 changed files with 252 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-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-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-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(w);
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,7 @@
<!DOCTYPE html>
<iframe src="/common/blank.html"></iframe>
<script>
window.onload = () => {
window.opener.postMessage("top ready", "*");
};
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
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 = (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 }) => {
if (source === expectedSource) {
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>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This is a testharness.js-based test.
PASS changing srcdoc does a replace navigation since the URL is still about:srcdoc
FAIL changing srcdoc to about:srcdoc#yo then another srcdoc does two push navigations and we can navigate back assert_equals: srcdoc content must be restored from history expected "srcdoc1" but got "srcdoc2"
Harness: the test ran to completion.

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
This is a testharness.js-based test.
FAIL srcdoc history entries: the iframe itself navigates assert_equals: srcdoc contents must be restored from history, not from the current value ('srcdoc2') of the content attribute expected "srcdoc1" but got "srcdoc2"
FAIL srcdoc history entries: the container window navigates assert_equals: srcdoc contents must be restored from history, not from the current value of the (not-existing) content attribute expected (string) "srcdoc1" but got (undefined) undefined
Harness: the test ran to completion.

0 comments on commit 1d65f97

Please sign in to comment.