339 lines
9 KiB
HTML
339 lines
9 KiB
HTML
<!DOCTYPE html>
|
|
<meta charset="utf-8">
|
|
<title>Test for PaymentRequest.show(optional promise) method</title>
|
|
<link rel="help" href="https://w3c.github.io/browser-payment-api/#show-method">
|
|
<script src="/resources/testharness.js"></script>
|
|
<script src="/resources/testharnessreport.js"></script>
|
|
<script>
|
|
"use strict";
|
|
setup({
|
|
allow_uncaught_exception: true,
|
|
explicit_done: true,
|
|
explicit_timeout: true,
|
|
});
|
|
|
|
// DATA USED BY TESTS
|
|
// PaymentMethods
|
|
const validMethods = Object.freeze([
|
|
{
|
|
supportedMethods: "valid-but-wont-ever-match",
|
|
},
|
|
{
|
|
supportedMethods: "basic-card",
|
|
},
|
|
{
|
|
supportedMethods: "https://apple.com/apple-pay",
|
|
data: {
|
|
version: 3,
|
|
merchantIdentifier: "merchant.com.example",
|
|
countryCode: "US",
|
|
merchantCapabilities: ["supports3DS"],
|
|
supportedNetworks: ["visa"],
|
|
}
|
|
},
|
|
]);
|
|
|
|
// Amounts
|
|
const failAmount = Object.freeze({
|
|
currency: "USD",
|
|
value: "1.00",
|
|
});
|
|
const passAmount = Object.freeze({
|
|
currency: "CAD",
|
|
value: "50.00",
|
|
});
|
|
const neutralAmount = Object.freeze({
|
|
currency: "AUD",
|
|
value: "0.00",
|
|
});
|
|
|
|
// Labels
|
|
const failLabel = "💥 TEST HAS FAILED 💥";
|
|
const passLabel = "✅ TEST HAS PASSED ✅";
|
|
const neutralLabel = "Ignore this label";
|
|
// Totals
|
|
const failTotal = Object.freeze({
|
|
label: failLabel,
|
|
amount: failAmount,
|
|
});
|
|
const passTotal = Object.freeze({
|
|
label: passLabel,
|
|
amount: passAmount,
|
|
});
|
|
const neutralTotal = Object.freeze({
|
|
label: neutralLabel,
|
|
amount: passAmount,
|
|
});
|
|
|
|
// PaymentItem
|
|
const failPaymentItem = Object.freeze({
|
|
amount: failAmount,
|
|
label: failLabel,
|
|
});
|
|
const failPaymentItems = Object.freeze([failPaymentItem]);
|
|
|
|
const passPaymentItem = Object.freeze({
|
|
amount: passAmount,
|
|
label: passLabel,
|
|
});
|
|
const passPaymentItems = Object.freeze([passPaymentItem]);
|
|
|
|
// PaymentShippingOptions
|
|
const failShippingOption = Object.freeze({
|
|
id: "fail",
|
|
label: failLabel,
|
|
amount: failAmount,
|
|
});
|
|
const failShippingOptions = Object.freeze([failShippingOption]);
|
|
|
|
const neutralShippingOption = Object.freeze({
|
|
id: "neutral",
|
|
label: neutralLabel,
|
|
amount: neutralAmount,
|
|
});
|
|
|
|
const updatedShippingOption1 = Object.freeze({
|
|
id: "updated-1",
|
|
label: `${passLabel} - option 1`,
|
|
amount: passAmount,
|
|
});
|
|
const updatedShippingOption2 = Object.freeze({
|
|
id: "updated-2",
|
|
label: `${passLabel} - option 2 (MUST BE SELECTED!)`,
|
|
amount: passAmount,
|
|
selected: true,
|
|
});
|
|
const passShippingOptions = Object.freeze([
|
|
updatedShippingOption1,
|
|
updatedShippingOption2,
|
|
]);
|
|
|
|
// Modifiers
|
|
// create a modifier objects for each validMethods
|
|
// and single additional display item
|
|
const failModifiers = validMethods.map(modifier => {
|
|
const label = `${failLabel} - (${modifier.supportedMethods})`;
|
|
return {
|
|
...modifier,
|
|
total: {
|
|
...failTotal,
|
|
label,
|
|
},
|
|
additionalDisplayItems: [
|
|
{
|
|
...failPaymentItem,
|
|
label,
|
|
},
|
|
],
|
|
};
|
|
});
|
|
// Updates the total for each, and changes the additionalDisplayItems
|
|
const passModifiers = failModifiers.map(modifier => {
|
|
const label = `${passLabel} - (${modifier.supportedMethods})`;
|
|
return {
|
|
...modifier,
|
|
total: {
|
|
...passTotal,
|
|
label,
|
|
},
|
|
additionalDisplayItems: [
|
|
{
|
|
...passPaymentItem,
|
|
label,
|
|
},
|
|
],
|
|
};
|
|
});
|
|
|
|
// PaymentDetailsInit
|
|
const failDetails = Object.freeze({
|
|
displayItems: failPaymentItems,
|
|
id: "this cannot be changed",
|
|
modifiers: failModifiers,
|
|
shippingOptions: failShippingOptions,
|
|
total: failTotal,
|
|
});
|
|
|
|
const neutralDetails = Object.freeze({
|
|
displayItems: [],
|
|
modifiers: [],
|
|
shippingOptions: [neutralShippingOption],
|
|
total: neutralTotal,
|
|
});
|
|
|
|
function smokeTest() {
|
|
promise_test(async t => {
|
|
const request = new PaymentRequest(validMethods, failDetails);
|
|
await promise_rejects_js(
|
|
t,
|
|
TypeError,
|
|
request.show({
|
|
total: "This throws a TypeError",
|
|
}),
|
|
"expected TypeError"
|
|
);
|
|
}, "smoke test - checks if the optional details are supported on show() method");
|
|
}
|
|
|
|
function runUpdateDetailsAlgorithm(
|
|
buttonElement,
|
|
details,
|
|
options = {
|
|
requestShipping: true,
|
|
},
|
|
initialDetails = failDetails,
|
|
) {
|
|
const testAssertion = buttonElement.textContent.trim();
|
|
buttonElement.disabled = true;
|
|
promise_test(async t => {
|
|
const request = new PaymentRequest(validMethods, initialDetails, options);
|
|
const detailsPromise = Promise.resolve(details);
|
|
const acceptPromise = request.show(detailsPromise);
|
|
assert_equals(request.id, "this cannot be changed", "id must never change.");
|
|
await promise_rejects_dom(
|
|
t,
|
|
"AbortError",
|
|
acceptPromise,
|
|
"expected AbortError"
|
|
);
|
|
}, testAssertion);
|
|
}
|
|
</script>
|
|
<h2>
|
|
PaymentRequest <code>.show(optional detailsPromise)</code> tests
|
|
</h2>
|
|
<p>
|
|
These test cause <code>detailsPromise</code> to resolve successfully with some updated value. As such, that will cause
|
|
something in the payment sheet to change. Each test describes what is expected to change - if anything.
|
|
</p>
|
|
<p>
|
|
<strong>Instructions:</strong> Click on each button in sequence from top to bottom without refreshing the page. The payment
|
|
sheet will be shown. If required, confirm that the expected value appears in the payment sheet. Finally, manually abort/cancel
|
|
the payment request by closing the payment sheet.
|
|
</p>
|
|
<ol>
|
|
<li><button onclick="smokeTest()">If the payment sheet is shown, the test has failed.</button></li>
|
|
<li><button onclick="
|
|
const details = {
|
|
...neutralDetails,
|
|
id: 'fail',
|
|
};
|
|
runUpdateDetailsAlgorithm(this, details);
|
|
">
|
|
When the payment sheet is shown, the provided `id` must have no effect on the payment request.
|
|
</button></li>
|
|
<li><button onclick="
|
|
const details = {
|
|
...neutralDetails,
|
|
total: passTotal
|
|
};
|
|
runUpdateDetailsAlgorithm(this, details);
|
|
">
|
|
When the payment sheet is shown, the total must be CAD$50 with the label "✅ TEST HAS PASSED ✅".
|
|
</button></li>
|
|
<li><button onclick="
|
|
const details = {
|
|
...neutralDetails,
|
|
displayItems: passPaymentItems,
|
|
};
|
|
runUpdateDetailsAlgorithm(this, details);
|
|
">
|
|
When the payment sheet is shown, there must be a one display item with a value of CAD$50 with the label "✅ TEST HAS PASSED ✅".
|
|
</button>
|
|
</li>
|
|
<li><button onclick="
|
|
const auItem = {
|
|
...passPaymentItem,
|
|
amount: { value: '40', currency: 'AUD'},
|
|
pending: true
|
|
}
|
|
const details = {
|
|
...neutralDetails,
|
|
displayItems: passPaymentItems.concat(auItem),
|
|
};
|
|
runUpdateDetailsAlgorithm(this, details);
|
|
">
|
|
When the payment sheet is shown, there must be
|
|
two display items: One with a value of CAD$50, another with
|
|
value AUD$40 that is pending.
|
|
</button>
|
|
</li>
|
|
<li><button onclick="
|
|
const details = {
|
|
...neutralDetails,
|
|
shippingOptions: [updatedShippingOption1],
|
|
};
|
|
runUpdateDetailsAlgorithm(this, details);
|
|
">
|
|
When the payment sheet is shown, there must be a one shipping option
|
|
with a value of CAD$50.
|
|
</button>
|
|
</li>
|
|
<li><button onclick="
|
|
const details = {
|
|
...neutralDetails,
|
|
shippingOptions: passShippingOptions,
|
|
};
|
|
runUpdateDetailsAlgorithm(this, details);
|
|
">
|
|
When the payment sheet is shown, there must be
|
|
two shipping options: One with a value of CAD$50, another with
|
|
value AUD$40 that is selected.
|
|
</button>
|
|
</li>
|
|
<li><button onclick="
|
|
const details = {
|
|
...neutralDetails,
|
|
modifiers: passModifiers,
|
|
};
|
|
runUpdateDetailsAlgorithm(this, details);
|
|
">
|
|
When the payment sheet is shown, the total should be CAD$50.
|
|
</button>
|
|
</li>
|
|
<li>
|
|
<button onclick="
|
|
const details = {
|
|
...neutralDetails,
|
|
shippingOptions: [],
|
|
error: passLabel,
|
|
};
|
|
runUpdateDetailsAlgorithm(this, details);
|
|
">
|
|
When the payment sheet is shown, the string "✅ TEST HAS PASSED ✅" should be shown
|
|
somewhere in the user interface. Alternatively, the payment sheet must indicate to the
|
|
end user that it's not possible to ship their order.
|
|
</button>
|
|
</li>
|
|
<li>
|
|
<button onclick="
|
|
const details = {
|
|
...neutralDetails,
|
|
error: failLabel,
|
|
};
|
|
runUpdateDetailsAlgorithm(this, details, {requestShipping: false});
|
|
">
|
|
When the payment sheet is shown, there should not be any errors shown.
|
|
</button>
|
|
</li>
|
|
<li>
|
|
<button onclick="
|
|
const initialDetails = {total: passTotal, id: 'this cannot be changed'};
|
|
const updatedDetails = {};
|
|
runUpdateDetailsAlgorithm(
|
|
this, updatedDetails, {requestShipping: false}, initialDetails);
|
|
">
|
|
Resolving the show promise with empty details will preserve the details from
|
|
the constructor. When the payment sheet is shown, the string
|
|
"✅ TEST HAS PASSED ✅" should be shown.
|
|
</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>
|