Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WPT: test srcdoc + session history interactions #34843

Merged
merged 1 commit into from
Jul 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>
7 changes: 7 additions & 0 deletions html/browsers/browsing-the-web/resources/has-iframe.html
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>
49 changes: 49 additions & 0 deletions html/browsers/browsing-the-web/resources/helpers.js
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>