retry-method-manual.https.html (9051B)
1 <!doctype html> 2 <meta charset="utf8"> 3 <link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-retry"> 4 <title> 5 PaymentResponse.prototype.retry() method 6 </title> 7 <script src="/resources/testharness.js"></script> 8 <script src="/resources/testharnessreport.js"></script> 9 <script src="helpers.js"></script> 10 <script> 11 test(() => { 12 assert_true( 13 "retry" in PaymentResponse.prototype, 14 "retry must be in prototype" 15 ); 16 assert_true( 17 PaymentResponse.prototype.retry instanceof Function, 18 "retry must be a function" 19 ); 20 }, "PaymentResponse.prototype must have a retry() function (smoke test)."); 21 22 function checkCompletedCantRetry(button) { 23 button.disabled = true; 24 promise_test(async t => { 25 const { response } = await getPaymentRequestResponse(); 26 // sets response.[[complete]] to true. 27 await response.complete("success"); 28 return promise_rejects_dom( 29 t, 30 "InvalidStateError", 31 response.retry(), 32 "response.[[complete]] is true, so rejects with InvalidStateError." 33 ); 34 }, button.textContent.trim()); 35 } 36 37 function repeatedCallsToRetry(button) { 38 button.disabled = true; 39 promise_test(async t => { 40 const { response } = await getPaymentRequestResponse(); 41 const retryPromise = response.retry(); 42 await promise_rejects_dom( 43 t, 44 "InvalidStateError", 45 response.retry(), 46 "Calling retry() again rejects with an InvalidStateError" 47 ); 48 await retryPromise; 49 await response.complete("success"); 50 }, button.textContent.trim()); 51 } 52 53 function callCompleteWhileRetrying(button) { 54 button.disabled = true; 55 promise_test(async t => { 56 const { response } = await getPaymentRequestResponse(); 57 const retryPromise = response.retry(); 58 const completePromise1 = response.complete("success"); 59 const completePromise2 = response.complete("fail"); 60 assert_not_equals( 61 completePromise1, 62 completePromise2, 63 "complete() must return unique promises" 64 ); 65 await promise_rejects_dom( 66 t, 67 "InvalidStateError", 68 completePromise1, 69 "Calling complete() while retrying rejects with an InvalidStateError" 70 ); 71 await promise_rejects_dom( 72 t, 73 "InvalidStateError", 74 completePromise2, 75 "Calling complete() while retrying rejects with an InvalidStateError" 76 ); 77 assert_not_equals( 78 completePromise1, 79 completePromise2, 80 "complete() must return unique promises" 81 ); 82 await retryPromise; 83 await response.complete("success"); 84 }, button.textContent.trim()); 85 } 86 87 function callingRequestAbortMustNotAbort(button) { 88 button.disabled = true; 89 promise_test(async t => { 90 const { response, request } = await getPaymentRequestResponse(); 91 const retryPromise = response.retry(); 92 await promise_rejects_dom( 93 t, 94 "InvalidStateError", 95 request.abort(), 96 "Calling request.abort() while retrying rejects with an InvalidStateError" 97 ); 98 await retryPromise; 99 await response.complete("success"); 100 }, button.textContent.trim()); 101 } 102 103 function canRetryMultipleTimes(button) { 104 button.disabled = true; 105 promise_test(async t => { 106 const { response } = await getPaymentRequestResponse(); 107 assert_equals( 108 await response.retry(), 109 undefined, 110 "Expected undefined as the resolve value" 111 ); 112 assert_equals( 113 await response.retry(), 114 undefined, 115 "Expected undefined as the resolve value" 116 ); 117 await response.complete("success"); 118 await promise_rejects_dom( 119 t, 120 "InvalidStateError", 121 response.retry(), 122 "Calling retry() after complete() rejects with a InvalidStateError" 123 ); 124 }, button.textContent.trim()); 125 } 126 127 function userCanAbortARetry(button) { 128 button.disabled = true; 129 promise_test(async t => { 130 const { response } = await getPaymentRequestResponse(); 131 await promise_rejects_dom( 132 t, 133 "AbortError", 134 response.retry(), 135 "The user aborting a retry rejects with a AbortError" 136 ); 137 await promise_rejects_dom( 138 t, 139 "InvalidStateError", 140 response.retry(), 141 "After the user aborts, response [[complete]] is true so retry() must reject with InvalidStateError" 142 ); 143 await promise_rejects_dom( 144 t, 145 "InvalidStateError", 146 response.complete("success"), 147 "After the user aborts, response [[complete]] is true, so complete() rejects with a InvalidStateError" 148 ); 149 }, button.textContent.trim()); 150 } 151 152 function userIsShownErrorsFields(button) { 153 button.disabled = true; 154 promise_test(async t => { 155 const { response, request } = await getPaymentRequestResponse({ requestShipping: true }); 156 const retryPromise = response.retry({ 157 shippingAddress: { city: "Invalid city", addressLine: "Invalid address line" }, 158 }); 159 await retryPromise; 160 await response.complete("success"); 161 }, button.textContent.trim()); 162 } 163 164 function abortTheUpdate(button) { 165 button.disabled = true; 166 promise_test(async t => { 167 const { response, request } = await getPaymentRequestResponse({ 168 requestShipping: true, 169 }); 170 const shipOptionChangePromise = new Promise(resolve => { 171 request.onshippingoptionchange = event => { 172 // causes "abort the update" to run 173 event.updateWith({ total: "error!" }); 174 resolve(); 175 }; 176 }); 177 const retryPromise = response.retry(); 178 await shipOptionChangePromise; 179 await promise_rejects_js( 180 t, 181 TypeError, 182 retryPromise, 183 "retry() aborts with a TypeError, because totals' value is invalid" 184 ); 185 await promise_rejects_dom( 186 t, 187 "InvalidStateError", 188 response.complete("success"), 189 "After the user aborts, response [[complete]] is true, so complete() rejects with a InvalidStateError" 190 ); 191 }, button.textContent.trim()); 192 } 193 194 function callingRetryReturnsUniquePromise(button){ 195 button.disabled = true; 196 promise_test(async t => { 197 const { response } = await getPaymentRequestResponse(); 198 const retryPromise = response.retry(); 199 const promises = new Set([ 200 retryPromise, 201 response.retry(), 202 response.retry(), 203 ]); 204 assert_equals(promises.size, 3, "Must have three unique objects"); 205 await retryPromise; 206 await response.complete(); 207 }, button.textContent.trim()); 208 }; 209 210 211 </script> 212 <h2> 213 Manual Tests for PaymentResponse.retry() - Please run in order! 214 </h2> 215 <p> 216 Click on each button in sequence from top to bottom without refreshing the page. 217 Each button will bring up the Payment Request UI window. 218 </p> 219 <p> 220 When presented with the payment sheet, use any credit card select to "Pay" multiple times. 221 </p> 222 <ol> 223 <li> 224 <button onclick="checkCompletedCantRetry(this);"> 225 A completed payment request cannot be retried. 226 </button> 227 </li> 228 <li> 229 <button onclick="repeatedCallsToRetry(this);"> 230 Calling retry() more than once yield a rejected promise, but the 231 retryPromise resolves independently. 232 </button> 233 </li> 234 <li> 235 <button onclick="callCompleteWhileRetrying(this);"> 236 Calling complete() while a retry() is in progress results in an InvalidStateError. 237 </button> 238 </li> 239 <li> 240 <button onclick="callingRequestAbortMustNotAbort(this);"> 241 Trying to abort() via PaymentRequest is not possible. 242 </button> 243 </li> 244 <li> 245 <button onclick="canRetryMultipleTimes(this);"> 246 It's possible to retry() multiple times and eventually complete(). 247 After complete(), however, retry() rejects with an InvalidStateError. 248 </button> 249 </li> 250 <li> 251 <p> 252 When shown the payment sheet, hit pay once, then abort retrying the payment. 253 </p> 254 <button onclick="userCanAbortARetry(this);"> 255 The user aborting retrying a payment causes the retryPromise to reject with AbortError. 256 Aborting a payment is causes it complete. 257 </button> 258 </li> 259 <li> 260 <p> 261 When shown the payment sheet, hit pay once. Check payment sheet for error fields. 262 Then hit escape or otherwise abort the payment. 263 </p> 264 <button onclick="userIsShownErrorsFields(this);"> 265 When retrying, the user is shown error fields to fix. 266 </button> 267 </li> 268 <li> 269 <p> 270 When shown the payment sheet, hit pay once. 271 Then, change the shipping option. 272 Select to pay again. 273 </p> 274 <button onclick="abortTheUpdate(this);"> 275 When "abort the update" occurs because of an update error, 276 the `retryPromise` is rejected and response.[[complete]] becomes true. 277 </button> 278 </li> 279 <li> 280 <p> 281 When shown the payment sheet, hit pay once. Then retry once. 282 </p> 283 <button onclick="callingRetryReturnsUniquePromise(this);"> 284 Calling retry() multiple times is always a new object. 285 </button> 286 </li> 287 <li> 288 <button onclick="done();"> 289 Done! 290 </button> 291 </li> 292 </ol> 293 <small> 294 If you find a buggy test, please <a href="https://github.com/web-platform-tests/wpt/issues">file a bug</a> 295 and tag one of the <a href="https://github.com/web-platform-tests/wpt/blob/master/payment-request/META.yml">owners</a>. 296 </small>