Skip to content
This repository was archived by the owner on Jul 9, 2025. It is now read-only.

Commit 339cbf9

Browse files
domenicmoz-wptsync-bot
authored andcommitted
Bug 1609532 [wpt PR 21206] - Test entry and incumbent settings object for promise jobs, a=testonly
Automatic update from web-platform-tests Test entry and incumbent settings object for promise jobs Follows whatwg/html#5212 and whatwg/html#5213. -- wpt-commits: bc4ddbbddc566c3602d1af8d73c0225f8335855d wpt-pr: 21206
1 parent adc85a9 commit 339cbf9

File tree

15 files changed

+469
-0
lines changed

15 files changed

+469
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Entry settings object for promise jobs when the function realm is different from the test realm</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<!-- https://github.com/whatwg/html/pull/5212 -->
7+
<!-- https://github.com/whatwg/html/issues/1426 -->
8+
9+
<!-- This is what would normally be considered the entry page. However, we use functions from the
10+
resources/function/function.html realm. So window.open() should resolve relative to that realm
11+
inside promise jobs. -->
12+
13+
<iframe src="resources/promise-job-entry-incumbent.html"></iframe>
14+
<iframe src="resources/function/function.html" id="function-frame"></iframe>
15+
16+
<script>
17+
setup({ explicit_done: true });
18+
19+
const relativeURL = "resources/window-to-open.html";
20+
const expectedURL = (new URL(relativeURL, document.querySelector("#function-frame").src)).href;
21+
22+
const incumbentWindow = frames[0];
23+
const functionWindow = frames[1];
24+
const FunctionFromAnotherWindow = frames[1].Function;
25+
26+
window.onload = () => {
27+
async_test(t => {
28+
const func = FunctionFromAnotherWindow(`
29+
const [incumbentWindow, relativeURL, t, assert_equals, expectedURL] = arguments[0];
30+
31+
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL);
32+
w.onload = t.step_func_done(() => {
33+
t.add_cleanup(() => w.close());
34+
assert_equals(w.location.href, expectedURL);
35+
});
36+
`);
37+
38+
Promise.resolve([incumbentWindow, relativeURL, t, assert_equals, expectedURL]).then(func);
39+
}, "Fulfillment handler on fulfilled promise");
40+
41+
async_test(t => {
42+
const func = FunctionFromAnotherWindow(`
43+
const [incumbentWindow, relativeURL, t, assert_equals, expectedURL] = arguments[0];
44+
45+
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL);
46+
w.onload = t.step_func_done(() => {
47+
t.add_cleanup(() => w.close());
48+
assert_equals(w.location.href, expectedURL);
49+
});
50+
`);
51+
52+
Promise.reject([incumbentWindow, relativeURL, t, assert_equals, expectedURL]).catch(func);
53+
}, "Rejection handler on rejected promise");
54+
55+
async_test(t => {
56+
let resolve;
57+
const p = new Promise(r => { resolve = r; });
58+
59+
const func = FunctionFromAnotherWindow(`
60+
const [incumbentWindow, relativeURL, t, assert_equals, expectedURL] = arguments[0];
61+
62+
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL);
63+
w.onload = t.step_func_done(() => {
64+
t.add_cleanup(() => w.close());
65+
assert_equals(w.location.href, expectedURL);
66+
});
67+
`);
68+
69+
p.then(func);
70+
t.step_timeout(() => resolve([incumbentWindow, relativeURL, t, assert_equals, expectedURL]), 0);
71+
}, "Fulfillment handler on pending-then-fulfilled promise");
72+
73+
async_test(t => {
74+
let reject;
75+
const p = new Promise((_, r) => { reject = r; });
76+
77+
const func = FunctionFromAnotherWindow(`
78+
const [incumbentWindow, relativeURL, t, assert_equals, expectedURL] = arguments[0];
79+
80+
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL);
81+
w.onload = t.step_func_done(() => {
82+
t.add_cleanup(() => w.close());
83+
assert_equals(w.location.href, expectedURL);
84+
});
85+
`);
86+
87+
p.catch(func);
88+
t.step_timeout(() => reject([incumbentWindow, relativeURL, t, assert_equals, expectedURL]), 0);
89+
}, "Rejection handler on pending-then-rejected promise");
90+
91+
async_test(t => {
92+
t.add_cleanup(() => { delete frames[1].args; });
93+
frames[1].args = [incumbentWindow, relativeURL, t, assert_equals, expectedURL];
94+
95+
const func = FunctionFromAnotherWindow(`
96+
const [incumbentWindow, relativeURL, t, assert_equals, expectedURL] = window.args;
97+
98+
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL);
99+
w.onload = t.step_func_done(() => {
100+
t.add_cleanup(() => w.close());
101+
assert_equals(w.location.href, expectedURL);
102+
});
103+
`);
104+
105+
const thenable = { then: func };
106+
107+
Promise.resolve(thenable);
108+
}, "Thenable resolution");
109+
110+
done();
111+
};
112+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Entry settings object for promise jobs</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
<!-- https://github.com/whatwg/html/pull/5212 -->
7+
<!-- https://github.com/whatwg/html/issues/1426 -->
8+
9+
<!-- This is the entry page, so window.open() should resolve relative to it, even inside promise jobs. -->
10+
11+
<iframe src="resources/promise-job-entry-incumbent.html"></iframe>
12+
13+
<script>
14+
setup({ explicit_done: true });
15+
16+
const relativeURL = "resources/window-to-open.html";
17+
const expectedURL = (new URL(relativeURL, location.href)).href;
18+
19+
const incumbentWindow = frames[0];
20+
21+
window.onload = () => {
22+
async_test(t => {
23+
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL);
24+
w.onload = t.step_func_done(() => {
25+
t.add_cleanup(() => w.close());
26+
assert_equals(w.location.href, expectedURL);
27+
});
28+
}, "Sanity check: this all works as expected with no promises involved");
29+
30+
async_test(t => {
31+
// No t.step_func because that could change the realms
32+
Promise.resolve().then(() => {
33+
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL);
34+
w.onload = t.step_func_done(() => {
35+
t.add_cleanup(() => w.close());
36+
assert_equals(w.location.href, expectedURL);
37+
});
38+
});
39+
}, "Fulfillment handler on fulfilled promise");
40+
41+
async_test(t => {
42+
// No t.step_func because that could change the realms
43+
Promise.reject().catch(() => {
44+
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL);
45+
w.onload = t.step_func_done(() => {
46+
t.add_cleanup(() => w.close());
47+
assert_equals(w.location.href, expectedURL);
48+
});
49+
});
50+
}, "Rejection handler on rejected promise");
51+
52+
async_test(t => {
53+
let resolve;
54+
const p = new Promise(r => { resolve = r; });
55+
56+
// No t.step_func because that could change the realms
57+
p.then(() => {
58+
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL);
59+
w.onload = t.step_func_done(() => {
60+
t.add_cleanup(() => w.close());
61+
assert_equals(w.location.href, expectedURL);
62+
});
63+
});
64+
65+
t.step_timeout(resolve, 0);
66+
}, "Fulfillment handler on pending-then-fulfilled promise");
67+
68+
async_test(t => {
69+
let reject;
70+
const p = new Promise((_, r) => { reject = r; });
71+
72+
// No t.step_func because that could change the realms
73+
p.catch(() => {
74+
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL);
75+
w.onload = t.step_func_done(() => {
76+
t.add_cleanup(() => w.close());
77+
assert_equals(w.location.href, expectedURL);
78+
});
79+
});
80+
81+
t.step_timeout(reject, 0);
82+
}, "Rejection handler on pending-then-rejected promise");
83+
84+
async_test(t => {
85+
const thenable = {
86+
// No t.step_func because that could change the realms
87+
then(f) {
88+
const w = incumbentWindow.runWindowOpenVeryIndirectly(relativeURL);
89+
w.onload = t.step_func_done(() => {
90+
t.add_cleanup(() => w.close());
91+
assert_equals(w.location.href, expectedURL);
92+
});
93+
}
94+
};
95+
96+
Promise.resolve(thenable);
97+
}, "Thenable resolution");
98+
99+
done();
100+
};
101+
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Incumbent settings object for promise jobs</title>
4+
<script src="/resources/testharness.js"></script>
5+
<script src="/resources/testharnessreport.js"></script>
6+
7+
<!-- This is the entry page. -->
8+
9+
<iframe src="resources/promise-job-incumbent-incumbent.html"></iframe>
10+
<iframe src="resources/promise-job-incumbent-resolver.html"></iframe>
11+
12+
<script>
13+
setup({ explicit_done: true });
14+
15+
// postMessage should pick the incumbent page as its .source value to set on the MessageEvent, even
16+
// inside promise jobs.
17+
const expectedURL = (new URL("resources/promise-job-incumbent-incumbent.html", location.href)).href;
18+
19+
let testId = 0;
20+
21+
window.onload = () => {
22+
const relevantWindow = frames[0].document.querySelector("#r").contentWindow;
23+
const runInResolver = frames[1].runWhatYouGiveMe;
24+
25+
function setupTest(t) {
26+
++testId;
27+
const thisTestId = testId;
28+
29+
relevantWindow.addEventListener("messagereceived", t.step_func(e => {
30+
const [receivedTestId, receivedSourceURL] = e.detail;
31+
32+
if (receivedTestId !== thisTestId) {
33+
return;
34+
}
35+
36+
assert_equals(receivedSourceURL, expectedURL);
37+
t.done();
38+
}));
39+
40+
return thisTestId;
41+
}
42+
43+
async_test(t => {
44+
const thisTestId = setupTest(t);
45+
46+
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
47+
}, "Sanity check: this all works as expected with no promises involved");
48+
49+
async_test(t => {
50+
const thisTestId = setupTest(t);
51+
52+
// No t.step_func because that could change the realms
53+
Promise.resolve().then(() => {
54+
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
55+
});
56+
}, "Fulfillment handler on fulfilled promise");
57+
58+
async_test(t => {
59+
const thisTestId = setupTest(t);
60+
61+
const p = Promise.resolve();
62+
frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "then", thisTestId, "*");
63+
}, "Fulfillment handler on fulfilled promise, using backup incumbent settings object stack");
64+
65+
async_test(t => {
66+
const thisTestId = setupTest(t);
67+
68+
// No t.step_func because that could change the realms
69+
Promise.reject().catch(() => {
70+
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
71+
});
72+
}, "Rejection handler on rejected promise");
73+
74+
async_test(t => {
75+
const thisTestId = setupTest(t);
76+
77+
const p = Promise.reject();
78+
frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "catch", thisTestId, "*");
79+
}, "Rejection handler on rejected promise, using backup incumbent settings object stack");
80+
81+
// The following tests test that we derive the incumbent settings object at promise-job time from
82+
// the incumbent realm at the time the handler was added, not at the time the resolve()/reject()
83+
// was done. See https://github.com/whatwg/html/issues/5213 for the spec side of this issue.
84+
85+
async_test(t => {
86+
const thisTestId = setupTest(t);
87+
88+
let resolve;
89+
const p = new Promise(r => { resolve = r; });
90+
91+
// No t.step_func because that could change the realms
92+
p.then(() => {
93+
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
94+
});
95+
96+
t.step_timeout(() => {
97+
runInResolver(resolve);
98+
}, 0);
99+
}, "Fulfillment handler on pending-then-fulfilled promise");
100+
101+
async_test(t => {
102+
const thisTestId = setupTest(t);
103+
104+
let resolve;
105+
const p = new Promise(r => { resolve = r; });
106+
107+
frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "then", thisTestId, "*");
108+
109+
t.step_timeout(() => {
110+
runInResolver(resolve);
111+
}, 0);
112+
}, "Fulfillment handler on pending-then-fulfilled promise, using backup incumbent settings object stack");
113+
114+
async_test(t => {
115+
const thisTestId = setupTest(t);
116+
117+
let reject;
118+
const p = new Promise((_, r) => { reject = r; });
119+
120+
// No t.step_func because that could change the realms
121+
p.catch(() => {
122+
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
123+
});
124+
125+
t.step_timeout(() => {
126+
runInResolver(reject);
127+
}, 0);
128+
}, "Rejection handler on pending-then-rejected promise");
129+
130+
async_test(t => {
131+
const thisTestId = setupTest(t);
132+
133+
let reject;
134+
const p = new Promise((_, r) => { reject = r; });
135+
136+
frames[0].runWindowPostMessageVeryIndirectlyWithNoUserCode(p, "catch", thisTestId, "*");
137+
138+
t.step_timeout(() => {
139+
runInResolver(reject);
140+
}, 0);
141+
}, "Rejection handler on pending-then-rejected promise, using backup incumbent settings object stack");
142+
143+
async_test(t => {
144+
const thisTestId = setupTest(t);
145+
146+
const thenable = {
147+
// No t.step_func because that could change the realms
148+
then(f) {
149+
frames[0].runWindowPostMessageVeryIndirectly(thisTestId, "*");
150+
}
151+
};
152+
153+
Promise.resolve(thenable);
154+
}, "Thenable resolution");
155+
156+
async_test(t => {
157+
const thisTestId = setupTest(t);
158+
159+
frames[0].resolveThenableThatRunsWindowPostMessageVeryIndirectlyWithNoUserCode(testId, "*", []);
160+
}, "Thenable resolution, using backup incumbent settings object stack");
161+
162+
done();
163+
};
164+
</script>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
A couple notes about the files scattered in this `resources/` directory:
2+
3+
* The nested directory structure is necessary here so that relative URL resolution can be tested; we need different sub-paths for each document.
4+
5+
* 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.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Current page used as a test helper</title>
4+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>If the current settings object is used this page will be opened</title>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<!DOCTYPE html>
2+
<meta charset="utf-8">
3+
<title>Realm for a "then" function used as a test helper</title>

0 commit comments

Comments
 (0)