Bug 1892041 - Part 1: Update test262 features. r=spidermonkey-reviewers,dminor
[gecko.git] / dom / base / test / test_blockParsing.html
blobaf4c8aaac5e80a9771e58b3fda58d5a8219ac40c
1 <!DOCTYPE HTML>
2 <html>
3 <head>
4 <title>Test for document.blockParsing</title>
5 <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
6 <link rel="stylesheet" href="chrome://mochikit/content/tests/SimpleTest/test.css">
7 </head>
8 <body>
9 <script>
10 const {TestUtils} = ChromeUtils.importESModule(
11 "resource://testing-common/TestUtils.sys.mjs"
14 async function runTest(url, initialHTML, finalHTML) {
15 let iframe = document.createElement("iframe");
16 iframe.src = url;
18 let blockerPromise;
19 let promise = TestUtils.topicObserved("document-element-inserted", document => {
20 if (document !== iframe.contentDocument) {
21 return false;
24 blockerPromise = new Promise(resolve => {
25 setTimeout(resolve, 0);
26 }).then(() => {
27 return new Promise(resolve => setTimeout(resolve, 0));
28 }).then(() => {
29 return new Promise(resolve => setTimeout(resolve, 0));
30 });
32 is(document.documentElement.outerHTML, initialHTML,
33 "Should have initial HTML during document-element-inserted");
34 is(document.defaultView.wrappedJSObject.scriptRan, undefined,
35 "Script node should not have run");
37 document.blockParsing(blockerPromise);
39 return true;
40 }).then(([document]) => {
41 return document;
42 });
44 document.body.appendChild(iframe);
46 // Wait for document-element-inserted to fire.
47 let doc = await promise;
48 let win = doc.defaultView.wrappedJSObject;
49 let root = doc.documentElement;
51 // At this point, if the parser was successfully blocked, we should still
52 // have the initial skeleton HTML for the page.
53 is(root.outerHTML, initialHTML, "Should have initial HTML after document-element-inserted returns");
54 is(win.scriptRan, undefined, "Script node should still not have run");
56 await blockerPromise;
58 // Just after the promise that's blocking the parser fires, we shouldn't have
59 // returned to the main event loop, so we should still have the initial HTML.
60 is(root.outerHTML, initialHTML, "Should still have initial HTML");
61 is(win.scriptRan, undefined, "Script node should still not have run");
63 await new Promise(resolve => win.addEventListener("DOMContentLoaded", resolve, {once: true}));
65 // Parsing should have resumed, and we should have finished loading the document.
66 is(root.outerHTML, finalHTML, "Should have final HTML");
67 is(win.scriptRan, true, "Script node should have run");
69 iframe.remove();
72 add_task(async function() {
73 await runTest("http://mochi.test:8888/chrome/dom/base/test/file_inline_script.html",
74 '<html lang="en"></html>',
75 '<html lang="en"><head>\n <script>window.scriptRan = true;<\/script>\n <meta charset="utf-8">\n <title></title>\n</head>\n<body>\n <p>Hello Mochitest</p>\n\n\n</body></html>');
77 await runTest("http://mochi.test:8888/chrome/dom/base/test/file_inline_script.xhtml",
78 '<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"></html>',
79 '<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">\n<head>\n <script>window.scriptRan = true;<\/script>\n <title></title>\n</head>\n<body>\n <p>Hello Mochitest</p>\n</body>\n</html>');
81 await runTest("http://mochi.test:8888/chrome/dom/base/test/file_external_script.html",
82 '<html lang="en"></html>',
83 '<html lang="en"><head>\n <script src="file_script.js"><\/script>\n <meta charset="utf-8">\n <title></title>\n</head>\n<body>\n <p>Hello Mochitest</p>\n\n\n</body></html>');
85 await runTest("http://mochi.test:8888/chrome/dom/base/test/file_external_script.xhtml",
86 '<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml"></html>',
87 '<html xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">\n<head>\n <script src="file_script.js"><\/script>\n <title></title>\n</head>\n<body>\n <p>Hello Mochitest</p>\n</body>\n</html>');
88 });
90 add_task(async function test_cleanup() {
91 const TOPIC = "blocking-promise-destroyed";
93 const finalizationWitness = Cc["@mozilla.org/toolkit/finalizationwitness;1"]
94 .getService(Ci.nsIFinalizationWitnessService);
96 for (let url of ["http://mochi.test:8888/chrome/dom/base/test/file_inline_script.html",
97 "http://mochi.test:8888/chrome/dom/base/test/file_inline_script.xhtml"]) {
98 let iframe = document.createElement("iframe");
99 iframe.src = url;
101 // Create a promise that never resolves.
102 let blockerPromise = new Promise(() => {});
104 // Create a finalization witness so we can be sure that the promises
105 // have been collected before the end of the test.
106 let destroyedPromise = TestUtils.topicObserved(TOPIC);
107 let witness = finalizationWitness.make(TOPIC, url);
108 blockerPromise.witness = witness;
110 let insertedPromise = TestUtils.topicObserved("document-element-inserted", document => {
111 document.blockParsing(blockerPromise).witness = witness;
113 return true;
116 document.body.appendChild(iframe);
117 await insertedPromise;
119 // Clear the promise reference, destroy the document, and force GC/CC. This should
120 // trigger any potential leaks or cleanup issues.
121 blockerPromise = null;
122 witness = null;
123 iframe.remove();
125 Cu.forceGC();
126 Cu.forceCC();
127 Cu.forceGC();
129 // Make sure the blocker promise has been collected.
130 let [, data] = await destroyedPromise;
131 is(data, url, "Should have correct finalizer URL");
134 </script>
135 </body>
136 </html>