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

Commit 0f2fcb7

Browse files
marcoscaceresmoz-wptsync-bot
authored andcommitted
Bug 1729247 [wpt PR 30352] - Fix test of docs not being fully active, a=testonly
Automatic update from web-platform-tests Fix test of docs not being fully active (#30352) -- wpt-commits: 1565ddf6e92cd3060d89c229c19db5e3513fbb1b wpt-pr: 30352
1 parent c6f2830 commit 0f2fcb7

File tree

2 files changed

+127
-245
lines changed

2 files changed

+127
-245
lines changed

testing/web-platform/tests/payment-request/rejects_if_not_active-manual.https.html

Lines changed: 0 additions & 171 deletions
This file was deleted.

testing/web-platform/tests/payment-request/rejects_if_not_active.https.html

Lines changed: 127 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -7,83 +7,136 @@
77
<script src="/resources/testdriver.js"></script>
88
<script src="/resources/testdriver-vendor.js"></script>
99
<body>
10-
<script>
11-
const applePay = Object.freeze({
12-
supportedMethods: "https://apple.com/apple-pay",
13-
data: {
14-
version: 3,
15-
merchantIdentifier: "merchant.com.example",
16-
countryCode: "US",
17-
merchantCapabilities: ["supports3DS"],
18-
supportedNetworks: ["visa"],
19-
},
20-
});
21-
const validMethod = Object.freeze({
22-
supportedMethods: "basic-card",
23-
});
24-
const validMethods = Object.freeze([validMethod, applePay]);
25-
const validAmount = Object.freeze({
26-
currency: "USD",
27-
value: "5.00",
28-
});
29-
const validTotal = Object.freeze({
30-
label: "Total due",
31-
amount: validAmount,
32-
});
33-
const validDetails = Object.freeze({
34-
total: validTotal,
35-
});
10+
<script>
11+
const applePay = Object.freeze({
12+
supportedMethods: "https://apple.com/apple-pay",
13+
data: {
14+
version: 3,
15+
merchantIdentifier: "merchant.com.example",
16+
countryCode: "US",
17+
merchantCapabilities: ["supports3DS"],
18+
supportedNetworks: ["visa"],
19+
},
20+
});
21+
const validMethod = Object.freeze({
22+
supportedMethods: "basic-card",
23+
});
24+
const validMethods = Object.freeze([validMethod, applePay]);
3625

37-
async function getLoadedPaymentRequest(iframe, url) {
38-
await new Promise((resolve) => {
39-
iframe.addEventListener("load", resolve, { once: true });
40-
iframe.src = url;
41-
});
42-
const { PaymentRequest } = iframe.contentWindow;
43-
const request = new PaymentRequest(validMethods, validDetails);
44-
return request;
45-
}
26+
const validDetails = Object.freeze({
27+
total: {
28+
label: "Total due",
29+
amount: {
30+
currency: "USD",
31+
value: "5.00",
32+
},
33+
},
34+
});
4635

47-
promise_test(async (t) => {
48-
const iframe = document.createElement("iframe");
49-
document.body.appendChild(iframe);
50-
// Make a request in the iframe.
51-
const request = await getLoadedPaymentRequest(
52-
iframe,
53-
"resources/page1.html"
54-
);
55-
await test_driver.bless("show payment request");
56-
const showPromise = request.show();
57-
const firstCtor = iframe.contentWindow.DOMException;
36+
async function getLoadedPaymentRequest(iframe, url) {
37+
await new Promise((resolve) => {
38+
iframe.addEventListener("load", resolve, { once: true });
39+
iframe.src = url;
40+
});
41+
return new iframe.contentWindow.PaymentRequest(
42+
validMethods,
43+
validDetails
44+
);
45+
}
5846

59-
// Navigate the iframe to a new location. Wait for the load event to fire.
60-
const request2 = await getLoadedPaymentRequest(
61-
iframe,
62-
"resources/page2.html"
63-
);
47+
promise_test(async (t) => {
48+
const iframe = document.createElement("iframe");
49+
iframe.allow = "payment";
50+
document.body.appendChild(iframe);
51+
t.add_cleanup(() => {
52+
iframe.remove();
53+
});
54+
// We first got to page1.html, grab a PaymentRequest instance.
55+
const request1 = await getLoadedPaymentRequest(
56+
iframe,
57+
"./resources/page1.html"
58+
);
59+
// Save the DOMException of page1.html before navigating away.
60+
const frameDOMException1 = iframe.contentWindow.DOMException;
6461

65-
await promise_rejects_dom(
66-
t,
67-
"AbortError",
68-
firstCtor,
69-
showPromise,
70-
"Show promise should abort."
71-
);
62+
// Get transient activation
63+
await test_driver.bless("payment 1", () => {}, iframe.contentWindow);
7264

73-
// The navigation dismisses the previous payment request so it
74-
// now possible to show another one.
75-
await test_driver.bless("show 2nd payment request");
76-
const showPromise2 = request2.show();
77-
const secondCtor = iframe.contentWindow.DOMException;
78-
// no longer fully active
79-
iframe.remove();
80-
await promise_rejects_dom(
81-
t,
82-
"AbortError",
83-
secondCtor,
84-
showPromise2,
85-
"Show promise should abort."
86-
);
87-
}, "If a payment request is showing, but its document is navigated away (so no longer fully active), the payment sheet is dismissed.");
88-
</script>
65+
// We navigate the iframe again, putting request1's document into an non-fully active state.
66+
const request2 = await getLoadedPaymentRequest(
67+
iframe,
68+
"./resources/page2.html"
69+
);
70+
71+
// Now, request1's relevant global object's document is no longer active.
72+
// So, call .show(), and make sure it rejects appropriately.
73+
await promise_rejects_dom(
74+
t,
75+
"AbortError",
76+
frameDOMException1,
77+
request1.show(),
78+
"Inactive document, so must throw AbortError"
79+
);
80+
// request2 has an active document tho, so confirm it's working as expected:
81+
// Get transient activation
82+
await test_driver.bless("payment 2", () => {}, iframe.contentWindow);
83+
request2.show();
84+
await request2.abort();
85+
await promise_rejects_dom(
86+
t,
87+
"InvalidStateError",
88+
iframe.contentWindow.DOMException,
89+
request2.show(),
90+
"Abort already called, so InvalidStateError"
91+
);
92+
}, "PaymentRequest.show() aborts if the document is not active.");
93+
94+
promise_test(async (t) => {
95+
// We nest two iframes and wait for them to load.
96+
const outerIframe = document.createElement("iframe");
97+
outerIframe.allow = "payment";
98+
document.body.appendChild(outerIframe);
99+
t.add_cleanup(() => {
100+
outerIframe.remove();
101+
});
102+
// Load the outer iframe (we don't care about the awaited request)
103+
await getLoadedPaymentRequest(outerIframe, "./resources/page1.html");
104+
105+
// Now we create the inner iframe
106+
const innerIframe = outerIframe.contentDocument.createElement("iframe");
107+
innerIframe.allow = "payment";
108+
109+
// nest them
110+
outerIframe.contentDocument.body.appendChild(innerIframe);
111+
112+
// load innerIframe, and get the PaymentRequest instance
113+
const request = await getLoadedPaymentRequest(
114+
innerIframe,
115+
"./resources/page2.html"
116+
);
117+
// Save DOMException from innerIframe before navigating away.
118+
const innerIframeDOMException = innerIframe.contentWindow.DOMException;
119+
120+
// Navigate the outer iframe to a new location.
121+
// Wait for the load event to fire.
122+
await new Promise((resolve) => {
123+
outerIframe.addEventListener("load", resolve);
124+
outerIframe.src = "./resources/page2.html";
125+
});
126+
127+
await test_driver.bless("", () => {}, innerIframe.contentWindow);
128+
const showPromise = request.show();
129+
// Now, request's relevant global object's document is still active
130+
// (it is the active document of the inner iframe), but is not fully active
131+
// (since the parent of the inner iframe is itself no longer active).
132+
// So, call request.show() and make sure it rejects appropriately.
133+
await promise_rejects_dom(
134+
t,
135+
"AbortError",
136+
innerIframeDOMException,
137+
showPromise,
138+
"Active, but not fully active, so must throw AbortError"
139+
);
140+
}, "PaymentRequest.show() aborts if the document is active, but not fully active.");
141+
</script>
89142
</body>

0 commit comments

Comments
 (0)