diff options
Diffstat (limited to 'browser/components/payments/test/mochitest/test_address_picker.html')
-rw-r--r-- | browser/components/payments/test/mochitest/test_address_picker.html | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/browser/components/payments/test/mochitest/test_address_picker.html b/browser/components/payments/test/mochitest/test_address_picker.html new file mode 100644 index 0000000000..5a3f1b398a --- /dev/null +++ b/browser/components/payments/test/mochitest/test_address_picker.html @@ -0,0 +1,278 @@ +<!DOCTYPE HTML> +<html> +<!-- +Test the address-picker component +--> +<head> + <meta charset="utf-8"> + <title>Test the address-picker component</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="/tests/SimpleTest/EventUtils.js"></script> + <script src="payments_common.js"></script> + <script src="../../res/unprivileged-fallbacks.js"></script> + <script src="autofillEditForms.js"></script> + + <link rel="stylesheet" type="text/css" href="../../res/containers/rich-picker.css"/> + <link rel="stylesheet" type="text/css" href="../../res/components/rich-select.css"/> + <link rel="stylesheet" type="text/css" href="../../res/components/address-option.css"/> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> + <p id="display"> + <address-picker id="picker1" + data-field-separator=", " + data-invalid-label="Picker1: Missing or Invalid" + selected-state-key="selectedShippingAddress"></address-picker> + </p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +<script type="module"> +/** Test the address-picker component **/ + +import "../../res/containers/address-picker.js"; + +let picker1 = document.getElementById("picker1"); + +add_task(async function test_empty() { + ok(picker1, "Check picker1 exists"); + let {savedAddresses} = picker1.requestStore.getState(); + is(Object.keys(savedAddresses).length, 0, "Check empty initial state"); + is(picker1.editLink.hidden, true, "Check that picker edit link is hidden"); + is(picker1.dropdown.popupBox.children.length, 0, "Check dropdown is empty"); +}); + +add_task(async function test_initialSet() { + picker1.requestStore.setState({ + savedAddresses: { + "48bnds6854t": { + "address-level1": "MI", + "address-level2": "Some City", + "country": "US", + "guid": "48bnds6854t", + "name": "Mr. Foo", + "postal-code": "90210", + "street-address": "123 Sesame Street,\nApt 40", + "tel": "+1 519 555-5555", + timeLastUsed: 200, + }, + "68gjdh354j": { + "address-level1": "CA", + "address-level2": "Mountain View", + "country": "US", + "guid": "68gjdh354j", + "name": "Mrs. Bar", + "postal-code": "94041", + "street-address": "P.O. Box 123", + "tel": "+1 650 555-5555", + timeLastUsed: 300, + }, + "abcde12345": { + "address-level2": "Mountain View", + "country": "US", + "guid": "abcde12345", + "name": "Mrs. Fields", + timeLastUsed: 100, + }, + }, + }); + await asyncElementRendered(); + let options = picker1.dropdown.popupBox.children; + is(options.length, 3, "Check dropdown has all addresses"); + ok(options[0].textContent.includes("Mrs. Bar"), "Check first address based on timeLastUsed"); + ok(options[1].textContent.includes("Mr. Foo"), "Check second address based on timeLastUsed"); + ok(options[2].textContent.includes("Mrs. Fields"), "Check third address based on timeLastUsed"); +}); + +add_task(async function test_update() { + picker1.requestStore.setState({ + savedAddresses: { + "48bnds6854t": { + // Same GUID, different values to trigger an update + "address-level1": "MI-edit", + // address-level2 was cleared which means it's not returned + "country": "CA", + "guid": "48bnds6854t", + "name": "Mr. Foo-edit", + "postal-code": "90210-1234", + "street-address": "new-edit", + "tel": "+1 650 555-5555", + }, + "68gjdh354j": { + "address-level1": "CA", + "address-level2": "Mountain View", + "country": "US", + "guid": "68gjdh354j", + "name": "Mrs. Bar", + "postal-code": "94041", + "street-address": "P.O. Box 123", + "tel": "+1 650 555-5555", + }, + "abcde12345": { + "address-level2": "Mountain View", + "country": "US", + "guid": "abcde12345", + "name": "Mrs. Fields", + }, + }, + }); + await asyncElementRendered(); + let options = picker1.dropdown.popupBox.children; + is(options.length, 3, "Check dropdown still has all addresses"); + ok(options[0].textContent.includes("Mr. Foo-edit"), "Check updated name in first address"); + ok(!options[0].getAttribute("address-level2"), "Check removed first address-level2"); + ok(options[1].textContent.includes("Mrs. Bar"), "Check that name is the same in second address"); + ok(options[1].getAttribute("street-address").includes("P.O. Box 123"), + "Check second address is the same"); + ok(options[2].textContent.includes("Mrs. Fields"), + "Check that name is the same in third address"); + is(options[2].getAttribute("street-address"), null, "Check third address is missing"); +}); + +add_task(async function test_change_selected_address() { + let options = picker1.dropdown.popupBox.children; + is(picker1.dropdown.selectedOption, null, "Should default to no selected option"); + is(picker1.editLink.hidden, true, "Picker edit link should be hidden when no option is selected"); + let {selectedShippingAddress} = picker1.requestStore.getState(); + is(selectedShippingAddress, null, "store should have no option selected"); + ok(!picker1.classList.contains("invalid-selected-option"), "No validation on an empty selection"); + ok(isHidden(picker1.invalidLabel), "The invalid label should be hidden"); + + picker1.dropdown.popupBox.focus(); + synthesizeKey(options[2].getAttribute("name"), {}); + await asyncElementRendered(); + + let selectedOption = picker1.dropdown.selectedOption; + is(selectedOption, options[2], "Selected option should now be the third option"); + selectedShippingAddress = picker1.requestStore.getState().selectedShippingAddress; + is(selectedShippingAddress, selectedOption.getAttribute("guid"), + "store should have third option selected"); + // The third option is missing some fields. Make sure that it is marked as such. + ok(picker1.classList.contains("invalid-selected-option"), "The third option is missing fields"); + ok(!isHidden(picker1.invalidLabel), "The invalid label should be visible"); + is(picker1.invalidLabel.innerText, picker1.dataset.invalidLabel, "Check displayed error text"); + + picker1.dropdown.popupBox.focus(); + synthesizeKey(options[1].getAttribute("name"), {}); + await asyncElementRendered(); + + selectedOption = picker1.dropdown.selectedOption; + is(selectedOption, options[1], "Selected option should now be the second option"); + selectedShippingAddress = picker1.requestStore.getState().selectedShippingAddress; + is(selectedShippingAddress, selectedOption.getAttribute("guid"), + "store should have second option selected"); + ok(!picker1.classList.contains("invalid-selected-option"), "The second option has all fields"); + ok(isHidden(picker1.invalidLabel), "The invalid label should be hidden"); +}); + +add_task(async function test_address_combines_name_street_level2_level1_postalCode_country() { + let options = picker1.dropdown.popupBox.children; + let richoption1 = picker1.dropdown.querySelector(".rich-select-selected-option"); + /* eslint-disable max-len */ + is(richoption1.innerText, + `${options[1].getAttribute("name")}, ${options[1].getAttribute("street-address")} +${options[1].getAttribute("address-level2")}, ${options[1].getAttribute("address-level1")}, ${options[1].getAttribute("postal-code")}, ${options[1].getAttribute("country")}`, + "The address shown should be human readable and include all fields"); + /* eslint-enable max-len */ + + picker1.dropdown.popupBox.focus(); + synthesizeKey(options[2].getAttribute("name"), {}); + await asyncElementRendered(); + + richoption1 = picker1.dropdown.querySelector(".rich-select-selected-option"); + // "Missing …" text is rendered via a pseudo element content and isn't included in innerText + is(richoption1.innerText, "Mrs. Fields, \nMountain View, , US", + "The address shown should be human readable and include all fields"); + + picker1.dropdown.popupBox.focus(); + synthesizeKey(options[1].getAttribute("name"), {}); + await asyncElementRendered(); +}); + +add_task(async function test_delete() { + picker1.requestStore.setState({ + savedAddresses: { + // 48bnds6854t and abcde12345 was deleted + "68gjdh354j": { + "address-level1": "CA", + "address-level2": "Mountain View", + "country": "US", + "guid": "68gjdh354j", + "name": "Mrs. Bar", + "postal-code": "94041", + "street-address": "P.O. Box 123", + "tel": "+1 650 555-5555", + }, + }, + }); + await asyncElementRendered(); + let options = picker1.dropdown.popupBox.children; + is(options.length, 1, "Check dropdown has one remaining address"); + ok(options[0].textContent.includes("Mrs. Bar"), "Check remaining address"); +}); + +add_task(async function test_merchantError() { + picker1.requestStore.setState({ + selectedShippingAddress: "68gjdh354j", + }); + await asyncElementRendered(); + + is(picker1.selectedStateKey, "selectedShippingAddress", "Check selectedStateKey"); + + let state = picker1.requestStore.getState(); + let { + request, + } = state; + ok(!picker1.classList.contains("invalid-selected-option"), "No validation on a valid option"); + ok(isHidden(picker1.invalidLabel), "The invalid label should be hidden"); + + let requestWithShippingAddressErrors = deepClone(request); + Object.assign(requestWithShippingAddressErrors.paymentDetails, { + shippingAddressErrors: { + country: "Your country is not supported", + }, + }); + picker1.requestStore.setState({ + request: requestWithShippingAddressErrors, + }); + await asyncElementRendered(); + + ok(picker1.classList.contains("invalid-selected-option"), "The merchant error applies"); + ok(!isHidden(picker1.invalidLabel), "The merchant error should be visible"); + is(picker1.invalidLabel.innerText, "Your country is not supported", "Check displayed error text"); + + info("update the request to remove the errors"); + picker1.requestStore.setState({ + request, + }); + await asyncElementRendered(); + ok(!picker1.classList.contains("invalid-selected-option"), + "No errors visible when merchant errors cleared"); + ok(isHidden(picker1.invalidLabel), "The invalid label should be hidden"); + + info("Set billing address and payer errors which aren't relevant to this picker"); + let requestWithNonShippingAddressErrors = deepClone(request); + Object.assign(requestWithNonShippingAddressErrors.paymentDetails, { + payerErrors: { + name: "Your name is too short", + }, + paymentMethodErrors: { + billingAddress: { + country: "Your billing country is not supported", + }, + }, + shippingAddressErrors: {}, + }); + picker1.requestStore.setState({ + request: requestWithNonShippingAddressErrors, + }); + await asyncElementRendered(); + ok(!picker1.classList.contains("invalid-selected-option"), "No errors on a shipping picker"); + ok(isHidden(picker1.invalidLabel), "The invalid label should still be hidden"); +}); +</script> + +</body> +</html> |