-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Test entry and incumbent settings object for promise jobs
Follows whatwg/html#5212 and whatwg/html#5213.
- Loading branch information
Showing
15 changed files
with
469 additions
and
0 deletions.
There are no files selected for viewing
112 changes: 112 additions & 0 deletions
112
...integration-with-the-javascript-job-queue/promise-job-entry-different-function-realm.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>Entry settings object for promise jobs when the function realm is different from the test realm</title> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<!-- https://github.com/whatwg/html/pull/5212 --> | ||
<!-- https://github.com/whatwg/html/issues/1426 --> | ||
|
||
<!-- This is what would normally be considered the entry page. However, we use functions from the | ||
resources/function/function.html realm. So window.open() should resolve relative to that realm | ||
inside promise jobs. --> | ||
|
||
<iframe src="resources/promise-job-entry-incumbent.html"></iframe> | ||
<iframe src="resources/function/function.html" id="function-frame"></iframe> | ||
|
||
<script> | ||
setup({ explicit_done: true }); | ||
|
||
const relativeURL = "resources/window-to-open.html"; | ||
const expectedURL = (new URL(relativeURL, document.querySelector("#function-frame").src)).href; | ||
|
||
const incumbentWindow = frames[0]; | ||
const functionWindow = frames[1]; | ||
const FunctionFromAnotherWindow = frames[1].Function; | ||
|
||
window.onload = () => { | ||
async_test(t => { | ||
const func = FunctionFromAnotherWindow(` | ||
const [incumbentWindow, relativeURL, t, assert_equals, expectedURL] = arguments[0]; | ||
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); | ||
w.onload = t.step_func_done(() => { | ||
t.add_cleanup(() => w.close()); | ||
assert_equals(w.location.href, expectedURL); | ||
}); | ||
`); | ||
|
||
Promise.resolve([incumbentWindow, relativeURL, t, assert_equals, expectedURL]).then(func); | ||
}, "Fulfillment handler on fulfilled promise"); | ||
|
||
async_test(t => { | ||
const func = FunctionFromAnotherWindow(` | ||
const [incumbentWindow, relativeURL, t, assert_equals, expectedURL] = arguments[0]; | ||
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); | ||
w.onload = t.step_func_done(() => { | ||
t.add_cleanup(() => w.close()); | ||
assert_equals(w.location.href, expectedURL); | ||
}); | ||
`); | ||
|
||
Promise.reject([incumbentWindow, relativeURL, t, assert_equals, expectedURL]).catch(func); | ||
}, "Rejection handler on rejected promise"); | ||
|
||
async_test(t => { | ||
let resolve; | ||
const p = new Promise(r => { resolve = r; }); | ||
|
||
const func = FunctionFromAnotherWindow(` | ||
const [incumbentWindow, relativeURL, t, assert_equals, expectedURL] = arguments[0]; | ||
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); | ||
w.onload = t.step_func_done(() => { | ||
t.add_cleanup(() => w.close()); | ||
assert_equals(w.location.href, expectedURL); | ||
}); | ||
`); | ||
|
||
p.then(func); | ||
t.step_timeout(() => resolve([incumbentWindow, relativeURL, t, assert_equals, expectedURL]), 0); | ||
}, "Fulfillment handler on pending-then-fulfilled promise"); | ||
|
||
async_test(t => { | ||
let reject; | ||
const p = new Promise((_, r) => { reject = r; }); | ||
|
||
const func = FunctionFromAnotherWindow(` | ||
const [incumbentWindow, relativeURL, t, assert_equals, expectedURL] = arguments[0]; | ||
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); | ||
w.onload = t.step_func_done(() => { | ||
t.add_cleanup(() => w.close()); | ||
assert_equals(w.location.href, expectedURL); | ||
}); | ||
`); | ||
|
||
p.catch(func); | ||
t.step_timeout(() => reject([incumbentWindow, relativeURL, t, assert_equals, expectedURL]), 0); | ||
}, "Rejection handler on pending-then-rejected promise"); | ||
|
||
async_test(t => { | ||
t.add_cleanup(() => { delete frames[1].args; }); | ||
frames[1].args = [incumbentWindow, relativeURL, t, assert_equals, expectedURL]; | ||
|
||
const func = FunctionFromAnotherWindow(` | ||
const [incumbentWindow, relativeURL, t, assert_equals, expectedURL] = window.args; | ||
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); | ||
w.onload = t.step_func_done(() => { | ||
t.add_cleanup(() => w.close()); | ||
assert_equals(w.location.href, expectedURL); | ||
}); | ||
`); | ||
|
||
const thenable = { then: func }; | ||
|
||
Promise.resolve(thenable); | ||
}, "Thenable resolution"); | ||
|
||
done(); | ||
}; | ||
</script> |
101 changes: 101 additions & 0 deletions
101
...pting/processing-model-2/integration-with-the-javascript-job-queue/promise-job-entry.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>Entry settings object for promise jobs</title> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<!-- https://github.com/whatwg/html/pull/5212 --> | ||
<!-- https://github.com/whatwg/html/issues/1426 --> | ||
|
||
<!-- This is the entry page, so window.open() should resolve relative to it, even inside promise jobs. --> | ||
|
||
<iframe src="resources/promise-job-entry-incumbent.html"></iframe> | ||
|
||
<script> | ||
setup({ explicit_done: true }); | ||
|
||
const relativeURL = "resources/window-to-open.html"; | ||
const expectedURL = (new URL(relativeURL, location.href)).href; | ||
|
||
const incumbentWindow = frames[0]; | ||
|
||
window.onload = () => { | ||
async_test(t => { | ||
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); | ||
w.onload = t.step_func_done(() => { | ||
t.add_cleanup(() => w.close()); | ||
assert_equals(w.location.href, expectedURL); | ||
}); | ||
}, "Sanity check: this all works as expected with no promises involved"); | ||
|
||
async_test(t => { | ||
// No t.step_func because that could change the realms | ||
Promise.resolve().then(() => { | ||
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); | ||
w.onload = t.step_func_done(() => { | ||
t.add_cleanup(() => w.close()); | ||
assert_equals(w.location.href, expectedURL); | ||
}); | ||
}); | ||
}, "Fulfillment handler on fulfilled promise"); | ||
|
||
async_test(t => { | ||
// No t.step_func because that could change the realms | ||
Promise.reject().catch(() => { | ||
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); | ||
w.onload = t.step_func_done(() => { | ||
t.add_cleanup(() => w.close()); | ||
assert_equals(w.location.href, expectedURL); | ||
}); | ||
}); | ||
}, "Rejection handler on rejected promise"); | ||
|
||
async_test(t => { | ||
let resolve; | ||
const p = new Promise(r => { resolve = r; }); | ||
|
||
// No t.step_func because that could change the realms | ||
p.then(() => { | ||
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); | ||
w.onload = t.step_func_done(() => { | ||
t.add_cleanup(() => w.close()); | ||
assert_equals(w.location.href, expectedURL); | ||
}); | ||
}); | ||
|
||
t.step_timeout(resolve, 0); | ||
}, "Fulfillment handler on pending-then-fulfilled promise"); | ||
|
||
async_test(t => { | ||
let reject; | ||
const p = new Promise((_, r) => { reject = r; }); | ||
|
||
// No t.step_func because that could change the realms | ||
p.catch(() => { | ||
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); | ||
w.onload = t.step_func_done(() => { | ||
t.add_cleanup(() => w.close()); | ||
assert_equals(w.location.href, expectedURL); | ||
}); | ||
}); | ||
|
||
t.step_timeout(reject, 0); | ||
}, "Rejection handler on pending-then-rejected promise"); | ||
|
||
async_test(t => { | ||
const thenable = { | ||
// No t.step_func because that could change the realms | ||
then(f) { | ||
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL); | ||
w.onload = t.step_func_done(() => { | ||
t.add_cleanup(() => w.close()); | ||
assert_equals(w.location.href, expectedURL); | ||
}); | ||
} | ||
}; | ||
|
||
Promise.resolve(thenable); | ||
}, "Thenable resolution"); | ||
|
||
done(); | ||
}; | ||
</script> |
164 changes: 164 additions & 0 deletions
164
...g/processing-model-2/integration-with-the-javascript-job-queue/promise-job-incumbent.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>Incumbent settings object for promise jobs</title> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
|
||
<!-- This is the entry page. --> | ||
|
||
<iframe src="resources/promise-job-incumbent-incumbent.html"></iframe> | ||
<iframe src="resources/promise-job-incumbent-resolver.html"></iframe> | ||
|
||
<script> | ||
setup({ explicit_done: true }); | ||
|
||
// postMessage should pick the incumbent page as its .source value to set on the MessageEvent, even | ||
// inside promise jobs. | ||
const expectedURL = (new URL("resources/promise-job-incumbent-incumbent.html", location.href)).href; | ||
|
||
let testId = 0; | ||
|
||
window.onload = () => { | ||
const relevantWindow = frames[0].document.querySelector("#r").contentWindow; | ||
const runInResolver = frames[1].runWhatYouGiveMe; | ||
|
||
function setupTest(t) { | ||
++testId; | ||
const thisTestId = testId; | ||
|
||
relevantWindow.addEventListener("messagereceived", t.step_func(e => { | ||
const [receivedTestId, receivedSourceURL] = e.detail; | ||
|
||
if (receivedTestId !== thisTestId) { | ||
return; | ||
} | ||
|
||
assert_equals(receivedSourceURL, expectedURL); | ||
t.done(); | ||
})); | ||
|
||
return thisTestId; | ||
} | ||
|
||
async_test(t => { | ||
const thisTestId = setupTest(t); | ||
|
||
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*"); | ||
}, "Sanity check: this all works as expected with no promises involved"); | ||
|
||
async_test(t => { | ||
const thisTestId = setupTest(t); | ||
|
||
// No t.step_func because that could change the realms | ||
Promise.resolve().then(() => { | ||
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*"); | ||
}); | ||
}, "Fulfillment handler on fulfilled promise"); | ||
|
||
async_test(t => { | ||
const thisTestId = setupTest(t); | ||
|
||
const p = Promise.resolve(); | ||
frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "then", thisTestId, "*"); | ||
}, "Fulfillment handler on fulfilled promise, using backup incumbent settings object stack"); | ||
|
||
async_test(t => { | ||
const thisTestId = setupTest(t); | ||
|
||
// No t.step_func because that could change the realms | ||
Promise.reject().catch(() => { | ||
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*"); | ||
}); | ||
}, "Rejection handler on rejected promise"); | ||
|
||
async_test(t => { | ||
const thisTestId = setupTest(t); | ||
|
||
const p = Promise.reject(); | ||
frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "catch", thisTestId, "*"); | ||
}, "Rejection handler on rejected promise, using backup incumbent settings object stack"); | ||
|
||
// The following tests test that we derive the incumbent settings object at promise-job time from | ||
// the incumbent realm at the time the handler was added, not at the time the resolve()/reject() | ||
// was done. See https://github.com/whatwg/html/issues/5213 for the spec side of this issue. | ||
|
||
async_test(t => { | ||
const thisTestId = setupTest(t); | ||
|
||
let resolve; | ||
const p = new Promise(r => { resolve = r; }); | ||
|
||
// No t.step_func because that could change the realms | ||
p.then(() => { | ||
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*"); | ||
}); | ||
|
||
t.step_timeout(() => { | ||
runInResolver(resolve); | ||
}, 0); | ||
}, "Fulfillment handler on pending-then-fulfilled promise"); | ||
|
||
async_test(t => { | ||
const thisTestId = setupTest(t); | ||
|
||
let resolve; | ||
const p = new Promise(r => { resolve = r; }); | ||
|
||
frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "then", thisTestId, "*"); | ||
|
||
t.step_timeout(() => { | ||
runInResolver(resolve); | ||
}, 0); | ||
}, "Fulfillment handler on pending-then-fulfilled promise, using backup incumbent settings object stack"); | ||
|
||
async_test(t => { | ||
const thisTestId = setupTest(t); | ||
|
||
let reject; | ||
const p = new Promise((_, r) => { reject = r; }); | ||
|
||
// No t.step_func because that could change the realms | ||
p.catch(() => { | ||
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*"); | ||
}); | ||
|
||
t.step_timeout(() => { | ||
runInResolver(reject); | ||
}, 0); | ||
}, "Rejection handler on pending-then-rejected promise"); | ||
|
||
async_test(t => { | ||
const thisTestId = setupTest(t); | ||
|
||
let reject; | ||
const p = new Promise((_, r) => { reject = r; }); | ||
|
||
frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "catch", thisTestId, "*"); | ||
|
||
t.step_timeout(() => { | ||
runInResolver(reject); | ||
}, 0); | ||
}, "Rejection handler on pending-then-rejected promise, using backup incumbent settings object stack"); | ||
|
||
async_test(t => { | ||
const thisTestId = setupTest(t); | ||
|
||
const thenable = { | ||
// No t.step_func because that could change the realms | ||
then(f) { | ||
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*"); | ||
} | ||
}; | ||
|
||
Promise.resolve(thenable); | ||
}, "Thenable resolution"); | ||
|
||
async_test(t => { | ||
const thisTestId = setupTest(t); | ||
|
||
frames[0].resolveThenableThatRunsWindowPostMessageVeryIndirectlyWithNoUserCode(testId, "*", []); | ||
}, "Thenable resolution, using backup incumbent settings object stack"); | ||
|
||
done(); | ||
}; | ||
</script> |
5 changes: 5 additions & 0 deletions
5
...rocessing-model-2/integration-with-the-javascript-job-queue/resources/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
A couple notes about the files scattered in this `resources/` directory: | ||
|
||
* The nested directory structure is necessary here so that relative URL resolution can be tested; we need different sub-paths for each document. | ||
|
||
* The semi-duplicate `window-to-open.html`s scattered throughout are present because Firefox, at least, does not fire `Window` `load` events for 404s, so we want to ensure that no matter which global is used, `window`'s `load` event is hit and our tests can proceed. |
4 changes: 4 additions & 0 deletions
4
...ocessing-model-2/integration-with-the-javascript-job-queue/resources/current/current.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>Current page used as a test helper</title> | ||
|
3 changes: 3 additions & 0 deletions
3
...integration-with-the-javascript-job-queue/resources/current/resources/window-to-open.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>If the current settings object is used this page will be opened</title> |
3 changes: 3 additions & 0 deletions
3
...essing-model-2/integration-with-the-javascript-job-queue/resources/function/function.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<title>Realm for a "then" function used as a test helper</title> |
Oops, something went wrong.