tasks.window.js (4481B)
1 // An older version of the HTML Standard mandated that document.open() remove 2 // all tasks associated with the document on which open() is called. This step 3 // has been proposed to be removed. This series of tests ensures that this step 4 // is no longer executed. 5 // 6 // This file comprehensively (but not exhaustively) tests for many queued tasks 7 // that may be observable. Each taskTest() call in fact runs two tests: the 8 // first one "tasks without document.open()" does not actually run 9 // document.open(), just to test that the tested task works ordinarily; the 10 // second actually calls document.open() to test if the method call removes 11 // that specific task from the queue. 12 13 // This is necessary to allow the promise rejection test below. 14 setup({ 15 allow_uncaught_exception: true 16 }); 17 18 function taskTest(description, testBody) { 19 async_test(t => { 20 const frame = document.body.appendChild(document.createElement("iframe")); 21 // The empty HTML seems to be necessary to cajole Chrome and Safari into 22 // firing a load event asynchronously, which is necessary to make sure the 23 // frame's document doesn't have a parser associated with it. 24 // See: https://crbug.com/569511 25 frame.src = "/common/blank.html"; 26 t.add_cleanup(() => frame.remove()); 27 frame.onload = t.step_func(() => { 28 // Make sure there is no parser. Firefox seems to have an additional 29 // non-spec-compliant readiness state "uninitialized", so test for the 30 // two known valid readiness states instead. 31 // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1191683 32 assert_in_array(frame.contentDocument.readyState, ["interactive", "complete"]); 33 testBody(t, frame, doc => {}); 34 }); 35 }, `tasks without document.open() (${description})`); 36 37 async_test(t => { 38 const frame = document.body.appendChild(document.createElement("iframe")); 39 // The empty HTML seems to be necessary to cajole Chrome into firing a load 40 // event, which is necessary to make sure the frame's document doesn't have 41 // a parser associated with it. 42 // See: https://crbug.com/569511 43 frame.src = "/common/blank.html"; 44 t.add_cleanup(() => frame.remove()); 45 frame.onload = t.step_func(() => { 46 // Make sure there is no parser. Firefox seems to have an additional 47 // non-spec-compliant readiness state "uninitialized", so test for the 48 // two known valid readiness states instead. 49 // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1191683 50 assert_in_array(frame.contentDocument.readyState, ["interactive", "complete"]); 51 testBody(t, frame, doc => doc.open()); 52 }); 53 }, `document.open() and tasks (${description})`); 54 } 55 56 taskTest("timeout", (t, frame, open) => { 57 frame.contentWindow.setTimeout(t.step_func_done(), 100); 58 open(frame.contentDocument); 59 }); 60 61 taskTest("window message", (t, frame, open) => { 62 let counter = 0; 63 frame.contentWindow.postMessage(undefined, "*"); 64 open(frame.contentDocument); 65 frame.contentWindow.postMessage(undefined, "*"); 66 frame.contentWindow.onmessage = t.step_func(e => { 67 assert_equals(e.data, undefined); 68 counter++; 69 assert_less_than_equal(counter, 2); 70 if (counter == 2) { 71 t.done(); 72 } 73 }); 74 }); 75 76 taskTest("canvas.toBlob()", (t, frame, open) => { 77 const canvas = frame.contentDocument.body.appendChild(frame.contentDocument.createElement("canvas")); 78 canvas.toBlob(t.step_func_done()); 79 open(frame.contentDocument); 80 }); 81 82 taskTest("MessagePort", (t, frame, open) => { 83 frame.contentWindow.eval(`({ port1, port2 } = new MessageChannel());`); 84 frame.contentWindow.port2.onmessage = t.step_func_done(ev => { 85 assert_equals(ev.data, "Hello world"); 86 }); 87 frame.contentWindow.port1.postMessage("Hello world"); 88 open(frame.contentDocument); 89 }); 90 91 taskTest("Promise rejection", (t, frame, open) => { 92 // There is currently some ambiguity on which Window object the 93 // unhandledrejection event should be fired on. Here, let's account for that 94 // ambiguity and allow event fired on _any_ global to pass this test. 95 // See: 96 // - https://github.com/whatwg/html/issues/958, 97 // - https://bugs.webkit.org/show_bug.cgi?id=187822 98 const promise = frame.contentWindow.eval("Promise.reject(42);"); 99 open(frame.contentDocument); 100 const listener = t.step_func_done(ev => { 101 assert_equals(ev.promise, promise); 102 assert_equals(ev.reason, 42); 103 }); 104 frame.contentWindow.onunhandledrejection = listener; 105 window.onunhandledrejection = listener; 106 });