| // An older version of the HTML Standard mandated that document.open() remove |
| // all tasks associated with the document on which open() is called. This step |
| // has been proposed to be removed. This series of tests ensures that this step |
| // is no longer executed. |
| // |
| // This file comprehensively (but not exhaustively) tests for many queued tasks |
| // that may be observable. Each taskTest() call in fact runs two tests: the |
| // first one "tasks without document.open()" does not actually run |
| // document.open(), just to test that the tested task works ordinarily; the |
| // second actually calls document.open() to test if the method call removes |
| // that specific task from the queue. |
| |
| // This is necessary to allow the promise rejection test below. |
| setup({ |
| allow_uncaught_exception: true |
| }); |
| |
| function taskTest(description, testBody) { |
| async_test(t => { |
| const frame = document.body.appendChild(document.createElement("iframe")); |
| // 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/569511 |
| frame.src = "/common/blank.html"; |
| t.add_cleanup(() => frame.remove()); |
| frame.onload = t.step_func(() => { |
| // Make sure there is no parser. Firefox seems to have an additional |
| // non-spec-compliant readiness state "uninitialized", so test for the |
| // two known valid readiness states instead. |
| // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1191683 |
| assert_in_array(frame.contentDocument.readyState, ["interactive", "complete"]); |
| testBody(t, frame, doc => {}); |
| }); |
| }, `tasks without document.open() (${description})`); |
| |
| async_test(t => { |
| const frame = document.body.appendChild(document.createElement("iframe")); |
| // 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/569511 |
| frame.src = "/common/blank.html"; |
| t.add_cleanup(() => frame.remove()); |
| frame.onload = t.step_func(() => { |
| // Make sure there is no parser. Firefox seems to have an additional |
| // non-spec-compliant readiness state "uninitialized", so test for the |
| // two known valid readiness states instead. |
| // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1191683 |
| assert_in_array(frame.contentDocument.readyState, ["interactive", "complete"]); |
| testBody(t, frame, doc => doc.open()); |
| }); |
| }, `document.open() and tasks (${description})`); |
| } |
| |
| taskTest("timeout", (t, frame, open) => { |
| frame.contentWindow.setTimeout(t.step_func_done(), 100); |
| open(frame.contentDocument); |
| }); |
| |
| taskTest("window message", (t, frame, open) => { |
| let counter = 0; |
| frame.contentWindow.postMessage(undefined, "*"); |
| open(frame.contentDocument); |
| frame.contentWindow.postMessage(undefined, "*"); |
| frame.contentWindow.onmessage = t.step_func(e => { |
| assert_equals(e.data, undefined); |
| counter++; |
| assert_less_than_equal(counter, 2); |
| if (counter == 2) { |
| t.done(); |
| } |
| }); |
| }); |
| |
| taskTest("canvas.toBlob()", (t, frame, open) => { |
| const canvas = frame.contentDocument.body.appendChild(frame.contentDocument.createElement("canvas")); |
| canvas.toBlob(t.step_func_done()); |
| open(frame.contentDocument); |
| }); |
| |
| taskTest("MessagePort", (t, frame, open) => { |
| frame.contentWindow.eval(`({ port1, port2 } = new MessageChannel());`); |
| frame.contentWindow.port2.onmessage = t.step_func_done(ev => { |
| assert_equals(ev.data, "Hello world"); |
| }); |
| frame.contentWindow.port1.postMessage("Hello world"); |
| open(frame.contentDocument); |
| }); |
| |
| taskTest("Promise rejection", (t, frame, open) => { |
| // There is currently some ambiguity on which Window object the |
| // unhandledrejection event should be fired on. Here, let's account for that |
| // ambiguity and allow event fired on _any_ global to pass this test. |
| // See: |
| // - https://github.com/whatwg/html/issues/958, |
| // - https://bugs.webkit.org/show_bug.cgi?id=187822 |
| const promise = frame.contentWindow.eval("Promise.reject(42);"); |
| open(frame.contentDocument); |
| const listener = t.step_func_done(ev => { |
| assert_equals(ev.promise, promise); |
| assert_equals(ev.reason, 42); |
| }); |
| frame.contentWindow.onunhandledrejection = listener; |
| window.onunhandledrejection = listener; |
| }); |
| |
| taskTest("marquee start", (t, frame, open) => { |
| const doc = frame.contentDocument; |
| const marquee = doc.body.appendChild(doc.createElement("marquee")); |
| open(frame.contentDocument); |
| marquee.addEventListener("start", t.step_func_done()); |
| }); |