зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1446203 - Basic Payment Request Shipping Address Add/Edit page. r=MattN
MozReview-Commit-ID: 9f0vPciw65V --HG-- rename : toolkit/components/payments/res/containers/basic-card-form.js => toolkit/components/payments/res/containers/address-form.js rename : toolkit/components/payments/test/browser/browser_card_edit.js => toolkit/components/payments/test/browser/browser_address_edit.js rename : toolkit/components/payments/test/mochitest/test_basic_card_form.html => toolkit/components/payments/test/mochitest/test_address_form.html extra : rebase_source : 0660f24a96f99f6b702f726d093ae6fb67c1ced2
This commit is contained in:
Родитель
b1959f906c
Коммит
b9d7c2eba2
|
@ -1672,7 +1672,7 @@ pref("extensions.formautofill.loglevel", "Warn");
|
|||
#ifdef NIGHTLY_BUILD
|
||||
// Comma separated list of countries Form Autofill supports.
|
||||
// This affects feature availability and the address edit form country picker.
|
||||
pref("extensions.formautofill.supportedCountries", "US,CA,DE");
|
||||
pref("extensions.formautofill.supportedCountries", "US,CA");
|
||||
pref("extensions.formautofill.supportRTL", true);
|
||||
#else
|
||||
pref("extensions.formautofill.supportedCountries", "US");
|
||||
|
|
|
@ -145,6 +145,8 @@ update.locale
|
|||
browser/chrome/browser/content/branding/icon128.png
|
||||
browser/chrome/devtools/content/framework/dev-edition-promo/dev-edition-logo.png
|
||||
# Bug 1451016 - Nightly-only PaymentRequest & Form Autofill code sharing.
|
||||
browser/features/formautofill@mozilla.org/chrome/content/editAddress.xhtml
|
||||
chrome/toolkit/res/payments/formautofill/editAddress.xhtml
|
||||
browser/features/formautofill@mozilla.org/chrome/content/editCreditCard.xhtml
|
||||
chrome/toolkit/res/payments/formautofill/editCreditCard.xhtml
|
||||
browser/features/formautofill@mozilla.org/chrome/content/autofillEditForms.js
|
||||
|
|
|
@ -65,7 +65,11 @@ let PaymentFrameScript = {
|
|||
* Expose privileged utility functions to the unprivileged page.
|
||||
*/
|
||||
exposeUtilityFunctions() {
|
||||
let waivedContent = Cu.waiveXrays(content);
|
||||
let PaymentDialogUtils = {
|
||||
DEFAULT_REGION: FormAutofillUtils.DEFAULT_REGION,
|
||||
supportedCountries: FormAutofillUtils.supportedCountries,
|
||||
|
||||
getAddressLabel(address) {
|
||||
return FormAutofillUtils.getAddressLabel(address);
|
||||
},
|
||||
|
@ -73,8 +77,12 @@ let PaymentFrameScript = {
|
|||
isCCNumber(value) {
|
||||
return FormAutofillUtils.isCCNumber(value);
|
||||
},
|
||||
|
||||
getFormFormat(country) {
|
||||
let format = FormAutofillUtils.getFormFormat(country);
|
||||
return Cu.cloneInto(format, waivedContent);
|
||||
},
|
||||
};
|
||||
let waivedContent = Cu.waiveXrays(content);
|
||||
waivedContent.PaymentDialogUtils = Cu.cloneInto(PaymentDialogUtils, waivedContent, {
|
||||
cloneFunctions: true,
|
||||
});
|
||||
|
|
|
@ -19,6 +19,7 @@ toolkit.jar:
|
|||
res/payments/debugging.html (res/debugging.html)
|
||||
res/payments/debugging.js (res/debugging.js)
|
||||
res/payments/formautofill/autofillEditForms.js (../../../browser/extensions/formautofill/content/autofillEditForms.js)
|
||||
res/payments/formautofill/editAddress.xhtml (../../../browser/extensions/formautofill/content/editAddress.xhtml)
|
||||
res/payments/formautofill/editCreditCard.xhtml (../../../browser/extensions/formautofill/content/editCreditCard.xhtml)
|
||||
res/payments/unprivileged-fallbacks.js (res/unprivileged-fallbacks.js)
|
||||
res/payments/mixins/ (res/mixins/*.js)
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* import-globals-from ../../../../../browser/extensions/formautofill/content/autofillEditForms.js*/
|
||||
import PaymentStateSubscriberMixin from "../mixins/PaymentStateSubscriberMixin.js";
|
||||
import paymentRequest from "../paymentRequest.js";
|
||||
/* import-globals-from ../unprivileged-fallbacks.js */
|
||||
|
||||
/**
|
||||
* <address-form></address-form>
|
||||
*
|
||||
* XXX: Bug 1446164 - This form isn't localized when used via this custom element
|
||||
* as it will be much easier to share the logic once we switch to Fluent.
|
||||
*/
|
||||
|
||||
export default class AddressForm extends PaymentStateSubscriberMixin(HTMLElement) {
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.genericErrorText = document.createElement("div");
|
||||
|
||||
this.backButton = document.createElement("button");
|
||||
this.backButton.addEventListener("click", this);
|
||||
|
||||
this.saveButton = document.createElement("button");
|
||||
this.saveButton.addEventListener("click", this);
|
||||
|
||||
// The markup is shared with form autofill preferences.
|
||||
let url = "formautofill/editAddress.xhtml";
|
||||
this.promiseReady = this._fetchMarkup(url).then(doc => {
|
||||
this.form = doc.getElementById("form");
|
||||
return this.form;
|
||||
});
|
||||
}
|
||||
|
||||
_fetchMarkup(url) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.responseType = "document";
|
||||
xhr.addEventListener("error", reject);
|
||||
xhr.addEventListener("load", evt => {
|
||||
resolve(xhr.response);
|
||||
});
|
||||
xhr.open("GET", url);
|
||||
xhr.send();
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.promiseReady.then(form => {
|
||||
this.appendChild(form);
|
||||
|
||||
let record = {};
|
||||
this.formHandler = new EditAddress({
|
||||
form,
|
||||
}, record, {
|
||||
DEFAULT_REGION: PaymentDialogUtils.DEFAULT_REGION,
|
||||
getFormFormat: PaymentDialogUtils.getFormFormat,
|
||||
supportedCountries: PaymentDialogUtils.supportedCountries,
|
||||
});
|
||||
|
||||
this.appendChild(this.genericErrorText);
|
||||
this.appendChild(this.backButton);
|
||||
this.appendChild(this.saveButton);
|
||||
// Only call the connected super callback(s) once our markup is fully
|
||||
// connected, including the shared form fetched asynchronously.
|
||||
super.connectedCallback();
|
||||
});
|
||||
}
|
||||
|
||||
render(state) {
|
||||
this.backButton.textContent = this.dataset.backButtonLabel;
|
||||
this.saveButton.textContent = this.dataset.saveButtonLabel;
|
||||
|
||||
let record = {};
|
||||
let {
|
||||
page,
|
||||
savedAddresses,
|
||||
} = state;
|
||||
|
||||
this.genericErrorText.textContent = page.error;
|
||||
|
||||
let editing = !!page.guid;
|
||||
|
||||
// If an address is selected we want to edit it.
|
||||
if (editing) {
|
||||
record = savedAddresses[page.guid];
|
||||
if (!record) {
|
||||
throw new Error("Trying to edit a non-existing address: " + page.guid);
|
||||
}
|
||||
}
|
||||
|
||||
this.formHandler.loadRecord(record);
|
||||
}
|
||||
|
||||
handleEvent(event) {
|
||||
switch (event.type) {
|
||||
case "click": {
|
||||
this.onClick(event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClick(evt) {
|
||||
switch (evt.target) {
|
||||
case this.backButton: {
|
||||
this.requestStore.setState({
|
||||
page: {
|
||||
id: "payment-summary",
|
||||
},
|
||||
});
|
||||
break;
|
||||
}
|
||||
case this.saveButton: {
|
||||
this.saveRecord();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error("Unexpected click target");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
saveRecord() {
|
||||
let record = this.formHandler.buildFormObject();
|
||||
let {
|
||||
page,
|
||||
selectedStateKey,
|
||||
} = this.requestStore.getState();
|
||||
|
||||
paymentRequest.updateAutofillRecord("addresses", record, page.guid, {
|
||||
errorStateChange: {
|
||||
page: {
|
||||
id: "address-page",
|
||||
error: this.dataset.errorGenericSave,
|
||||
},
|
||||
},
|
||||
preserveOldProperties: true,
|
||||
selectedStateKey,
|
||||
successStateChange: {
|
||||
page: {
|
||||
id: "payment-summary",
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("address-form", AddressForm);
|
|
@ -8,7 +8,7 @@ import RichSelect from "../components/rich-select.js";
|
|||
|
||||
/**
|
||||
* <address-picker></address-picker>
|
||||
* Container around <rich-select> (eventually providing add/edit links) with
|
||||
* Container around add/edit links and <rich-select> with
|
||||
* <address-option> listening to savedAddresses.
|
||||
*/
|
||||
|
||||
|
@ -21,10 +21,21 @@ export default class AddressPicker extends PaymentStateSubscriberMixin(HTMLEleme
|
|||
super();
|
||||
this.dropdown = new RichSelect();
|
||||
this.dropdown.addEventListener("change", this);
|
||||
this.addLink = document.createElement("a");
|
||||
this.addLink.href = "javascript:void(0)";
|
||||
this.addLink.textContent = this.dataset.addLinkLabel;
|
||||
this.addLink.addEventListener("click", this);
|
||||
this.editLink = document.createElement("a");
|
||||
this.editLink.href = "javascript:void(0)";
|
||||
this.editLink.textContent = this.dataset.editLinkLabel;
|
||||
this.editLink.addEventListener("click", this);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
this.appendChild(this.dropdown);
|
||||
this.appendChild(this.addLink);
|
||||
this.append(" ");
|
||||
this.appendChild(this.editLink);
|
||||
super.connectedCallback();
|
||||
}
|
||||
|
||||
|
@ -134,6 +145,9 @@ export default class AddressPicker extends PaymentStateSubscriberMixin(HTMLEleme
|
|||
this.onChange(event);
|
||||
break;
|
||||
}
|
||||
case "click": {
|
||||
this.onClick(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,6 +160,33 @@ export default class AddressPicker extends PaymentStateSubscriberMixin(HTMLEleme
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
onClick({target}) {
|
||||
let nextState = {
|
||||
page: {
|
||||
id: "address-page",
|
||||
selectedStateKey: this.selectedStateKey,
|
||||
},
|
||||
};
|
||||
|
||||
switch (target) {
|
||||
case this.addLink: {
|
||||
nextState.page.guid = null;
|
||||
break;
|
||||
}
|
||||
case this.editLink: {
|
||||
let state = this.requestStore.getState();
|
||||
let selectedAddressGUID = state[this.selectedStateKey];
|
||||
nextState.page.guid = selectedAddressGUID;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
throw new Error("Unexpected onClick");
|
||||
}
|
||||
}
|
||||
|
||||
this.requestStore.setState(nextState);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("address-picker", AddressPicker);
|
||||
|
|
|
@ -9,6 +9,7 @@ import paymentRequest from "../paymentRequest.js";
|
|||
|
||||
import "../components/currency-amount.js";
|
||||
import "./address-picker.js";
|
||||
import "./address-form.js";
|
||||
import "./basic-card-form.js";
|
||||
import "./order-details.js";
|
||||
import "./payment-method-picker.js";
|
||||
|
|
|
@ -13,8 +13,12 @@
|
|||
<!ENTITY pickupAddressLabel "Pickup Address">
|
||||
<!ENTITY shippingOptionsLabel "Shipping Options">
|
||||
<!ENTITY paymentMethodsLabel "Payment Method">
|
||||
<!ENTITY address.addLink.label "Add">
|
||||
<!ENTITY address.editLink.label "Edit">
|
||||
<!ENTITY basicCard.addLink.label "Add">
|
||||
<!ENTITY basicCard.editLink.label "Edit">
|
||||
<!ENTITY payer.addLink.label "Add">
|
||||
<!ENTITY payer.editLink.label "Edit">
|
||||
<!ENTITY payerLabel "Contact Information">
|
||||
<!ENTITY cancelPaymentButton.label "Cancel">
|
||||
<!ENTITY approvePaymentButton.label "Pay">
|
||||
|
@ -28,6 +32,9 @@
|
|||
<!ENTITY basicCardPage.backButton.label "Back">
|
||||
<!ENTITY basicCardPage.saveButton.label "Save">
|
||||
<!ENTITY basicCardPage.persistCheckbox.label "Save credit card to Firefox (Security code will not be saved)">
|
||||
<!ENTITY addressPage.error.genericSave "There was an error saving the address.">
|
||||
<!ENTITY addressPage.backButton.label "Back">
|
||||
<!ENTITY addressPage.saveButton.label "Save">
|
||||
]>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
|
@ -75,7 +82,10 @@
|
|||
data-shipping-address-label="&shippingAddressLabel;"
|
||||
data-delivery-address-label="&deliveryAddressLabel;"
|
||||
data-pickup-address-label="&pickupAddressLabel;"><label></label></div>
|
||||
<address-picker class="shipping-related" selected-state-key="selectedShippingAddress"></address-picker>
|
||||
<address-picker class="shipping-related"
|
||||
data-add-link-label="&address.addLink.label;"
|
||||
data-edit-link-label="&address.editLink.label;"
|
||||
selected-state-key="selectedShippingAddress"></address-picker>
|
||||
|
||||
<div class="shipping-related"><label>&shippingOptionsLabel;</label></div>
|
||||
<shipping-option-picker class="shipping-related"></shipping-option-picker>
|
||||
|
@ -88,6 +98,8 @@
|
|||
|
||||
<div class="payer-related"><label>&payerLabel;</label></div>
|
||||
<address-picker class="payer-related"
|
||||
data-add-link-label="&payer.addLink.label;"
|
||||
data-edit-link-label="&payer.editLink.label;"
|
||||
selected-state-key="selectedPayerAddress"></address-picker>
|
||||
<div id="error-text"></div>
|
||||
</section>
|
||||
|
@ -114,6 +126,13 @@
|
|||
data-save-button-label="&basicCardPage.saveButton.label;"
|
||||
data-persist-checkbox-label="&basicCardPage.persistCheckbox.label;"
|
||||
hidden="hidden"></basic-card-form>
|
||||
|
||||
<address-form id="address-page"
|
||||
class="page"
|
||||
data-error-generic-save="&addressPage.error.genericSave;"
|
||||
data-back-button-label="&addressPage.backButton.label;"
|
||||
data-save-button-label="&addressPage.saveButton.label;"
|
||||
hidden="hidden"></address-form>
|
||||
</div>
|
||||
|
||||
<div id="disabled-overlay" hidden="hidden">
|
||||
|
|
|
@ -28,4 +28,20 @@ var PaymentDialogUtils = {
|
|||
isCCNumber(str) {
|
||||
return str.length > 0;
|
||||
},
|
||||
DEFAULT_REGION: "US",
|
||||
supportedCountries: ["US", "CA"],
|
||||
getFormFormat(country) {
|
||||
return {
|
||||
"addressLevel1Label": country == "US" ? "state" : "province",
|
||||
"postalCodeLabel": country == "US" ? "zip" : "postalCode",
|
||||
"fieldsOrder": [
|
||||
{fieldId: "name", newLine: true},
|
||||
{fieldId: "organization", newLine: true},
|
||||
{fieldId: "street-address", newLine: true},
|
||||
{fieldId: "address-level2"},
|
||||
{fieldId: "address-level1"},
|
||||
{fieldId: "postal-code"},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
|
|
@ -6,6 +6,7 @@ skip-if = !e10s # Bug 1365964 - Payment Request isn't implemented for non-e10s
|
|||
support-files =
|
||||
blank_page.html
|
||||
|
||||
[browser_address_edit.js]
|
||||
[browser_card_edit.js]
|
||||
[browser_change_shipping.js]
|
||||
[browser_host_name.js]
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
"use strict";
|
||||
|
||||
add_task(async function test_add_link() {
|
||||
await BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: BLANK_PAGE_URL,
|
||||
}, async browser => {
|
||||
let {win, frame} =
|
||||
await setupPaymentDialog(browser, {
|
||||
methodData: [PTU.MethodData.basicCard],
|
||||
details: PTU.Details.twoShippingOptions,
|
||||
options: PTU.Options.requestShippingOption,
|
||||
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
|
||||
}
|
||||
);
|
||||
|
||||
let shippingAddressChangePromise = ContentTask.spawn(browser, {
|
||||
eventName: "shippingaddresschange",
|
||||
}, PTU.ContentTasks.awaitPaymentRequestEventPromise);
|
||||
|
||||
const EXPECTED_ADDRESS = {
|
||||
"given-name": "Jared",
|
||||
"family-name": "Wein",
|
||||
"organization": "Mozilla",
|
||||
"street-address": "404 Internet Lane",
|
||||
"address-level2": "Firefoxity City",
|
||||
"address-level1": "CA",
|
||||
"postal-code": "31337",
|
||||
"country": "US",
|
||||
"tel": "+15555551212",
|
||||
"email": "test@example.com",
|
||||
};
|
||||
|
||||
await spawnPaymentDialogTask(frame, async (address) => {
|
||||
let {
|
||||
PaymentTestUtils: PTU,
|
||||
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
|
||||
|
||||
let addLink = content.document.querySelector("address-picker a");
|
||||
is(addLink.textContent, "Add", "Add link text");
|
||||
|
||||
addLink.click();
|
||||
|
||||
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return state.page.id == "address-page" && !state.page.guid;
|
||||
}, "Check add page state");
|
||||
|
||||
info("filling fields");
|
||||
for (let [key, val] of Object.entries(address)) {
|
||||
let field = content.document.getElementById(key);
|
||||
if (!field) {
|
||||
ok(false, `${key} field not found`);
|
||||
}
|
||||
field.value = val;
|
||||
ok(!field.disabled, `Field #${key} shouldn't be disabled`);
|
||||
}
|
||||
|
||||
content.document.querySelector("address-form button:last-of-type").click();
|
||||
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return Object.keys(state.savedAddresses).length == 1;
|
||||
}, "Check address was added");
|
||||
|
||||
let addressGUIDs = Object.keys(state.savedAddresses);
|
||||
is(addressGUIDs.length, 1, "Check there is one address");
|
||||
let savedAddress = state.savedAddresses[addressGUIDs[0]];
|
||||
for (let [key, val] of Object.entries(address)) {
|
||||
is(savedAddress[key], val, "Check " + key);
|
||||
}
|
||||
|
||||
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return state.page.id == "payment-summary";
|
||||
}, "Switched back to payment-summary");
|
||||
}, EXPECTED_ADDRESS);
|
||||
|
||||
await shippingAddressChangePromise;
|
||||
info("got shippingaddresschange event");
|
||||
|
||||
info("clicking cancel");
|
||||
await spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
|
||||
|
||||
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
|
||||
});
|
||||
});
|
||||
|
||||
add_task(async function test_edit_link() {
|
||||
await BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: BLANK_PAGE_URL,
|
||||
}, async browser => {
|
||||
let {win, frame} =
|
||||
await setupPaymentDialog(browser, {
|
||||
methodData: [PTU.MethodData.basicCard],
|
||||
details: PTU.Details.twoShippingOptions,
|
||||
options: PTU.Options.requestShippingOption,
|
||||
merchantTaskFn: PTU.ContentTasks.createAndShowRequest,
|
||||
}
|
||||
);
|
||||
|
||||
let shippingAddressChangePromise = ContentTask.spawn(browser, {
|
||||
eventName: "shippingaddresschange",
|
||||
}, PTU.ContentTasks.awaitPaymentRequestEventPromise);
|
||||
|
||||
const EXPECTED_ADDRESS = {
|
||||
"given-name": "Jaws",
|
||||
"family-name": "swaJ",
|
||||
"organization": "aliizoM",
|
||||
};
|
||||
|
||||
await spawnPaymentDialogTask(frame, async (address) => {
|
||||
let {
|
||||
PaymentTestUtils: PTU,
|
||||
} = ChromeUtils.import("resource://testing-common/PaymentTestUtils.jsm", {});
|
||||
|
||||
let editLink = content.document.querySelector("address-picker a:nth-of-type(2)");
|
||||
is(editLink.textContent, "Edit", "Edit link text");
|
||||
|
||||
editLink.click();
|
||||
|
||||
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return state.page.id == "address-page" && !!state.page.guid;
|
||||
}, "Check edit page state");
|
||||
|
||||
info("overwriting field values");
|
||||
for (let [key, val] of Object.entries(address)) {
|
||||
let field = content.document.getElementById(key);
|
||||
field.value = val;
|
||||
ok(!field.disabled, `Field #${key} shouldn't be disabled`);
|
||||
}
|
||||
|
||||
content.document.querySelector("address-form button:last-of-type").click();
|
||||
|
||||
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return Object.keys(state.savedAddresses).length == 1;
|
||||
}, "Check address was edited");
|
||||
|
||||
let addressGUIDs = Object.keys(state.savedAddresses);
|
||||
is(addressGUIDs.length, 1, "Check there is still one address");
|
||||
let savedAddress = state.savedAddresses[addressGUIDs[0]];
|
||||
for (let [key, val] of Object.entries(address)) {
|
||||
is(savedAddress[key], val, "Check updated " + key);
|
||||
}
|
||||
|
||||
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return state.page.id == "payment-summary";
|
||||
}, "Switched back to payment-summary");
|
||||
}, EXPECTED_ADDRESS);
|
||||
|
||||
await shippingAddressChangePromise;
|
||||
info("got shippingaddresschange event");
|
||||
|
||||
info("clicking cancel");
|
||||
await spawnPaymentDialogTask(frame, PTU.DialogContentTasks.manuallyClickCancel);
|
||||
|
||||
await BrowserTestUtils.waitForCondition(() => win.closed, "dialog should be closed");
|
||||
});
|
||||
await cleanupFormAutofillStorage();
|
||||
});
|
|
@ -17,8 +17,7 @@ add_task(async function test_add_link() {
|
|||
|
||||
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return state.page.id == "basic-card-page" && !state.page.guid;
|
||||
},
|
||||
"Check add page state");
|
||||
}, "Check add page state");
|
||||
|
||||
ok(!state.isPrivate,
|
||||
"isPrivate flag is not set when paymentrequest is shown from a non-private session");
|
||||
|
@ -44,8 +43,7 @@ add_task(async function test_add_link() {
|
|||
|
||||
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return Object.keys(state.savedBasicCards).length == 1;
|
||||
},
|
||||
"Check card was added");
|
||||
}, "Check card was added");
|
||||
|
||||
let cardGUIDs = Object.keys(state.savedBasicCards);
|
||||
is(cardGUIDs.length, 1, "Check there is one card");
|
||||
|
@ -57,8 +55,7 @@ add_task(async function test_add_link() {
|
|||
|
||||
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return state.page.id == "payment-summary";
|
||||
},
|
||||
"Switched back to payment-summary");
|
||||
}, "Switched back to payment-summary");
|
||||
}, args);
|
||||
});
|
||||
|
||||
|
@ -79,8 +76,7 @@ add_task(async function test_edit_link() {
|
|||
|
||||
let state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return state.page.id == "basic-card-page" && !!state.page.guid;
|
||||
},
|
||||
"Check edit page state");
|
||||
}, "Check edit page state");
|
||||
|
||||
let nextYear = (new Date()).getFullYear() + 1;
|
||||
let card = {
|
||||
|
@ -102,8 +98,7 @@ add_task(async function test_edit_link() {
|
|||
|
||||
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return Object.keys(state.savedBasicCards).length == 1;
|
||||
},
|
||||
"Check card was added");
|
||||
}, "Check card was added");
|
||||
|
||||
let cardGUIDs = Object.keys(state.savedBasicCards);
|
||||
is(cardGUIDs.length, 1, "Check there is still one card");
|
||||
|
@ -115,8 +110,7 @@ add_task(async function test_edit_link() {
|
|||
|
||||
state = await PTU.DialogContentUtils.waitForState(content, (state) => {
|
||||
return state.page.id == "payment-summary";
|
||||
},
|
||||
"Switched back to payment-summary");
|
||||
}, "Switched back to payment-summary");
|
||||
}, args);
|
||||
});
|
||||
|
||||
|
|
|
@ -4,5 +4,6 @@
|
|||
# to resemble the layout in the shipped JAR file.
|
||||
support-files =
|
||||
../../../../../../browser/extensions/formautofill/content/editCreditCard.xhtml
|
||||
../../../../../../browser/extensions/formautofill/content/editAddress.xhtml
|
||||
|
||||
[test_editCreditCard.html]
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
prefs =
|
||||
dom.webcomponents.customelements.enabled=false
|
||||
support-files =
|
||||
!/browser/extensions/formautofill/content/editAddress.xhtml
|
||||
!/browser/extensions/formautofill/content/editCreditCard.xhtml
|
||||
../../../../../browser/extensions/formautofill/content/autofillEditForms.js
|
||||
../../../../../testing/modules/sinon-2.3.2.js
|
||||
|
@ -9,6 +10,7 @@ support-files =
|
|||
payments_common.js
|
||||
skip-if = !e10s
|
||||
|
||||
[test_address_form.html]
|
||||
[test_address_picker.html]
|
||||
[test_basic_card_form.html]
|
||||
[test_currency_amount.html]
|
||||
|
|
|
@ -0,0 +1,229 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
Test the address-form element
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test the address-form element</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/AddTask.js"></script>
|
||||
<script src="sinon-2.3.2.js"></script>
|
||||
<script src="payments_common.js"></script>
|
||||
<script src="../../res/vendor/custom-elements.min.js"></script>
|
||||
<script src="../../res/unprivileged-fallbacks.js"></script>
|
||||
<script src="autofillEditForms.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<link rel="stylesheet" type="text/css" href="../../res/paymentRequest.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display">
|
||||
</p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
<script type="module">
|
||||
/** Test the address-form element **/
|
||||
|
||||
/* global sinon */
|
||||
/* import-globals-from payments_common.js */
|
||||
|
||||
import AddressForm from "../../res/containers/address-form.js";
|
||||
|
||||
let display = document.getElementById("display");
|
||||
|
||||
function checkAddressForm(customEl, expectedAddress) {
|
||||
const ADDRESS_PROPERTY_NAMES = [
|
||||
"given-name",
|
||||
"family-name",
|
||||
"organization",
|
||||
"street-address",
|
||||
"address-level2",
|
||||
"address-level1",
|
||||
"postal-code",
|
||||
"country",
|
||||
"email",
|
||||
"tel",
|
||||
];
|
||||
for (let propName of ADDRESS_PROPERTY_NAMES) {
|
||||
let expectedVal = expectedAddress[propName] || "";
|
||||
is(document.getElementById(propName).value,
|
||||
expectedVal.toString(),
|
||||
`Check ${propName}`);
|
||||
}
|
||||
}
|
||||
|
||||
add_task(async function test_initialState() {
|
||||
let form = new AddressForm();
|
||||
let {page} = form.requestStore.getState();
|
||||
is(page.id, "payment-summary", "Check initial page");
|
||||
await form.promiseReady;
|
||||
display.appendChild(form);
|
||||
await asyncElementRendered();
|
||||
is(page.id, "payment-summary", "Check initial page after appending");
|
||||
form.remove();
|
||||
});
|
||||
|
||||
add_task(async function test_backButton() {
|
||||
let form = new AddressForm();
|
||||
form.dataset.backButtonLabel = "Back";
|
||||
await form.requestStore.setState({
|
||||
page: {
|
||||
id: "test-page",
|
||||
},
|
||||
});
|
||||
await form.promiseReady;
|
||||
display.appendChild(form);
|
||||
await asyncElementRendered();
|
||||
|
||||
let stateChangePromise = promiseStateChange(form.requestStore);
|
||||
is(form.backButton.textContent, "Back", "Check label");
|
||||
synthesizeMouseAtCenter(form.backButton, {});
|
||||
|
||||
let {page} = await stateChangePromise;
|
||||
is(page.id, "payment-summary", "Check initial page after appending");
|
||||
|
||||
form.remove();
|
||||
});
|
||||
|
||||
add_task(async function test_saveButton() {
|
||||
let form = new AddressForm();
|
||||
form.dataset.saveButtonLabel = "Save";
|
||||
form.dataset.errorGenericSave = "Generic error";
|
||||
await form.promiseReady;
|
||||
display.appendChild(form);
|
||||
await asyncElementRendered();
|
||||
|
||||
form.form.querySelector("#given-name").focus();
|
||||
sendString("Jaws");
|
||||
form.form.querySelector("#family-name").focus();
|
||||
sendString("Swaj");
|
||||
form.form.querySelector("#organization").focus();
|
||||
sendString("Allizom");
|
||||
form.form.querySelector("#street-address").focus();
|
||||
sendString("404 Internet Super Highway");
|
||||
form.form.querySelector("#address-level2").focus();
|
||||
sendString("Firefoxity City");
|
||||
form.form.querySelector("#address-level1").focus();
|
||||
sendString("CA");
|
||||
form.form.querySelector("#postal-code").focus();
|
||||
sendString("00001");
|
||||
form.form.querySelector("#country option[value='US']").selected = true;
|
||||
form.form.querySelector("#email").focus();
|
||||
sendString("test@example.com");
|
||||
form.form.querySelector("#tel").focus();
|
||||
sendString("+15555551212");
|
||||
|
||||
let messagePromise = promiseContentToChromeMessage("updateAutofillRecord");
|
||||
is(form.saveButton.textContent, "Save", "Check label");
|
||||
synthesizeMouseAtCenter(form.saveButton, {});
|
||||
|
||||
let details = await messagePromise;
|
||||
is(details.collectionName, "addresses", "Check collectionName");
|
||||
isDeeply(details, {
|
||||
collectionName: "addresses",
|
||||
errorStateChange: {
|
||||
page: {
|
||||
id: "address-page",
|
||||
error: "Generic error",
|
||||
},
|
||||
},
|
||||
guid: undefined,
|
||||
messageType: "updateAutofillRecord",
|
||||
preserveOldProperties: true,
|
||||
record: {
|
||||
"given-name": "Jaws",
|
||||
"family-name": "Swaj",
|
||||
"organization": "Allizom",
|
||||
"street-address": "404 Internet Super Highway",
|
||||
"address-level2": "Firefoxity City",
|
||||
"address-level1": "CA",
|
||||
"postal-code": "00001",
|
||||
"country": "US",
|
||||
"email": "test@example.com",
|
||||
"tel": "+15555551212",
|
||||
},
|
||||
selectedStateKey: undefined,
|
||||
successStateChange: {
|
||||
page: {
|
||||
id: "payment-summary",
|
||||
},
|
||||
},
|
||||
}, "Check event details for the message to chrome");
|
||||
form.remove();
|
||||
});
|
||||
|
||||
add_task(async function test_genericError() {
|
||||
let form = new AddressForm();
|
||||
await form.requestStore.setState({
|
||||
page: {
|
||||
id: "test-page",
|
||||
error: "Generic Error",
|
||||
},
|
||||
});
|
||||
await form.promiseReady;
|
||||
display.appendChild(form);
|
||||
await asyncElementRendered();
|
||||
|
||||
ok(!isHidden(form.genericErrorText), "Error message should be visible");
|
||||
is(form.genericErrorText.textContent, "Generic Error", "Check error message");
|
||||
form.remove();
|
||||
});
|
||||
|
||||
add_task(async function test_edit() {
|
||||
let form = new AddressForm();
|
||||
await form.promiseReady;
|
||||
display.appendChild(form);
|
||||
await asyncElementRendered();
|
||||
|
||||
let address1 = deepClone(PTU.Addresses.TimBL);
|
||||
address1.guid = "9864798564";
|
||||
|
||||
await form.requestStore.setState({
|
||||
page: {
|
||||
id: "address-page",
|
||||
guid: address1.guid,
|
||||
},
|
||||
savedAddresses: {
|
||||
[address1.guid]: deepClone(address1),
|
||||
},
|
||||
});
|
||||
await asyncElementRendered();
|
||||
checkAddressForm(form, address1);
|
||||
|
||||
info("test change to minimal record");
|
||||
let minimalAddress = {
|
||||
"given-name": address1["given-name"],
|
||||
guid: "9gnjdhen46",
|
||||
};
|
||||
await form.requestStore.setState({
|
||||
page: {
|
||||
id: "address-page",
|
||||
guid: minimalAddress.guid,
|
||||
},
|
||||
savedAddresses: {
|
||||
[minimalAddress.guid]: deepClone(minimalAddress),
|
||||
},
|
||||
});
|
||||
await asyncElementRendered();
|
||||
checkAddressForm(form, minimalAddress);
|
||||
|
||||
info("change to no selected address");
|
||||
await form.requestStore.setState({
|
||||
page: {
|
||||
id: "address-page",
|
||||
},
|
||||
});
|
||||
await asyncElementRendered();
|
||||
checkAddressForm(form, {});
|
||||
|
||||
form.remove();
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче