summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/payment-request/payment-response
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/payment-request/payment-response')
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/complete-method-manual.https.html101
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/helpers.js110
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/methodName-attribute-manual.https.html28
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/onpayerdetailchange-attribute-manual.https.html73
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/onpayerdetailchange-attribute.https.html14
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/payerEmail-attribute-manual.https.html48
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/payerName-attribute-manual.https.html48
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/payerPhone-attribute-manual.https.html48
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/payerdetailschange-updateWith-immediate-manual.https.html68
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/payerdetailschange-updateWith-manual.https.html56
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/rejects_if_not_active-manual.https.html160
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/requestId-attribute-manual.https.html34
12 files changed, 788 insertions, 0 deletions
diff --git a/testing/web-platform/tests/payment-request/payment-response/complete-method-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/complete-method-manual.https.html
new file mode 100644
index 0000000000..f7facd7980
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/complete-method-manual.https.html
@@ -0,0 +1,101 @@
+<!doctype html>
+<meta charset="utf8">
+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-complete()">
+<title>
+ PaymentResponse.prototype.complete() method
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helpers.js"></script>
+<script>
+async function runManualTest({ completeWith: result }, button) {
+ button.disabled = true;
+ const { response, request } = await getPaymentRequestResponse();
+ promise_test(async t => {
+ let completePromise;
+ let invalidComplete;
+ let afterComplete;
+ try {
+ // We .complete() as normal, using the passed test value
+ completePromise = response.complete(result);
+ assert_true(completePromise instanceof Promise, "returns a promise");
+ // Immediately calling complete() again yields a rejected promise.
+ invalidComplete = response.complete(result);
+ await promise_rejects_dom(t, "InvalidStateError", invalidComplete);
+ // but the original promise is unaffected
+ const returnedValue = await completePromise;
+ assert_equals(
+ returnedValue,
+ undefined,
+ "Returned value must always be undefined"
+ );
+ // We now call .complete() again, to force an exception
+ // because [[complete]] is true.
+ afterComplete = response.complete(result);
+ await promise_rejects_dom(t, "InvalidStateError", afterComplete);
+ button.innerHTML = `✅ ${button.textContent}`;
+ } catch (err) {
+ button.innerHTML = `❌ ${button.textContent}`;
+ assert_unreached("Unexpected exception: " + err.message);
+ }
+ const allPromises = new Set([
+ completePromise,
+ invalidComplete,
+ afterComplete,
+ ]);
+ assert_equals(
+ allPromises.size,
+ 3,
+ "Calling complete() multiple times is always a new object."
+ );
+ }, button.textContent.trim());
+}
+</script>
+
+<h2>
+ Manual Tests for PaymentResponse.complete() - Please run in order!
+</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.
+</p>
+<p>
+ When presented with the payment sheet, use any credit card select to "Pay".
+ Also confirm any prompts that come up.
+</p>
+<ol>
+ <li>
+ <button onclick="runManualTest({completeWith: 'success'}, this)">
+ If the value of the internal slot [[completeCalled]] is true,
+ reject promise with an "InvalidStateError" DOMException.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest({completeWith: undefined}, this)">
+ Passing no argument defaults to "unknown",
+ eventually closing the sheet and doesn't throw.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest({completeWith: 'success'}, this)">
+ Passing "success" eventually closes the sheet and doesn't throw.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest({completeWith: 'fail'}, this)">
+ Passing "fail" eventually closes the sheet and doesn't throw.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest({completeWith: 'unknown'}, this)">
+ Passing "unknown" eventually closes the sheet and doesn't throw.
+ </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>
diff --git a/testing/web-platform/tests/payment-request/payment-response/helpers.js b/testing/web-platform/tests/payment-request/payment-response/helpers.js
new file mode 100644
index 0000000000..1242ecb743
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/helpers.js
@@ -0,0 +1,110 @@
+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 validAmount = Object.freeze({
+ currency: "USD",
+ value: "1.00",
+});
+
+const validTotal = Object.freeze({
+ label: "Valid total",
+ amount: validAmount,
+});
+const validDetails = {
+ total: validTotal,
+};
+
+test(() => {
+ try {
+ new PaymentRequest(validMethods, validDetails);
+ } catch (err) {
+ done();
+ throw err;
+ }
+}, "Can construct a payment request (smoke test).");
+
+/**
+ * Pops up a payment sheet, allowing options to be
+ * passed in if particular values are needed.
+ *
+ * @param PaymentOptions options
+ */
+async function getPaymentResponse(options, id) {
+ const { response } = await getPaymentRequestResponse(options, id);
+ return response;
+}
+
+/**
+ * Creates a payment request and response pair.
+ * It also shows the payment sheet.
+ *
+ * @param {PaymentOptions?} options
+ * @param {String?} id
+ */
+async function getPaymentRequestResponse(options, id) {
+ const methods = [{ supportedMethods: "basic-card" }];
+ const details = {
+ id,
+ total: {
+ label: "Total due",
+ amount: { currency: "USD", value: "1.0" },
+ },
+ };
+ const request = new PaymentRequest(methods, details, options);
+ const response = await request.show();
+ return { request, response };
+}
+
+/**
+ * Runs a manual test for payment
+ *
+ * @param {HTMLButtonElement} button The HTML button.
+ * @param {PaymentOptions?} options.
+ * @param {Object} expected What property values are expected to pass the test.
+ * @param {String?} id And id for the request/response pair.
+ */
+async function runManualTest(button, options, expected = {}, id = undefined) {
+ button.disabled = true;
+ const { request, response } = await getPaymentRequestResponse(options, id);
+ await response.complete();
+ test(() => {
+ assert_idl_attribute(
+ response,
+ "requestId",
+ "Expected requestId to be an IDL attribute."
+ );
+ assert_equals(response.requestId, request.id, `Expected ids to match`);
+ for (const [attribute, value] of Object.entries(expected)) {
+ assert_idl_attribute(
+ response,
+ attribute,
+ `Expected ${attribute} to be an IDL attribute.`
+ );
+ assert_equals(
+ response[attribute],
+ value,
+ `Expected response ${attribute} attribute to be ${value}`
+ );
+ }
+ assert_idl_attribute(response, "details");
+ assert_equals(typeof response.details, "object", "Expected an object");
+ // Testing that this does not throw:
+ response.toJSON();
+ }, button.textContent.trim());
+}
diff --git a/testing/web-platform/tests/payment-request/payment-response/methodName-attribute-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/methodName-attribute-manual.https.html
new file mode 100644
index 0000000000..0a8ef6c77e
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/methodName-attribute-manual.https.html
@@ -0,0 +1,28 @@
+<!doctype html>
+<meta charset="utf8">
+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-methodname">
+<title>
+ PaymentResponse.prototype.methodName attribute
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helpers.js"></script>
+<h2>methodName attribute</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.
+</p>
+<p>
+ Use any credit card and any values.
+</p>
+<ol>
+ <li>
+ <button onclick="runManualTest(this, {}, { methodName: 'basic-card' }).then(done)">
+ Expect the payment method identifier to be 'basic-card'.
+ </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>
diff --git a/testing/web-platform/tests/payment-request/payment-response/onpayerdetailchange-attribute-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/onpayerdetailchange-attribute-manual.https.html
new file mode 100644
index 0000000000..5731952c0e
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/onpayerdetailchange-attribute-manual.https.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>PaymentResponse.prototype.onpayerdetailchange attribute</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="helpers.js"></script>
+<script>
+function runTest(button, options, expected){
+ button.disabled = true;
+ promise_test(async () => {
+ const response = await getPaymentResponse(options);
+ const eventPromise = new Promise(resolve => {
+ response.addEventListener("payerdetailchange", resolve);
+ });
+ const error = button.previousElementSibling.textContent.trim();
+ await response.retry({ error });
+ const event = await eventPromise;
+ assert_true(event instanceof PaymentRequestUpdateEvent);
+ for([prop, value] of Object.entries(expected)){
+ if (prop === 'payerPhone') {
+ // |payerPhone| may optionally adhere to E164 structure, which does not
+ // contain formatting, e.g. +180000000 instead of +1-800-000-0000.
+ // Strip out the formatting in case the user agent implements E164.
+ // https://w3c.github.io/payment-request/#addressinit-dictionary
+ value = value.replace(/[-\(\) ]/g, '');
+ }
+ assert_equals(response[prop], value);
+ }
+ await response.complete("success");
+ }, button.textContent.trim());
+}
+</script>
+<h2>Handling PaymentResponse.prototype.onpayerdetailchange events</h2>
+<p>
+ Each button will bring up the Payment Request UI window.
+ When shown the payment sheet, use any details and hit pay.
+</p>
+<p>
+ When asked to retry the payment:
+</p>
+<ol>
+ <li>
+ <p>
+ Change payer's name to "pass".
+ </p>
+ <button onclick="runTest(this, { requestPayerName: true }, { payerName: 'pass' });">
+ PaymentRequestUpdateEvent is dispatched when payer name changes.
+ </button>
+ </li>
+ <li>
+ <p>
+ Change payer's email to "pass@pass.pass".
+ </p>
+ <button onclick="runTest(this, {requestPayerEmail: true}, { payerEmail: 'pass@pass.pass' });">
+ PaymentRequestUpdateEvent is dispatched when payer email changes.
+ </button>
+ </li>
+ <li>
+ <p>
+ Change payer's phone to "+1-800-000-0000".
+ </p>
+ <button onclick="runTest(this, {requestPayerPhone: true}, { payerPhone: '+18000000000' })">
+ PaymentRequestUpdateEvent is dispatched when payer phone changes.
+ </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">owners</a>.
+</small>
diff --git a/testing/web-platform/tests/payment-request/payment-response/onpayerdetailchange-attribute.https.html b/testing/web-platform/tests/payment-request/payment-response/onpayerdetailchange-attribute.https.html
new file mode 100644
index 0000000000..ed9e6e885b
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/onpayerdetailchange-attribute.https.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>PaymentResponse.prototype.onpayerdetailschange attribute</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script>
+test(() => {
+ assert_equals(Object.getPrototypeOf(PaymentResponse), window.EventTarget);
+}, "PaymentResponse inherits from EventTarget");
+
+test(() => {
+ assert_true("onpayerdetailchange" in PaymentResponse.prototype);
+}, "PaymentResponse has an onpayerdetailchange in the prototype chain");
+</script>
diff --git a/testing/web-platform/tests/payment-request/payment-response/payerEmail-attribute-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/payerEmail-attribute-manual.https.html
new file mode 100644
index 0000000000..28ce4c28a8
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/payerEmail-attribute-manual.https.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<meta charset="utf8">
+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-payeremail">
+<title>
+ PaymentResponse.prototype.payerEmail attribute
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helpers.js"></script>
+<h2>payerEmail attribute</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.
+</p>
+<p>
+ When requested, please use "wpt@w3.org" as the email.
+</p>
+<ol>
+ <li>
+ <button onclick="runManualTest(this, undefined, { payerEmail: null })">
+ payerEmail attribute is null when options undefined.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerEmail: undefined }, { payerEmail: null })">
+ payerEmail attribute is null when requestPayerEmail is undefined.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerEmail: false }, { payerEmail: null })">
+ payerEmail attribute is null when requestPayerEmail is false.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerEmail: true }, { payerEmail: 'wpt@w3.org' })">
+ payerEmail attribute is 'wpt@w3.org' when requestPayerEmail is true.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerEmail: 'yep' }, { payerEmail: 'wpt@w3.org' }).then(done)">
+ payerEmail attribute is 'wpt@w3.org' when requestPayerEmail is truthy.
+ </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>
diff --git a/testing/web-platform/tests/payment-request/payment-response/payerName-attribute-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/payerName-attribute-manual.https.html
new file mode 100644
index 0000000000..44d741ae45
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/payerName-attribute-manual.https.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<meta charset="utf8">
+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-payername">
+<title>
+ PaymentResponse.prototype.payerName attribute
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helpers.js"></script>
+<h2>payerName attribute</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.
+</p>
+<p>
+ When requested, please use "web platform test" as the payer name.
+</p>
+<ol>
+ <li>
+ <button onclick="runManualTest(this, undefined, { payerName: null })">
+ payerName attribute is null when option is undefined.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerName: undefined }, { payerName: null })">
+ payerName attribute is null when requestPayerName is undefined.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerName: false }, { payerName: null })">
+ payerName attribute is null when requestPayerName is false.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerName: true }, { payerName: 'web platform test' })">
+ payerName attribute is 'web platform test' when requestPayerName is true.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerName: 'yep' }, { payerName: 'web platform test' }).then(done)">
+ payerName attribute is 'web platform test' when requestPayerName is truthy.
+ </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>
diff --git a/testing/web-platform/tests/payment-request/payment-response/payerPhone-attribute-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/payerPhone-attribute-manual.https.html
new file mode 100644
index 0000000000..85a44a819c
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/payerPhone-attribute-manual.https.html
@@ -0,0 +1,48 @@
+<!doctype html>
+<meta charset="utf8">
+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-payerphone">
+<title>
+ PaymentResponse.prototype.payerPhone attribute
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helpers.js"></script>
+<h2>payerPhone attribute</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.
+</p>
+<p>
+ When prompted, please use +12345678910 as the phone number.
+</p>
+<ol>
+ <li>
+ <button onclick="runManualTest(this, undefined, { payerPhone: null })">
+ payerPhone attribute is null when options is undefined.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerPhone: undefined }, { payerPhone: null })">
+ payerPhone attribute is null when requestPayerPhone is undefined.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerPhone: false }, { payerPhone: null })">
+ payerPhone attribute is null when requestPayerPhone is false.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerPhone: true }, { payerPhone: '+12345678910' })">
+ payerPhone attribute is '+12345678910' when requestPayerPhone is true.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestPayerPhone: 'yep' }, { payerPhone: '+12345678910' }).then(done)">
+ payerPhone attribute is '+12345678910' when requestPayerPhone is truthy.
+ </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>
diff --git a/testing/web-platform/tests/payment-request/payment-response/payerdetailschange-updateWith-immediate-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/payerdetailschange-updateWith-immediate-manual.https.html
new file mode 100644
index 0000000000..7e35d78700
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/payerdetailschange-updateWith-immediate-manual.https.html
@@ -0,0 +1,68 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Dispatching PaymentRequestUpdateEvent for "payerdetailschange"</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="helpers.js"></script>
+<script>
+function testImmediateUpdate({ textContent: testName }) {
+ promise_test(async t => {
+ const response = await getPaymentResponse({ requestPayerName: true });
+ const eventPromise = new Promise((resolve, reject) => {
+ response.addEventListener(
+ "payerdetailchange",
+ ev => {
+ // Forces updateWith() to be run in the next event loop tick so that
+ // [[waitForUpdate]] is already true when it runs.
+ t.step_timeout(() => {
+ try {
+ ev.updateWith({});
+ resolve(); // This is bad.
+ } catch (err) {
+ reject(err); // this is good.
+ }
+ });
+ },
+ { once: true }
+ );
+ });
+
+ const retryPromise = response.retry({
+ payer: { name: "Change me!" },
+ });
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ eventPromise,
+ "The event loop already spun, so [[waitForUpdate]] is now true"
+ );
+ await retryPromise;
+ await response.complete("success");
+ }, testName.trim());
+}
+</script>
+<h2>Handling PaymentResponse.prototype.onpayerdetailchange events</h2>
+<p>
+ The test brings up the Payment Request UI window.
+ When shown the payment sheet, use any details and hit pay.
+</p>
+<p>
+ When asked to retry the payment:
+</p>
+<ol>
+ <li>
+ <p>
+ Change payer's name to anything.
+ </p>
+ <button onclick="testImmediateUpdate(this);">
+ updateWith() must be called immediately, otherwise must throw an InvalidStateError.
+ </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">owners</a>.
+</small>
diff --git a/testing/web-platform/tests/payment-request/payment-response/payerdetailschange-updateWith-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/payerdetailschange-updateWith-manual.https.html
new file mode 100644
index 0000000000..1a7342365d
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/payerdetailschange-updateWith-manual.https.html
@@ -0,0 +1,56 @@
+<!doctype html>
+<meta charset=utf-8>
+<title>Dispatching PaymentRequestUpdateEvent for "payerdetailschange"</title>
+<script src=/resources/testharness.js></script>
+<script src=/resources/testharnessreport.js></script>
+<script src="helpers.js"></script>
+<script>
+function runTest(button) {
+ button.disabled = true;
+ promise_test(async t => {
+ const response = await getPaymentResponse({ requestPayerName: true });
+ const eventPromise = new Promise((_, reject) => {
+ response.addEventListener("payerdetailchange", ev => {
+ // [[waitForUpdate]] becomes true...
+ ev.updateWith({});
+ // So calling it again throws "InvalidStateError".
+ try {
+ ev.updateWith({});
+ } catch (err) {
+ reject(err);
+ }
+ });
+ });
+ await response.retry({
+ payer: { name: "Change me!" },
+ });
+ await promise_rejects_dom(t, "InvalidStateError", eventPromise);
+ await response.complete("success");
+ }, button.textContent.trim());
+}
+</script>
+<h2>Handling PaymentResponse.prototype.onpayerdetailchange events</h2>
+<p>
+ The test brings up the Payment Request UI window.
+ When shown the payment sheet, use any details and hit pay.
+</p>
+<p>
+ When asked to retry the payment:
+</p>
+<ol>
+ <li>
+ <p>
+ Change payer's name to anything.
+ </p>
+ <button onclick="runTest(this);">
+ Calling PaymentRequestUpdateEvent updateWith() twice throws an "InvalidStateError".
+ </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">owners</a>.
+</small>
diff --git a/testing/web-platform/tests/payment-request/payment-response/rejects_if_not_active-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/rejects_if_not_active-manual.https.html
new file mode 100644
index 0000000000..6f2e9e95d4
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/rejects_if_not_active-manual.https.html
@@ -0,0 +1,160 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<link rel="help" href="https://w3c.github.io/payment-request/#retry-method">
+<title>PaymentResponse retry() rejects if doc is not fully active</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-retry">
+<body>
+<script>
+setup({ explicit_done: true, explicit_timeout: true });
+const validMethod = Object.freeze({
+ supportedMethods: "basic-card",
+});
+const applePay = Object.freeze({
+ supportedMethods: "https://apple.com/apple-pay",
+ data: {
+ version: 3,
+ merchantIdentifier: "merchant.com.example",
+ countryCode: "US",
+ merchantCapabilities: ["supports3DS"],
+ supportedNetworks: ["visa"],
+ }
+});
+const validMethods = Object.freeze([validMethod, applePay]);
+const validAmount = Object.freeze({
+ currency: "USD",
+ value: "5.00",
+});
+const validTotal = Object.freeze({
+ label: "Total due",
+ amount: validAmount,
+});
+const validDetails = Object.freeze({
+ total: validTotal,
+});
+
+function getLoadedPaymentResponse(iframe, url) {
+ return new Promise(resolve => {
+ iframe.addEventListener(
+ "load",
+ async () => {
+ const { PaymentRequest } = iframe.contentWindow;
+ const response = await new PaymentRequest(
+ validMethods,
+ validDetails
+ ).show();
+ resolve(response);
+ },
+ { once: true }
+ );
+ iframe.src = url;
+ });
+}
+
+function methodNotFullyActive(button, method, ...args) {
+ const text = button.textContent.trim();
+ promise_test(async t => {
+ const iframe = document.createElement("iframe");
+ iframe.allow = "payment";
+ document.body.appendChild(iframe);
+
+ // We first got to page1.html, grab a PaymentResponse instance.
+ const response = await getLoadedPaymentResponse(
+ iframe,
+ "/payment-request/resources/page1.html"
+ );
+ // We navigate the iframe again, putting response's document into an inactive state.
+ await new Promise(resolve => {
+ iframe.addEventListener("load", resolve);
+ iframe.src = "/payment-request/resources/page2.html";
+ });
+ // Now, response's relevant global object's document is no longer active.
+ // So, promise needs to reject appropriately.
+ const promise = response[methodName](...args);
+ await promise_rejects_dom(
+ t,
+ "AbortError",
+ promise,
+ "Inactive document, so must throw AbortError"
+ );
+ // We are done, so clean up.
+ iframe.remove();
+ }, text);
+}
+
+function methodBecomesNotFullyActive(button, methodName, ...args) {
+ const text = button.textContent.trim();
+ promise_test(async t => {
+ const iframe = document.createElement("iframe");
+ iframe.allow = "payment";
+ document.body.appendChild(iframe);
+
+ // We first got to page1.html, grab a PaymentResponse instance.
+ const response = await getLoadedPaymentResponse(
+ iframe,
+ "/payment-request/resources/page1.html"
+ );
+
+ // we get the promise from page1.html, while it's active!
+ const promise = response[methodName](...args);
+
+ // We navigate the iframe again, putting response's document into an inactive state.
+ await new Promise(resolve => {
+ iframe.addEventListener("load", resolve);
+ iframe.src = "/payment-request/resources/page2.html";
+ });
+
+ // Now, response's relevant global object's document is no longer active.
+ // So, promise needs to reject appropriately.
+ await promise_rejects_dom(
+ t,
+ "AbortError",
+ promise,
+ "Inactive document, so must throw AbortError"
+ );
+ // We are done, so clean up.
+ iframe.remove();
+ }, text);
+}
+</script>
+<section>
+ <p>
+ For each test, when the payment sheet is shown, select a payment method and hit "Pay".
+ </p>
+ <h2>retry() and document active state</h2>
+ <p>Manual Tests for PaymentResponse.retry() - Please run in order!</p>
+ <ol>
+ <li>
+ <button onclick="methodNotFullyActive(this, 'retry', {});">
+ retry()'s retryPromise rejects if document is not fully active.
+ </button>
+ </li>
+ <li>
+ <button onclick="methodBecomesNotFullyActive(this, 'retry', {});">
+ retry()'s retryPromise rejects if the document becomes not fully active.
+ </button>
+ </li>
+ </ol>
+ <h2>complete() and document active state</h2>
+ <p>Manual Tests for PaymentResponse.complete() - Please run in order!</p>
+ <ol>
+ <li>
+ <button onclick="methodNotFullyActive(this, 'complete', 'success');">
+ complete()'s completePromise rejects if document is not fully active.
+ </button>
+ </li>
+ <li>
+ <button onclick="methodBecomesNotFullyActive(this, 'complete', 'success');">
+ complete()'s completePromise rejects if the document becomes not fully active.
+ </button>
+ </li>
+ <li>
+ <button onclick="done();">Done</button>
+ </li>
+ </ol>
+</section>
+<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>
diff --git a/testing/web-platform/tests/payment-request/payment-response/requestId-attribute-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/requestId-attribute-manual.https.html
new file mode 100644
index 0000000000..ddb1e0d831
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/requestId-attribute-manual.https.html
@@ -0,0 +1,34 @@
+<!doctype html>
+<meta charset="utf8">
+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-requestid">
+<title>
+ PaymentResponse.prototype.requestId attribute
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helpers.js"></script>
+<h2>requestId attribute</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.
+</p>
+<p>
+ When presented with the payment sheet, use any credit card select to "Pay".
+ Also confirm any prompts that come up.
+</p>
+<ol>
+ <li>
+ <button onclick="runManualTest(this, {}, {})">
+ Must mirror the payment request's automatically set id
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, {}, {requestId: 'pass'}, 'pass').then(done)">
+ Must mirror the payment request's explicitly set id
+ </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>