-
Notifications
You must be signed in to change notification settings - Fork 3k
/
rejects_if_not_active-manual.https.html
171 lines (159 loc) · 5.54 KB
/
rejects_if_not_active-manual.https.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
<!DOCTYPE html>
<meta charset=utf-8>
<title>PaymentRequest show() rejects if doc is not fully active</title>
<link rel="help" href="https://w3c.github.io/payment-request/#show-method">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<body>
<script>
setup({
explicit_done: true,
explicit_timeout: true,
});
const applePay = Object.freeze({
supportedMethods: "https://apple.com/apple-pay",
data: {
version: 3,
merchantIdentifier: "merchant.com.example",
countryCode: "US",
merchantCapabilities: ["supports3DS"],
supportedNetworks: ["visa"],
}
});
const validMethod = Object.freeze({
supportedMethods: "basic-card",
});
const validMethods = Object.freeze([validMethod, applePay]);
const validDetails = Object.freeze({
total: {
label: "Total due",
amount: {
currency: "USD",
value: "5.00",
},
},
});
function getLoadedPaymentRequest(iframe, url) {
return new Promise(resolve => {
iframe.addEventListener(
"load",
() => {
const { PaymentRequest } = iframe.contentWindow;
const request = new PaymentRequest(validMethods, validDetails);
resolve(request);
},
{ once: true }
);
iframe.src = url;
});
}
function testAbortShowIfDocumentIsNotActive() {
promise_test(async t => {
const iframe = document.createElement("iframe");
iframe.allow = "payment";
document.body.appendChild(iframe);
// We first got to page1.html, grab a PaymentRequest instance.
const request1 = await getLoadedPaymentRequest(
iframe,
"/payment-request/resources/page1.html"
);
// Save the DOMException of page1.html before navigating away.
const frameDOMException1 = iframe.contentWindow.DOMException;
// We navigate the iframe again, putting request1's document into an inactive state.
const request2 = await getLoadedPaymentRequest(
iframe,
"/payment-request/resources/page2.html"
);
// Now, request1's relevant global object's document is no longer active.
// So, call .show(), and make sure it rejects appropriately.
await promise_rejects_dom(
t,
"AbortError",
frameDOMException1,
request1.show(),
"Inactive document, so must throw AbortError"
);
// request2 has an active document tho, so confirm it's working as expected:
request2.show();
await request2.abort();
await promise_rejects_dom(
t,
"InvalidStateError",
iframe.contentWindow.DOMException,
request2.show(),
"Abort already called, so InvalidStateError"
);
// We are done, so clean up.
iframe.remove();
}, "PaymentRequest.show() aborts if the document is not active.");
}
function testAbortShowIfDocumentIsNotFullyActive() {
promise_test(async t => {
// We nest two iframes and wait for them to load.
const outerIframe = document.createElement("iframe");
outerIframe.allow = "payment";
document.body.appendChild(outerIframe);
// Load the outer iframe (we don't care about the awaited request)
await getLoadedPaymentRequest(
outerIframe,
"/payment-request/resources/page1.html"
);
// Now we create the inner iframe
const innerIframe = outerIframe.contentDocument.createElement("iframe");
innerIframe.allow = "payment";
// nest them
outerIframe.contentDocument.body.appendChild(innerIframe);
// load innerIframe, and get the PaymentRequest instance
const request = await getLoadedPaymentRequest(
innerIframe,
"/payment-request/resources/page2.html"
);
// Save DOMException from innerIframe before navigating away.
const innerIframeDOMException = innerIframe.contentWindow.DOMException;
// Navigate the outer iframe to a new location.
// Wait for the load event to fire.
await new Promise(resolve => {
outerIframe.addEventListener("load", resolve);
outerIframe.src = "/payment-request/resources/page2.html";
});
const showPromise = request.show();
// Now, request's relevant global object's document is still active
// (it is the active document of the inner iframe), but is not fully active
// (since the parent of the inner iframe is itself no longer active).
// So, call request.show() and make sure it rejects appropriately.
await promise_rejects_dom(
t,
"AbortError",
innerIframeDOMException,
showPromise,
"Active, but not fully active, so must throw AbortError"
);
// We are done, so clean up.
outerIframe.remove();
}, "PaymentRequest.show() aborts if the document is active, but not fully active.");
}
</script>
<h2>PaymentRequest show() rejects if doc is not fully active</h2>
<p>
Click on each button in sequence from top to bottom without refreshing the
page. Each button will bring up the Payment Request UI window and then will
close it automatically. (If a payment sheet stays open, the test has failed.)
</p>
<ol>
<li>
<button onclick="testAbortShowIfDocumentIsNotActive()">
PaymentRequest.show() aborts if the document is not active.
</button>
</li>
<li>
<button onclick="testAbortShowIfDocumentIsNotFullyActive()">
PaymentRequest.show() aborts if the document is active, but not fully
active.
</button>
</li>
<li><button onclick="done()">Done!</button></li>
</ol>
<small>
If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a>
and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">suggested reviewers</a>.
</small>