-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
3602a64
commit cd418e2
Showing
33 changed files
with
4,154 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
109 changes: 109 additions & 0 deletions
109
payment-request/PaymentAddress/attributes-and-toJSON-method-manual.https.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> |
206 changes: 206 additions & 0 deletions
206
payment-request/PaymentRequestUpdateEvent/updateWith-call-immediate-manual.https.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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({ | ||
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: "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> |
Oops, something went wrong.