mirror of
https://github.com/servo/servo.git
synced 2025-07-08 07:53:40 +01:00
Update web-platform-tests to revision 34f9b93c2749043ba68485dea92d1fb554075e60
This commit is contained in:
parent
fd64f11efe
commit
ace02666c2
75 changed files with 1496 additions and 120 deletions
|
@ -0,0 +1,97 @@
|
|||
document.domain = "{{host}}";
|
||||
|
||||
// In many cases in this test, we want to delay execution of a piece of code so
|
||||
// that the entry settings object would be the top-level page. A microtask is
|
||||
// perfect for this purpose as it is executed in the "clean up after running
|
||||
// script" algorithm, which is generally called right after the callback.
|
||||
function setEntryToTopLevel(cb) {
|
||||
Promise.resolve().then(cb);
|
||||
}
|
||||
|
||||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => { iframe.remove(); });
|
||||
iframe.onload = t.step_func_done(() => {
|
||||
// Since this is called as an event handler on an element of this window,
|
||||
// the entry settings object is that of this browsing context.
|
||||
assert_throws("InvalidStateError", () => {
|
||||
iframe.contentDocument.open();
|
||||
}, "opening an XML document should throw an InvalidStateError");
|
||||
});
|
||||
const frameURL = new URL("resources/bailout-order-xml-with-domain-frame.sub.xhtml", document.URL);
|
||||
frameURL.port = "{{ports[http][1]}}";
|
||||
iframe.src = frameURL.href;
|
||||
}, "document.open should throw an InvalidStateError with XML document even if it is cross-origin");
|
||||
|
||||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => { iframe.remove(); });
|
||||
window.onCustomElementReady = t.step_func(() => {
|
||||
window.onCustomElementReady = t.unreached_func("onCustomElementReady called again");
|
||||
// Here, the entry settings object is still the iframe's, as the function
|
||||
// is called from a custom element constructor in the iframe document.
|
||||
// Delay execution in such a way that makes the entry settings object the
|
||||
// top-level page's, but without delaying too much that the
|
||||
// throw-on-dynamic-markup-insertion counter gets decremented (which is
|
||||
// what this test tries to pit against the cross-origin document check).
|
||||
//
|
||||
// "Clean up after running script" is executed through the "construct" Web
|
||||
// IDL algorithm in "create an element", called by "create an element for a
|
||||
// token" in the parser.
|
||||
setEntryToTopLevel(t.step_func_done(() => {
|
||||
assert_throws("InvalidStateError", () => {
|
||||
iframe.contentDocument.open();
|
||||
}, "opening a document when the throw-on-dynamic-markup-insertion counter is incremented should throw an InvalidStateError");
|
||||
}));
|
||||
});
|
||||
const frameURL = new URL("resources/bailout-order-custom-element-with-domain-frame.sub.html", document.URL);
|
||||
frameURL.port = "{{ports[http][1]}}";
|
||||
iframe.src = frameURL.href;
|
||||
}, "document.open should throw an InvalidStateError when the throw-on-dynamic-markup-insertion counter is incremented even if the document is cross-origin");
|
||||
|
||||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => { iframe.remove(); });
|
||||
self.testSynchronousScript = t.step_func(() => {
|
||||
// Here, the entry settings object is still the iframe's, as the function
|
||||
// is synchronously called from a <script> element in the iframe's
|
||||
// document.
|
||||
//
|
||||
// "Clean up after running script" is executed when the </script> tag is
|
||||
// seen by the HTML parser.
|
||||
setEntryToTopLevel(t.step_func_done(() => {
|
||||
assert_throws("SecurityError", () => {
|
||||
iframe.contentDocument.open();
|
||||
}, "opening a same origin-domain (but not same origin) document should throw a SecurityError");
|
||||
}));
|
||||
});
|
||||
const frameURL = new URL("resources/bailout-order-synchronous-script-with-domain-frame.sub.html", document.URL);
|
||||
frameURL.port = "{{ports[http][1]}}";
|
||||
iframe.src = frameURL.href;
|
||||
}, "document.open should throw a SecurityError with cross-origin document even when there is an active parser executing script");
|
||||
|
||||
for (const ev of ["beforeunload", "pagehide", "unload"]) {
|
||||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => { iframe.remove(); });
|
||||
iframe.addEventListener("load", t.step_func(() => {
|
||||
iframe.contentWindow.addEventListener(ev, t.step_func(() => {
|
||||
// Here, the entry settings object should be the top-level page's, as
|
||||
// the callback context of this event listener is the incumbent
|
||||
// settings object, which is the this page. However, due to a Chrome
|
||||
// bug (https://crbug.com/606900), the entry settings object may be
|
||||
// mis-set to the iframe's.
|
||||
//
|
||||
// "Clean up after running script" is called in the task that
|
||||
// navigates.
|
||||
setEntryToTopLevel(t.step_func_done(() => {
|
||||
assert_throws("SecurityError", () => {
|
||||
iframe.contentDocument.open();
|
||||
}, "opening a same origin-domain (but not same origin) document should throw a SecurityError");
|
||||
}));
|
||||
}));
|
||||
iframe.src = "about:blank";
|
||||
}), { once: true });
|
||||
iframe.src = "http://{{host}}:{{ports[http][1]}}/common/domain-setter.sub.html";
|
||||
}, `document.open should throw a SecurityError with cross-origin document even when the ignore-opens-during-unload counter is greater than 0 (during ${ev} event)`);
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => { iframe.remove(); });
|
||||
self.testSynchronousScript = t.step_func_done(() => {
|
||||
assert_throws("InvalidStateError", () => {
|
||||
iframe.contentDocument.open();
|
||||
}, "opening an XML document should throw");
|
||||
});
|
||||
iframe.src = "resources/bailout-order-xml-with-synchronous-script-frame.xhtml";
|
||||
}, "document.open should throw an InvalidStateError with XML document even when there is an active parser executing script");
|
||||
|
||||
for (const ev of ["beforeunload", "pagehide", "unload"]) {
|
||||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => { iframe.remove(); });
|
||||
iframe.addEventListener("load", t.step_func(() => {
|
||||
iframe.contentWindow.addEventListener(ev, t.step_func_done(() => {
|
||||
assert_throws("InvalidStateError", () => {
|
||||
iframe.contentDocument.open();
|
||||
}, "opening an XML document should throw");
|
||||
}));
|
||||
iframe.src = "about:blank";
|
||||
}), { once: true });
|
||||
iframe.src = "/common/dummy.xhtml";
|
||||
}, `document.open should throw an InvalidStateError with XML document even when the ignore-opens-during-unload counter is greater than 0 (during ${ev} event)`);
|
||||
}
|
|
@ -6,11 +6,19 @@ for (const ev of ["unload", "beforeunload", "pagehide"]) {
|
|||
t.add_cleanup(() => iframe.remove());
|
||||
iframe.src = "/common/blank.html";
|
||||
iframe.onload = t.step_func(() => {
|
||||
iframe.contentWindow.addEventListener(ev, t.step_func_done(() => {
|
||||
const origURL = iframe.contentDocument.URL;
|
||||
assertDocumentIsReadyForSideEffectsTest(iframe.contentDocument, `ignore-opens-during-unload counter is greater than 0 during ${ev} event`);
|
||||
assert_equals(iframe.contentDocument.open(), iframe.contentDocument);
|
||||
assertOpenHasNoSideEffects(iframe.contentDocument, origURL, `ignore-opens-during-unload counter is greater than 0 during ${ev} event`);
|
||||
iframe.contentWindow.addEventListener(ev, t.step_func(() => {
|
||||
// Here, the entry settings object could still be the iframe's. Delay
|
||||
// it in such a way that ensures the entry settings object is the
|
||||
// top-level page's, but without delaying too much that the
|
||||
// ignore-opens-during-unload counter becomes decremented. A microtask
|
||||
// is perfect as it's executed immediately in "clean up after running
|
||||
// script".
|
||||
Promise.resolve().then(t.step_func_done(() => {
|
||||
const origURL = iframe.contentDocument.URL;
|
||||
assertDocumentIsReadyForSideEffectsTest(iframe.contentDocument, `ignore-opens-during-unload counter is greater than 0 during ${ev} event`);
|
||||
assert_equals(iframe.contentDocument.open(), iframe.contentDocument);
|
||||
assertOpenHasNoSideEffects(iframe.contentDocument, origURL, `ignore-opens-during-unload counter is greater than 0 during ${ev} event`);
|
||||
}));
|
||||
}));
|
||||
iframe.src = "about:blank";
|
||||
});
|
||||
|
|
|
@ -3,11 +3,17 @@
|
|||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => iframe.remove());
|
||||
self.testSynchronousScript = t.step_func_done(() => {
|
||||
const origURL = iframe.contentDocument.URL;
|
||||
assertDocumentIsReadyForSideEffectsTest(iframe.contentDocument, "active parser whose script nesting level is greater than 0");
|
||||
assert_equals(iframe.contentDocument.open(), iframe.contentDocument);
|
||||
assertOpenHasNoSideEffects(iframe.contentDocument, origURL, "active parser whose script nesting level is greater than 0");
|
||||
self.testSynchronousScript = t.step_func(() => {
|
||||
// Here, the entry settings object is still the iframe's. Delay it in such
|
||||
// a way that makes the entry settings object the top-level page's, but
|
||||
// without delaying too much that the parser becomes inactive. A microtask
|
||||
// is perfect as it's executed in "clean up after running script".
|
||||
Promise.resolve().then(t.step_func_done(() => {
|
||||
const origURL = iframe.contentDocument.URL;
|
||||
assertDocumentIsReadyForSideEffectsTest(iframe.contentDocument, "active parser whose script nesting level is greater than 0");
|
||||
assert_equals(iframe.contentDocument.open(), iframe.contentDocument);
|
||||
assertOpenHasNoSideEffects(iframe.contentDocument, origURL, "active parser whose script nesting level is greater than 0");
|
||||
}));
|
||||
});
|
||||
iframe.src = "resources/bailout-order-synchronous-script-frame.html";
|
||||
}, "document.open bailout should not have any side effects (active parser whose script nesting level is greater than 0)");
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => iframe.remove());
|
||||
iframe.src = "/common/blank.html";
|
||||
iframe.onload = t.step_func_done(() => {
|
||||
const win = iframe.contentWindow;
|
||||
const doc = iframe.contentDocument;
|
||||
assert_equals(win.history.state, null);
|
||||
win.history.replaceState("state", "");
|
||||
assert_equals(win.history.state, "state");
|
||||
assert_equals(doc.open(), doc);
|
||||
assert_equals(win.history.state, "state");
|
||||
});
|
||||
}, "history.state is kept by document.open()");
|
||||
|
||||
async_test(t => {
|
||||
const iframe = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => iframe.remove());
|
||||
iframe.src = "/common/blank.html";
|
||||
iframe.onload = t.step_func_done(() => {
|
||||
const win = iframe.contentWindow;
|
||||
const doc = iframe.contentDocument;
|
||||
assert_equals(win.history.state, null);
|
||||
win.history.replaceState("state", "");
|
||||
assert_equals(win.history.state, "state");
|
||||
assert_equals(doc.open("", "replace"), doc);
|
||||
assert_equals(win.history.state, "state");
|
||||
});
|
||||
}, "history.state is kept by document.open() (with historical replace parameter set)");
|
|
@ -0,0 +1,71 @@
|
|||
// This test tests for the nonexistence of a reload override buffer, which is
|
||||
// used in a previous version of the HTML Standard to make reloads of a
|
||||
// document.open()'d document load the written-to document rather than doing an
|
||||
// actual reload of the document's URL.
|
||||
//
|
||||
// This test has a somewhat interesting structure compared to the other tests
|
||||
// in this directory. It eschews the <iframe> structure used by other tests,
|
||||
// since when the child frame is reloaded it would adopt the URL of the test
|
||||
// page (the responsible document of the entry settings object), and the spec
|
||||
// forbids navigation in nested browsing contexts to the same URL as their
|
||||
// parent. To work around that, we use window.open() which does not suffer from
|
||||
// that restriction.
|
||||
//
|
||||
// In any case, this test as the caller of `document.open()` would be used both
|
||||
// as the test file and as part of the test file. The `if (!opener)` condition
|
||||
// controls what role this file plays.
|
||||
|
||||
if (!opener) {
|
||||
async_test(t => {
|
||||
const testURL = document.URL;
|
||||
const dummyURL = new URL("resources/dummy.html", document.URL).href;
|
||||
|
||||
// 1. Open an auxiliary window.
|
||||
const win = window.open("resources/dummy.html");
|
||||
t.add_cleanup(() => { win.close(); });
|
||||
|
||||
win.addEventListener("load", t.step_func(() => {
|
||||
// The timeout seems to be necessary for Firefox, which when `load` is
|
||||
// called may still have an active parser.
|
||||
t.step_timeout(() => {
|
||||
const doc = win.document;
|
||||
assert_true(doc.body.textContent.includes("Dummy"), "precondition");
|
||||
assert_equals(doc.URL, dummyURL, "precondition");
|
||||
|
||||
window.onChildLoad = t.step_func(message => {
|
||||
// 3. The dynamically overwritten content will trigger this function,
|
||||
// which puts in place the actual test.
|
||||
|
||||
assert_equals(message, "Written", "script on written page is executed");
|
||||
assert_true(win.document.body.textContent.includes("Content"), "page is written to");
|
||||
assert_equals(win.document.URL, testURL, "postcondition: after document.write()");
|
||||
assert_equals(win.document, doc, "document.open should not change the document object");
|
||||
window.onChildLoad = t.step_func_done(message => {
|
||||
// 6. This function should be called from the if (opener) branch of
|
||||
// this file. It would throw an assertion error if the overwritten
|
||||
// content was executed instead.
|
||||
assert_equals(message, "Done!", "actual test");
|
||||
assert_true(win.document.body.textContent.includes("Back to the test"), "test is reloaded");
|
||||
assert_equals(win.document.URL, testURL, "postcondition: after reload");
|
||||
assert_not_equals(win.document, doc, "reload should change the document object");
|
||||
});
|
||||
|
||||
// 4. Reload the pop-up window. Because of the doc.open() call, this
|
||||
// pop-up window will reload to the same URL as this test itself.
|
||||
win.location.reload();
|
||||
});
|
||||
|
||||
// 2. When it is loaded, dynamically overwrite its content.
|
||||
assert_equals(doc.open(), doc);
|
||||
assert_equals(doc.URL, testURL, "postcondition: after document.open()");
|
||||
doc.write("<p>Content</p><script>opener.onChildLoad('Written');</script>");
|
||||
doc.close();
|
||||
}, 100);
|
||||
}), { once: true });
|
||||
}, "Reloading a document.open()'d page should reload the URL of the entry realm's responsible document");
|
||||
} else {
|
||||
document.write("<p>Back to the test</p>");
|
||||
// 5. Since this window is window.open()'d, opener refers to the test window.
|
||||
// Inform the opener that reload succeeded.
|
||||
opener.onChildLoad("Done!");
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
<p>Text</p>
|
||||
<script>
|
||||
document.domain = "{{host}}";
|
||||
|
||||
class CustomElement extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
parent.onCustomElementReady();
|
||||
}
|
||||
}
|
||||
customElements.define("custom-element", CustomElement);
|
||||
</script>
|
||||
<custom-element></custom-element>
|
|
@ -0,0 +1,5 @@
|
|||
<p>Text</p>
|
||||
<script>
|
||||
document.domain = "{{host}}";
|
||||
parent.testSynchronousScript();
|
||||
</script>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head><title>XHTML document with domain set</title></head>
|
||||
<body>
|
||||
<p>Text</p>
|
||||
<script>
|
||||
document.domain = "{{host}}";
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,11 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head><title>XHTML document with hook to run script from a script tag</title></head>
|
||||
<body>
|
||||
<p>Text</p>
|
||||
<script>
|
||||
parent.testSynchronousScript();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,2 @@
|
|||
<!-- Like /common/blank.html, but with some content in it. -->
|
||||
<p>Dummy</p>
|
|
@ -21,7 +21,7 @@ function taskTest(description, testBody) {
|
|||
// The empty HTML seems to be necessary to cajole Chrome and Safari into
|
||||
// firing a load event asynchronously, which is necessary to make sure the
|
||||
// frame's document doesn't have a parser associated with it.
|
||||
// See: https://crbug.com/875354
|
||||
// See: https://crbug.com/569511
|
||||
frame.src = "/common/blank.html";
|
||||
t.add_cleanup(() => frame.remove());
|
||||
frame.onload = t.step_func(() => {
|
||||
|
@ -39,7 +39,7 @@ function taskTest(description, testBody) {
|
|||
// The empty HTML seems to be necessary to cajole Chrome into firing a load
|
||||
// event, which is necessary to make sure the frame's document doesn't have
|
||||
// a parser associated with it.
|
||||
// See: https://crbug.com/875354
|
||||
// See: https://crbug.com/569511
|
||||
frame.src = "/common/blank.html";
|
||||
t.add_cleanup(() => frame.remove());
|
||||
frame.onload = t.step_func(() => {
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
test(t => {
|
||||
const frame = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => frame.remove());
|
||||
assert_equals(frame.contentDocument.URL, "about:blank");
|
||||
assert_equals(frame.contentWindow.location.href, "about:blank");
|
||||
frame.contentDocument.open();
|
||||
assert_equals(frame.contentDocument.URL, document.URL);
|
||||
assert_equals(frame.contentWindow.location.href, document.URL);
|
||||
}, "document.open() changes document's URL (fully active document)");
|
||||
|
||||
async_test(t => {
|
||||
const blankURL = new URL("/common/blank.html", document.URL).href;
|
||||
const frameURL = new URL("resources/page-with-frame.html", document.URL).href;
|
||||
const frame = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => frame.remove());
|
||||
frame.onload = t.step_func(() => {
|
||||
assert_equals(frame.contentDocument.URL, frameURL);
|
||||
assert_equals(frame.contentWindow.location.href, frameURL);
|
||||
const childFrame = frame.contentDocument.querySelector("iframe");
|
||||
const childDoc = childFrame.contentDocument;
|
||||
const childWin = childFrame.contentWindow;
|
||||
assert_equals(childDoc.URL, blankURL);
|
||||
assert_equals(childWin.location.href, blankURL);
|
||||
|
||||
// Right now childDoc is still fully active.
|
||||
|
||||
frame.onload = t.step_func_done(() => {
|
||||
// Now childDoc is still active but no longer fully active.
|
||||
childDoc.open();
|
||||
assert_equals(childDoc.URL, blankURL);
|
||||
assert_equals(childWin.location.href, blankURL);
|
||||
});
|
||||
frame.src = "/common/blank.html";
|
||||
});
|
||||
frame.src = frameURL;
|
||||
}, "document.open() does not change document's URL (active but not fully active document)");
|
||||
|
||||
test(t => {
|
||||
const frame = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => frame.remove());
|
||||
const doc = frame.contentDocument;
|
||||
|
||||
// Right now the frame is connected and it has an active document.
|
||||
assert_equals(doc.URL, "about:blank");
|
||||
|
||||
frame.remove();
|
||||
|
||||
// Now the frame is no longer connected. Its document is no longer active.
|
||||
assert_equals(doc.URL, "about:blank");
|
||||
assert_equals(doc.open(), doc);
|
||||
assert_equals(doc.URL, "about:blank");
|
||||
}, "document.open() does not change document's URL (non-active document with an associated Window object; frame is removed)");
|
||||
|
||||
async_test(t => {
|
||||
const frame = document.createElement("iframe");
|
||||
t.add_cleanup(() => frame.remove());
|
||||
|
||||
frame.onload = t.step_func(() => {
|
||||
const doc = frame.contentDocument;
|
||||
// Right now the frame is connected and it has an active document.
|
||||
assert_equals(doc.URL, "about:blank");
|
||||
|
||||
frame.onload = t.step_func_done(() => {
|
||||
// Now even though the frame is still connected, its document is no
|
||||
// longer active.
|
||||
assert_not_equals(frame.contentDocument, doc);
|
||||
assert_equals(doc.URL, "about:blank");
|
||||
assert_equals(doc.open(), doc);
|
||||
assert_equals(doc.URL, "about:blank");
|
||||
});
|
||||
|
||||
frame.src = "/common/blank.html";
|
||||
});
|
||||
|
||||
// We need to connect the frame after the load event is set up to mitigate
|
||||
// against https://crbug.com/569511.
|
||||
document.body.appendChild(frame);
|
||||
}, "document.open() does not change document's URL (non-active document with an associated Window object; navigated away)");
|
||||
|
||||
test(t => {
|
||||
const frame = document.body.appendChild(document.createElement("iframe"));
|
||||
t.add_cleanup(() => frame.remove());
|
||||
const doc = frame.contentDocument.implementation.createHTMLDocument();
|
||||
assert_equals(doc.URL, "about:blank");
|
||||
assert_equals(doc.open(), doc);
|
||||
assert_equals(doc.URL, "about:blank");
|
||||
}, "document.open() does not change document's URL (non-active document without an associated Window object)");
|
Loading…
Add table
Add a link
Reference in a new issue