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/helpers.js40
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/retry-method-manual.https.html296
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/retry-method-warnings-manual.https.html158
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/shippingAddress-attribute-manual.https.html101
-rw-r--r--testing/web-platform/tests/payment-request/payment-response/shippingOption-attribute-manual.https.html43
5 files changed, 638 insertions, 0 deletions
diff --git a/testing/web-platform/tests/payment-request/payment-response/helpers.js b/testing/web-platform/tests/payment-request/payment-response/helpers.js
index 1242ecb743..3e4f5cfd36 100644
--- a/testing/web-platform/tests/payment-request/payment-response/helpers.js
+++ b/testing/web-platform/tests/payment-request/payment-response/helpers.js
@@ -65,8 +65,30 @@ async function getPaymentRequestResponse(options, id) {
label: "Total due",
amount: { currency: "USD", value: "1.0" },
},
+ shippingOptions: [
+ {
+ id: "fail1",
+ label: "Fail option 1",
+ amount: { currency: "USD", value: "5.00" },
+ selected: false,
+ },
+ {
+ id: "pass",
+ label: "Pass option",
+ amount: { currency: "USD", value: "5.00" },
+ selected: true,
+ },
+ {
+ id: "fail2",
+ label: "Fail option 2",
+ amount: { currency: "USD", value: "5.00" },
+ selected: false,
+ },
+ ],
};
const request = new PaymentRequest(methods, details, options);
+ request.onshippingaddresschange = ev => ev.updateWith(details);
+ request.onshippingoptionchange = ev => ev.updateWith(details);
const response = await request.show();
return { request, response };
}
@@ -106,5 +128,23 @@ async function runManualTest(button, options, expected = {}, id = undefined) {
assert_equals(typeof response.details, "object", "Expected an object");
// Testing that this does not throw:
response.toJSON();
+ if (options && options.requestShipping) {
+ assert_equals(
+ response.shippingOption,
+ "pass",
+ "request.shippingOption must be 'pass'"
+ );
+ } else {
+ assert_equals(
+ request.shippingOption,
+ null,
+ "If requestShipping is falsy, request.shippingOption must be null"
+ );
+ assert_equals(
+ response.shippingOption,
+ null,
+ "request.shippingOption must be null"
+ );
+ }
}, button.textContent.trim());
}
diff --git a/testing/web-platform/tests/payment-request/payment-response/retry-method-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/retry-method-manual.https.html
new file mode 100644
index 0000000000..a5aab49e38
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/retry-method-manual.https.html
@@ -0,0 +1,296 @@
+<!doctype html>
+<meta charset="utf8">
+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-retry">
+<title>
+ PaymentResponse.prototype.retry() method
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helpers.js"></script>
+<script>
+test(() => {
+ assert_true(
+ "retry" in PaymentResponse.prototype,
+ "retry must be in prototype"
+ );
+ assert_true(
+ PaymentResponse.prototype.retry instanceof Function,
+ "retry must be a function"
+ );
+}, "PaymentResponse.prototype must have a retry() function (smoke test).");
+
+function checkCompletedCantRetry(button) {
+ button.disabled = true;
+ promise_test(async t => {
+ const { response } = await getPaymentRequestResponse();
+ // sets response.[[complete]] to true.
+ await response.complete("success");
+ return promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ response.retry(),
+ "response.[[complete]] is true, so rejects with InvalidStateError."
+ );
+ }, button.textContent.trim());
+}
+
+function repeatedCallsToRetry(button) {
+ button.disabled = true;
+ promise_test(async t => {
+ const { response } = await getPaymentRequestResponse();
+ const retryPromise = response.retry();
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ response.retry(),
+ "Calling retry() again rejects with an InvalidStateError"
+ );
+ await retryPromise;
+ await response.complete("success");
+ }, button.textContent.trim());
+}
+
+function callCompleteWhileRetrying(button) {
+ button.disabled = true;
+ promise_test(async t => {
+ const { response } = await getPaymentRequestResponse();
+ const retryPromise = response.retry();
+ const completePromise1 = response.complete("success");
+ const completePromise2 = response.complete("fail");
+ assert_not_equals(
+ completePromise1,
+ completePromise2,
+ "complete() must return unique promises"
+ );
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ completePromise1,
+ "Calling complete() while retrying rejects with an InvalidStateError"
+ );
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ completePromise2,
+ "Calling complete() while retrying rejects with an InvalidStateError"
+ );
+ assert_not_equals(
+ completePromise1,
+ completePromise2,
+ "complete() must return unique promises"
+ );
+ await retryPromise;
+ await response.complete("success");
+ }, button.textContent.trim());
+}
+
+function callingRequestAbortMustNotAbort(button) {
+ button.disabled = true;
+ promise_test(async t => {
+ const { response, request } = await getPaymentRequestResponse();
+ const retryPromise = response.retry();
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ request.abort(),
+ "Calling request.abort() while retrying rejects with an InvalidStateError"
+ );
+ await retryPromise;
+ await response.complete("success");
+ }, button.textContent.trim());
+}
+
+function canRetryMultipleTimes(button) {
+ button.disabled = true;
+ promise_test(async t => {
+ const { response } = await getPaymentRequestResponse();
+ assert_equals(
+ await response.retry(),
+ undefined,
+ "Expected undefined as the resolve value"
+ );
+ assert_equals(
+ await response.retry(),
+ undefined,
+ "Expected undefined as the resolve value"
+ );
+ await response.complete("success");
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ response.retry(),
+ "Calling retry() after complete() rejects with a InvalidStateError"
+ );
+ }, button.textContent.trim());
+}
+
+function userCanAbortARetry(button) {
+ button.disabled = true;
+ promise_test(async t => {
+ const { response } = await getPaymentRequestResponse();
+ await promise_rejects_dom(
+ t,
+ "AbortError",
+ response.retry(),
+ "The user aborting a retry rejects with a AbortError"
+ );
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ response.retry(),
+ "After the user aborts, response [[complete]] is true so retry() must reject with InvalidStateError"
+ );
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ response.complete("success"),
+ "After the user aborts, response [[complete]] is true, so complete() rejects with a InvalidStateError"
+ );
+ }, button.textContent.trim());
+}
+
+function userIsShownErrorsFields(button) {
+ button.disabled = true;
+ promise_test(async t => {
+ const { response, request } = await getPaymentRequestResponse({ requestShipping: true });
+ const retryPromise = response.retry({
+ shippingAddress: { city: "Invalid city", addressLine: "Invalid address line" },
+ });
+ await retryPromise;
+ await response.complete("success");
+ }, button.textContent.trim());
+}
+
+function abortTheUpdate(button) {
+ button.disabled = true;
+ promise_test(async t => {
+ const { response, request } = await getPaymentRequestResponse({
+ requestShipping: true,
+ });
+ const shipOptionChangePromise = new Promise(resolve => {
+ request.onshippingoptionchange = event => {
+ // causes "abort the update" to run
+ event.updateWith({ total: "error!" });
+ resolve();
+ };
+ });
+ const retryPromise = response.retry();
+ await shipOptionChangePromise;
+ await promise_rejects_js(
+ t,
+ TypeError,
+ retryPromise,
+ "retry() aborts with a TypeError, because totals' value is invalid"
+ );
+ await promise_rejects_dom(
+ t,
+ "InvalidStateError",
+ response.complete("success"),
+ "After the user aborts, response [[complete]] is true, so complete() rejects with a InvalidStateError"
+ );
+ }, button.textContent.trim());
+}
+
+function callingRetryReturnsUniquePromise(button){
+ button.disabled = true;
+ promise_test(async t => {
+ const { response } = await getPaymentRequestResponse();
+ const retryPromise = response.retry();
+ const promises = new Set([
+ retryPromise,
+ response.retry(),
+ response.retry(),
+ ]);
+ assert_equals(promises.size, 3, "Must have three unique objects");
+ await retryPromise;
+ await response.complete();
+ }, button.textContent.trim());
+};
+
+
+</script>
+<h2>
+ Manual Tests for PaymentResponse.retry() - 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" multiple times.
+</p>
+<ol>
+ <li>
+ <button onclick="checkCompletedCantRetry(this);">
+ A completed payment request cannot be retried.
+ </button>
+ </li>
+ <li>
+ <button onclick="repeatedCallsToRetry(this);">
+ Calling retry() more than once yield a rejected promise, but the
+ retryPromise resolves independently.
+ </button>
+ </li>
+ <li>
+ <button onclick="callCompleteWhileRetrying(this);">
+ Calling complete() while a retry() is in progress results in an InvalidStateError.
+ </button>
+ </li>
+ <li>
+ <button onclick="callingRequestAbortMustNotAbort(this);">
+ Trying to abort() via PaymentRequest is not possible.
+ </button>
+ </li>
+ <li>
+ <button onclick="canRetryMultipleTimes(this);">
+ It's possible to retry() multiple times and eventually complete().
+ After complete(), however, retry() rejects with an InvalidStateError.
+ </button>
+ </li>
+ <li>
+ <p>
+ When shown the payment sheet, hit pay once, then abort retrying the payment.
+ </p>
+ <button onclick="userCanAbortARetry(this);">
+ The user aborting retrying a payment causes the retryPromise to reject with AbortError.
+ Aborting a payment is causes it complete.
+ </button>
+ </li>
+ <li>
+ <p>
+ When shown the payment sheet, hit pay once. Check payment sheet for error fields.
+ Then hit escape or otherwise abort the payment.
+ </p>
+ <button onclick="userIsShownErrorsFields(this);">
+ When retrying, the user is shown error fields to fix.
+ </button>
+ </li>
+ <li>
+ <p>
+ When shown the payment sheet, hit pay once.
+ Then, change the shipping option.
+ Select to pay again.
+ </p>
+ <button onclick="abortTheUpdate(this);">
+ When "abort the update" occurs because of an update error,
+ the `retryPromise` is rejected and response.[[complete]] becomes true.
+ </button>
+ </li>
+ <li>
+ <p>
+ When shown the payment sheet, hit pay once. Then retry once.
+ </p>
+ <button onclick="callingRetryReturnsUniquePromise(this);">
+ Calling retry() multiple times is always a new object.
+ </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/retry-method-warnings-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/retry-method-warnings-manual.https.html
new file mode 100644
index 0000000000..b68bf18309
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/retry-method-warnings-manual.https.html
@@ -0,0 +1,158 @@
+<!DOCTYPE html> <meta charset="utf-8" />
+<title>Warn when errorFields don't match request[[options]]</title>
+<link rel="help" href="https://github.com/w3c/payment-request/pull/807" />
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helpers.js"></script>
+<script>
+ test(() => {
+ assert_true(
+ "retry" in PaymentResponse.prototype,
+ "retry must be in prototype"
+ );
+ assert_true(
+ PaymentResponse.prototype.retry instanceof Function,
+ "retry must be a function"
+ );
+ }, "PaymentResponse.prototype must have a retry() function (smoke test).");
+
+ const defaultOptions = {
+ requestPayerName: false,
+ requestPayerEmail: false,
+ requestPayerPhone: false,
+ requestShipping: false,
+ };
+ function testShowWarning(button, errorFields) {
+ button.disabled = true;
+ promise_test(async () => {
+ const { response } = await getPaymentRequestResponse(defaultOptions);
+ await response.retry(errorFields);
+ await response.complete();
+ });
+ }
+</script>
+<h2>Manual Tests - Please run in order!</h2>
+<p>
+ Please open the developer console. Each of the tests below should generate a
+ warning in the developer console.
+</p>
+<p>When presented with the payment sheet, hit pay twice.</p>
+<ol>
+ <li>
+ <button onclick="testShowWarning(this, {payer: {name: 'Dont show this'}});">
+ Show warning if `requestPayerName` if false, and `errorFields.payer.name` is
+ present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {payer: {email: 'Dont show this'}});"
+ >
+ Show warning if `requestPayerEmail` if false, and `errorFields.payer.email`
+ is present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {payer: {phone: 'Dont show this'}});"
+ >
+ Show warning if `requestPayerPhone` if false, and `errorFields.payer.phone`
+ is present.
+ </button>
+ </li>
+ <li>
+ <button onclick="testShowWarning(this, {shippingAddress: {}});">
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress` member present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {shippingAddress: {addressLine: 'Dont show this'}});"
+ >
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress.addressLine` member present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {shippingAddress: {city: 'Dont show this'}});"
+ >
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress.city` member present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {shippingAddress: {country: 'Dont show this'}});"
+ >
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress.country` member present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {shippingAddress: {dependentLocality: 'Dont show this'}});"
+ >
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress.dependentLocality` member present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {shippingAddress: {organization: 'Dont show this'}});"
+ >
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress.organization` member present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {shippingAddress: {phone: 'Dont show this'}});"
+ >
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress.phone` member present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {shippingAddress: {postalCode: 'Dont show this'}});"
+ >
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress.postalCode` member present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {shippingAddress: {recipient: 'Dont show this'}});"
+ >
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress.recipient` member present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {shippingAddress: {region: 'Dont show this'}});"
+ >
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress.region` member present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {shippingAddress: {regionCode: 'Dont show this'}});"
+ >
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress.regionCode` member present.
+ </button>
+ </li>
+ <li>
+ <button
+ onclick="testShowWarning(this, {shippingAddress: {sortingCode: 'Dont show this'}});"
+ >
+ Show warning if `requestShipping` if false, and
+ `errorFields.shippingAddress.sortingCode` member present.
+ </button>
+ </li>
+ <li><button onclick="done()">Done!</button></li>
+</ol>
diff --git a/testing/web-platform/tests/payment-request/payment-response/shippingAddress-attribute-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/shippingAddress-attribute-manual.https.html
new file mode 100644
index 0000000000..f9f0a6e4fa
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/shippingAddress-attribute-manual.https.html
@@ -0,0 +1,101 @@
+<!doctype html>
+<meta charset="utf8">
+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-shippingaddress">
+<title>
+ PaymentResponse.prototype.shippingAddress
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helpers.js"></script>
+<script>
+async function checkNullShippingAddress(button, options) {
+ button.disabled = true;
+ const { request, response } = await getPaymentRequestResponse(options);
+ await response.complete();
+ test(() => {
+ assert_idl_attribute(response, "shippingAddress");
+ assert_equals(
+ response.shippingAddress,
+ null,
+ "Expected response.shippingAddress to be null"
+ );
+ assert_equals(
+ request.shippingAddress,
+ null,
+ "Expected request.shippingAddress to be null"
+ );
+ }, button.textContent.trim());
+}
+
+async function runManualTest(button, options = {}, expected = {}, id) {
+ button.disabled = true;
+ const { request, response } = await getPaymentRequestResponse(options, id);
+ await response.complete();
+ test(() => {
+ assert_equals(response.requestId, request.id, `Expected ids to match`);
+ assert_idl_attribute(response, "shippingAddress");
+ const { shippingAddress: addr } = request;
+ assert_true(
+ addr instanceof ContactAddress,
+ "Expect instance of ContactAddress"
+ );
+ try {
+ addr.toJSON();
+ } catch (err) {
+ assert_unreached(
+ `Unexpected exception calling ContactAddress.toJSON(): ${err}`
+ );
+ }
+ if (expected.shippingAddress === null) {
+ return;
+ }
+ assert_equals(addr.country, "AF", "Expected AF for country");
+ assert_true(
+ addr.addressLine instanceof Array,
+ "Expected addressLine to be an array"
+ );
+ assert_equals(
+ addr.addressLine.toString(),
+ "1 wpt street",
+ "Expected '1 wpt street' for addressLine"
+ );
+ assert_equals(addr.city, "Kabul", "Expected city to be Kabul");
+ assert_equals(addr.postalCode, "1001", "Expect postalCode to be 1001");
+ assert_equals(addr.recipient, "web platform test");
+ }, button.textContent.trim());
+}
+</script>
+<h2>shippingAddress 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 enter "web platform test" as recipient, at address "1 wpt street" in "Kabul, Afghanistan", zip/postal code 1001.
+</p>
+<ol>
+ <li>
+ <button onclick="checkNullShippingAddress(this, undefined)">
+ If options is undefined, then shippingAddress must be null.
+ </button>
+ </li>
+ <li>
+ <button onclick="checkNullShippingAddress(this, {})">
+ If the requestShipping member is missing, then shippingAddress must be null.
+ </button>
+ </li>
+ <li>
+ <button onclick="checkNullShippingAddress(this, {requestShipping: false})">
+ If the requestShipping member is false, then shippingAddress must be null.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, {requestShipping: true}).then(done)">
+ If the requestShipping member is true, then shippingAddress must be "1 wpt street" in "Kabul, Afghanistan", zip code 1001.
+ </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/shippingOption-attribute-manual.https.html b/testing/web-platform/tests/payment-request/payment-response/shippingOption-attribute-manual.https.html
new file mode 100644
index 0000000000..687d3a52de
--- /dev/null
+++ b/testing/web-platform/tests/payment-request/payment-response/shippingOption-attribute-manual.https.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<meta charset="utf8">
+<link rel="help" href="https://w3c.github.io/payment-request/#dom-paymentresponse-shippingoption">
+<title>
+ PaymentResponse.prototype.complete() method
+</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script src="helpers.js"></script>
+<h2>shippingOption 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>
+ For the last test, please select the only available shipping option and select "Pay".
+</p>
+<ol>
+ <li>
+ <button onclick="runManualTest(this, undefined, { shippingOption: null })">
+ If the options is undefined, then shippingOption must be null.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestShipping: undefined }, { shippingOption: null })">
+ If the requestShipping member is missing, then shippingOption must be null.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestShipping: false }, { shippingOption: null })">
+ If the requestShipping member is false, then shippingOption must be null.
+ </button>
+ </li>
+ <li>
+ <button onclick="runManualTest(this, { requestShipping: true }, { shippingOption: 'pass' }).then(done)">
+ If the requestShipping member is true, then shippingOption must be the id of the selected shipping option ("pass").
+ </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>