-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revert "Remove shipping related things from payment-request (#28830)" #44409
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
<!doctype html> | ||
<meta charset="utf8"> | ||
<link rel="help" href="https://www.w3.org/TR/payment-request/#ContactAddress-interface"> | ||
<title> | ||
PaymentResponse.prototype.shippingAddress | ||
</title> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script src="../payment-response/helpers.js"></script> | ||
<script> | ||
const options = { requestShipping: true }; | ||
function runManualTest(button, expected = {}) { | ||
button.disabled = true; | ||
promise_test(async () => { | ||
const { response } = await getPaymentRequestResponse(options); | ||
await response.complete(); | ||
assert_idl_attribute(response, "shippingAddress"); | ||
const { shippingAddress: addr } = response; | ||
assert_true( | ||
addr instanceof ContactAddress, | ||
"Expect instance of ContactAddress" | ||
); | ||
// An [ISO3166] alpha-2 code. The canonical form is upper case. | ||
const { country } = addr; | ||
assert_equals(country.length, 2, "Expected length is 2"); | ||
assert_true(/^[A-Z]{2}$/.test(country), "Canonical form is upper case"); | ||
assert_true( | ||
addr.addressLine instanceof Array, | ||
"Expected addressLine to be an array" | ||
); | ||
assert_throws_js( | ||
TypeError, | ||
() => { | ||
addr.addressLine.push("this must throw"); | ||
}, | ||
"Array must be frozen" | ||
); | ||
for (let [attr, expectedValue] of Object.entries(expected)) { | ||
assert_idl_attribute(addr, attr); | ||
const msg = `Expected ContactAddress.${attr} to equal ${expectedValue}.`; | ||
//.toString() flattens array addressLine, | ||
//.toLowerCase() because case can't be enforced for some attributes | ||
const actualValue = addr[attr].toString().toLowerCase(); | ||
expectedValue = expectedValue.toString().toLowerCase(); | ||
assert_equals(actualValue, expectedValue, msg); | ||
} | ||
// Check toJSON result | ||
for (let [prop, jsonValue] of Object.entries(addr.toJSON())) { | ||
const actualValue = jsonValue.toString().toLowerCase(); | ||
const expectedValue = expected[prop].toString().toLowerCase(); | ||
const msg = `Expected JSON ${prop} to be ${expectedValue}`; | ||
assert_equals(actualValue, expectedValue, msg); | ||
} | ||
}, button.textContent.trim()); | ||
done(); | ||
} | ||
</script> | ||
<h2>ContactAddress interface</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 addresses as follows... | ||
</p> | ||
<ol> | ||
<li> | ||
<button onclick=" | ||
const expectedAddress = { | ||
country: 'AU', | ||
regionCode: 'QLD', | ||
addressLine: '55 test st', | ||
city: 'Chapel Hill', | ||
dependentLocality: '', | ||
postalCode: '6095', | ||
region: 'QLD', | ||
sortingCode: '', | ||
organization: 'w3c', | ||
recipient: 'web platform test', | ||
phone: '+61733780000', | ||
}; | ||
runManualTest(this, expectedAddress);"> | ||
If the requestShipping member is true, then shippingAddress's ContactAddress must match the expected values. | ||
</button> | ||
Please use: | ||
<dl> | ||
<dt>Recipient:</dt> | ||
<dd>web platform test</dd> | ||
<dt>Address line:</dt> | ||
<dd>55 test st</dd> | ||
<dt>Country</dt> | ||
<dd>Australia</dd> | ||
<dt>City</dt> | ||
<dd>Chapel Hill</dd> | ||
<dd>State/Region</dd> | ||
<dd>Queensland</dd> | ||
<dt>postal code </dt> | ||
<dd>6095</dd> | ||
<dt>organization</dt> | ||
<dd>w3c</dd> | ||
<dt>Phone number</dt> | ||
<dd>+61 7 3378 0000</dd> | ||
</dl> | ||
</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> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
<!doctype html> | ||
<meta charset="utf8"> | ||
<link rel="help" href="https://www.w3.org/TR/payment-request/#updatewith()-method"> | ||
<link rel="help" href="https://github.com/w3c/payment-request/pull/591"> | ||
<title> | ||
PaymentRequestUpdateEvent.updateWith() needs to be called immediately | ||
</title> | ||
<script src="/resources/testharness.js"></script> | ||
<script src="/resources/testharnessreport.js"></script> | ||
<script> | ||
setup({ explicit_done: true, explicit_timeout: true }); | ||
const applePay = Object.freeze({ | ||
rsolomakhin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
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" }); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure if it makes a difference, but Chrome has deprecated "basic-card". We only support payment handlers now, such as "https://google.com/pay". We also deprecated manual install of payment handlers. Only just-in-time install is supported. What that means for our tests is that we setup a JIT-installable payment handler at some local URL and then point our tests to it as the I think it's OK to re-land these tests as-is, but let's keep in mind that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's add https://google.com/pay ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, let's add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that would be great! |
||
const validMethods = Object.freeze([validMethod, applePay]); | ||
const validAmount = Object.freeze({ currency: "USD", value: "5.00" }); | ||
const validTotal = Object.freeze({ | ||
label: "label", | ||
amount: validAmount, | ||
}); | ||
const validShippingOptionA = Object.freeze({ | ||
id: "a-shipping-option", | ||
label: "A shipping option", | ||
amount: validAmount, | ||
selected: true, | ||
}); | ||
const validShippingOptionB = Object.freeze({ | ||
id: "b-shipping-option", | ||
label: "B shipping option", | ||
amount: validAmount, | ||
}); | ||
const validDetails = Object.freeze({ | ||
total: validTotal, | ||
shippingOptions: [validShippingOptionA, validShippingOptionB], | ||
}); | ||
const validOptions = Object.freeze({ | ||
requestShipping: true, | ||
}); | ||
|
||
function testImmediateUpdate({ textContent: testName }) { | ||
promise_test(async t => { | ||
const request = new PaymentRequest( | ||
validMethods, | ||
validDetails, | ||
validOptions | ||
); | ||
const eventPromise = new Promise((resolve, reject) => { | ||
request.addEventListener( | ||
"shippingaddresschange", | ||
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(validDetails); | ||
resolve(); // This is bad. | ||
} catch (err) { | ||
reject(err); // this is good. | ||
} | ||
}); | ||
}, | ||
{ once: true } | ||
); | ||
}); | ||
const acceptPromise = request.show(); | ||
await promise_rejects_dom( | ||
t, | ||
"InvalidStateError", | ||
eventPromise, | ||
"The event loop already spun, so [[waitForUpdate]] is now true" | ||
); | ||
const response = await acceptPromise; | ||
await response.complete(); | ||
}, testName.trim()); | ||
} | ||
|
||
function testSubsequentUpdateWithCalls({ textContent: testName }) { | ||
promise_test(async t => { | ||
const request = new PaymentRequest( | ||
validMethods, | ||
validDetails, | ||
validOptions | ||
); | ||
const eventPromise = new Promise((resolve, reject) => { | ||
request.addEventListener("shippingaddresschange", async ev => { | ||
const p = Promise.resolve(validDetails); | ||
ev.updateWith(p); | ||
await p; | ||
try { | ||
ev.updateWith(validDetails); | ||
resolve(); // this is bad, we should never get to here. | ||
} catch (err) { | ||
reject(err); // this is good! | ||
} | ||
}); | ||
}); | ||
const responsePromise = request.show(); | ||
await promise_rejects_dom( | ||
t, | ||
"InvalidStateError", | ||
eventPromise, | ||
"Expected eventPromise to have rejected, because updateWith() was a called twice" | ||
); | ||
const response = await responsePromise; | ||
await response.complete(); | ||
}, testName.trim()); | ||
} | ||
|
||
function testRecycleEvents({ textContent: testName }) { | ||
promise_test(async t => { | ||
const request = new PaymentRequest( | ||
validMethods, | ||
validDetails, | ||
validOptions | ||
); | ||
|
||
// Register both listeners. | ||
const addressChangedPromise = new Promise(resolve => { | ||
request.addEventListener("shippingaddresschange", resolve, { | ||
once: true, | ||
}); | ||
}); | ||
|
||
const optionChangedPromise = new Promise(resolve => { | ||
request.addEventListener("shippingoptionchange", resolve, { | ||
once: true, | ||
}); | ||
}); | ||
|
||
const responsePromise = request.show(); | ||
|
||
// Let's wait for the address to change. | ||
const addressChangeEvent = await addressChangedPromise; | ||
|
||
// Sets [[waitingForUpdate]] to true. | ||
addressChangeEvent.updateWith(validDetails); | ||
|
||
// Let's wait for the shippingOption. | ||
const optionChangeEvent = await optionChangedPromise; | ||
|
||
// Here, we try to be sneaky, and reuse the addressChangeEvent to perform the update. | ||
// However, addressChangeEvent [[waitingForUpdate]] is true, so it throws. | ||
assert_throws_dom( | ||
"InvalidStateError", | ||
() => { | ||
addressChangeEvent.updateWith(validDetails); | ||
}, | ||
"addressChangeEvent [[waitingForUpdate]] is true, so it must throw" | ||
); | ||
|
||
// But optionChangeEvent is still usable tho, so... | ||
optionChangeEvent.updateWith(validDetails); | ||
|
||
assert_throws_dom( | ||
"InvalidStateError", | ||
() => { | ||
optionChangeEvent.updateWith(validDetails); | ||
}, | ||
"optionChangeEvent [[waitingForUpdate]] is true, so it must throw" | ||
); | ||
|
||
const response = await responsePromise; | ||
await response.complete(); | ||
}, testName.trim()); | ||
} | ||
</script> | ||
<h2>updateWith() method</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 the payment sheet is shown, select a different shipping address once. Then pay. | ||
</p> | ||
<ol> | ||
<li id="test-0"> | ||
<button onclick="testImmediateUpdate(this);"> | ||
updateWith() must be called immediately, otherwise must throw an InvalidStateError. | ||
</button> | ||
</li> | ||
<li id="test-1"> | ||
<button onclick="testSubsequentUpdateWithCalls(this);"> | ||
Once the event has performed an update, subsequent calls to updateWith() must throw InvalidStateError. | ||
</button> | ||
</li> | ||
<li id="test-2"> | ||
<button onclick="testRecycleEvents(this);"> | ||
Recycling events must not be possible. | ||
</button> When the payment sheet is shown, select a different shipping address once, then change shipping option once. Then pay. | ||
</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> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this directory be renamed to ContactAddress?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch!