mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-23 02:05:42 +00:00
Bug 1407508 - Part 5. Add mochitest for clear form button. r=lchang
MozReview-Commit-ID: 2TfAcwKmQTq --HG-- extra : rebase_source : 55a3bd41c0fa9d324361d0bbbe584b03310a2143
This commit is contained in:
parent
6e6989c8a6
commit
b17ff5950f
@ -5,6 +5,7 @@
|
||||
"use strict";
|
||||
|
||||
let formFillChromeScript;
|
||||
let defaultTextColor;
|
||||
let expectingPopup = null;
|
||||
|
||||
const {FormAutofillUtils} = SpecialPowers.Cu.import("resource://formautofill/FormAutofillUtils.jsm");
|
||||
@ -66,6 +67,62 @@ function clickOnElement(selector) {
|
||||
SimpleTest.executeSoon(() => element.click());
|
||||
}
|
||||
|
||||
// The equivalent helper function to getAdaptedProfiles in FormAutofillHandler.jsm that
|
||||
// transforms the given profile to expected filled profile.
|
||||
function _getAdaptedProfile(profile) {
|
||||
const adaptedProfile = Object.assign({}, profile);
|
||||
|
||||
if (profile["street-address"]) {
|
||||
adaptedProfile["street-address"] = FormAutofillUtils.toOneLineAddress(profile["street-address"]);
|
||||
}
|
||||
|
||||
return adaptedProfile;
|
||||
}
|
||||
|
||||
// We could not get ManuallyManagedState of element now, so directly check if
|
||||
// filter and text color style are applied.
|
||||
function checkFieldHighlighted(elem, expectedValue) {
|
||||
const computedStyle = window.getComputedStyle(elem);
|
||||
const isHighlighteApplied = computedStyle.getPropertyValue("filter") !== "none";
|
||||
|
||||
is(isHighlighteApplied, expectedValue, `Checking #${elem.id} highlight style`);
|
||||
}
|
||||
|
||||
function checkFieldPreview(elem, expectedValue) {
|
||||
const computedStyle = window.getComputedStyle(elem);
|
||||
const isTextColorApplied = computedStyle.getPropertyValue("color") !== defaultTextColor;
|
||||
|
||||
is(SpecialPowers.wrap(elem).previewValue, expectedValue, `Checking #${elem.id} previewValue`);
|
||||
is(isTextColorApplied, !!expectedValue, `Checking #${elem.id} preview style`);
|
||||
}
|
||||
|
||||
function checkFieldValue(elem, expectedValue) {
|
||||
if (typeof elem === "string") {
|
||||
elem = document.querySelector(elem);
|
||||
}
|
||||
is(elem.value, String(expectedValue), "Checking " + elem.id + " field");
|
||||
}
|
||||
|
||||
function triggerAutofillAndCheckProfile(profile) {
|
||||
const adaptedProfile = _getAdaptedProfile(profile);
|
||||
const promises = [];
|
||||
|
||||
for (const [fieldName, value] of Object.entries(adaptedProfile)) {
|
||||
const element = document.getElementById(fieldName);
|
||||
const expectingEvent = document.activeElement == element ? "DOMAutoComplete" : "change";
|
||||
const checkFieldAutofilled = Promise.all([
|
||||
new Promise(resolve => element.addEventListener("input", resolve, {once: true})),
|
||||
new Promise(resolve => element.addEventListener(expectingEvent, resolve, {once: true})),
|
||||
]).then(() => checkFieldValue(element, value));
|
||||
|
||||
promises.push(checkFieldAutofilled);
|
||||
}
|
||||
// Press return key and trigger form autofill.
|
||||
doKey("return");
|
||||
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
async function onStorageChanged(type) {
|
||||
info(`expecting the storage changed: ${type}`);
|
||||
return new Promise(resolve => {
|
||||
@ -183,6 +240,16 @@ function initPopupListener() {
|
||||
registerPopupShownListener(popupShownListener);
|
||||
}
|
||||
|
||||
async function triggerPopupAndHoverItem(fieldSelector, selectIndex) {
|
||||
await focusAndWaitForFieldsIdentified(fieldSelector);
|
||||
doKey("down");
|
||||
await expectPopup();
|
||||
for (let i = 0; i <= selectIndex; i++) {
|
||||
doKey("down");
|
||||
}
|
||||
await notifySelectedIndex(selectIndex);
|
||||
}
|
||||
|
||||
function formAutoFillCommonSetup() {
|
||||
let chromeURL = SimpleTest.getTestFileURL("formautofill_parent_utils.js");
|
||||
formFillChromeScript = SpecialPowers.loadChromeScript(chromeURL);
|
||||
@ -201,6 +268,11 @@ function formAutoFillCommonSetup() {
|
||||
formFillChromeScript.destroy();
|
||||
expectingPopup = null;
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
defaultTextColor = window.getComputedStyle(document.querySelector("input"))
|
||||
.getPropertyValue("color");
|
||||
}, {once: true});
|
||||
}
|
||||
|
||||
formAutoFillCommonSetup();
|
||||
|
@ -11,6 +11,7 @@ support-files =
|
||||
[test_basic_autocomplete_form.html]
|
||||
[test_basic_creditcard_autocomplete_form.html]
|
||||
scheme=https
|
||||
[test_clear_form.html]
|
||||
[test_creditcard_autocomplete_off.html]
|
||||
scheme=https
|
||||
[test_form_changes.html]
|
||||
|
@ -33,52 +33,6 @@ let MOCK_STORAGE = [{
|
||||
"address-level1": "CA",
|
||||
}];
|
||||
|
||||
function checkElementFilled(element, expectedvalue) {
|
||||
return [
|
||||
new Promise(resolve => {
|
||||
element.addEventListener("input", function onInput() {
|
||||
ok(true, "Checking " + element.name + " field fires input event");
|
||||
resolve();
|
||||
}, {once: true});
|
||||
}),
|
||||
new Promise(resolve => {
|
||||
element.addEventListener("change", function onChange() {
|
||||
ok(true, "Checking " + element.name + " field fires change event");
|
||||
is(element.value, expectedvalue, "Checking " + element.name + " field");
|
||||
resolve();
|
||||
}, {once: true});
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
function checkAutoCompleteInputFilled(element, expectedvalue) {
|
||||
return new Promise(resolve => {
|
||||
element.addEventListener("DOMAutoComplete", function onChange() {
|
||||
is(element.value, expectedvalue, "Checking " + element.name + " field");
|
||||
resolve();
|
||||
}, {once: true});
|
||||
});
|
||||
}
|
||||
|
||||
function checkFormFilled(address) {
|
||||
info("expecting form filled");
|
||||
let promises = [];
|
||||
for (let prop in address) {
|
||||
let element = document.getElementById(prop);
|
||||
if (document.activeElement == element) {
|
||||
promises.push(checkAutoCompleteInputFilled(element, address[prop]));
|
||||
} else {
|
||||
let converted = address[prop];
|
||||
if (prop == "street-address") {
|
||||
converted = FormAutofillUtils.toOneLineAddress(converted);
|
||||
}
|
||||
promises.push(...checkElementFilled(element, converted));
|
||||
}
|
||||
}
|
||||
doKey("return");
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
async function setupAddressStorage() {
|
||||
await addAddress(MOCK_STORAGE[0]);
|
||||
await addAddress(MOCK_STORAGE[1]);
|
||||
@ -198,12 +152,12 @@ add_task(async function check_fields_after_form_autofill() {
|
||||
})
|
||||
).slice(1));
|
||||
doKey("down");
|
||||
await checkFormFilled(MOCK_STORAGE[1]);
|
||||
await triggerAutofillAndCheckProfile(MOCK_STORAGE[1]);
|
||||
});
|
||||
|
||||
// Fallback to history search after autofill address.
|
||||
add_task(async function check_fallback_after_form_autofill() {
|
||||
await setInput("#tel", "");
|
||||
await setInput("#tel", "", true);
|
||||
doKey("down");
|
||||
await expectPopup();
|
||||
checkMenuEntries(["+1234567890"], false);
|
||||
|
@ -36,44 +36,6 @@ const reducedMockRecord = {
|
||||
"cc-number": "1234123456785678",
|
||||
};
|
||||
|
||||
function checkElementFilled(element, expectedvalue) {
|
||||
const focusedElem = document.activeElement;
|
||||
const promises = [];
|
||||
|
||||
promises.push(new Promise(resolve => {
|
||||
element.addEventListener("input", function onInput() {
|
||||
ok(true, "Checking " + element.name + " field fires input event");
|
||||
resolve();
|
||||
}, {once: true});
|
||||
}));
|
||||
|
||||
// Don't expect that focused input will receive "change" event since focus never move away.
|
||||
if (element !== focusedElem) {
|
||||
promises.push(new Promise(resolve => {
|
||||
element.addEventListener("change", function onChange() {
|
||||
ok(true, "Checking " + element.name + " field fires change event");
|
||||
is(element.value, expectedvalue, "Checking " + element.name + " field");
|
||||
resolve();
|
||||
}, {once: true});
|
||||
}));
|
||||
}
|
||||
|
||||
return promises;
|
||||
}
|
||||
|
||||
function checkFormFilled(creditCard) {
|
||||
info("expecting form filled");
|
||||
let promises = [];
|
||||
for (let prop in creditCard) {
|
||||
let element = document.getElementById(prop);
|
||||
let converted = String(creditCard[prop]); // Convert potential number to string
|
||||
|
||||
promises.push(...checkElementFilled(element, converted));
|
||||
}
|
||||
doKey("return");
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
async function setupCreditCardStorage() {
|
||||
await addCreditCard(MOCK_STORAGE[0]);
|
||||
await addCreditCard(MOCK_STORAGE[1]);
|
||||
@ -199,12 +161,12 @@ add_task(async function check_fields_after_form_autofill() {
|
||||
})));
|
||||
|
||||
doKey("down");
|
||||
await checkFormFilled(MOCK_STORAGE[1]);
|
||||
await triggerAutofillAndCheckProfile(MOCK_STORAGE[1]);
|
||||
});
|
||||
|
||||
// Fallback to history search after autofill address.
|
||||
add_task(async function check_fallback_after_form_autofill() {
|
||||
await setInput("#cc-name", "");
|
||||
await setInput("#cc-name", "", true);
|
||||
doKey("down");
|
||||
await expectPopup();
|
||||
checkMenuEntries(["John Smith"], false);
|
||||
|
@ -0,0 +1,90 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test form autofill - clear form button</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script>
|
||||
<script type="text/javascript" src="formautofill_common.js"></script>
|
||||
<script type="text/javascript" src="satchel_common.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
Form autofill test: clear form button
|
||||
|
||||
<script>
|
||||
/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SpawnTask.js */
|
||||
/* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
|
||||
/* import-globals-from formautofill_common.js */
|
||||
|
||||
"use strict";
|
||||
|
||||
const MOCK_STORAGE = [{
|
||||
organization: "Sesame Street",
|
||||
"street-address": "123 Sesame Street.",
|
||||
tel: "+13453453456",
|
||||
}, {
|
||||
organization: "Mozilla",
|
||||
"street-address": "331 E. Evelyn Avenue",
|
||||
}, {
|
||||
organization: "Tel org",
|
||||
tel: "+12223334444",
|
||||
}];
|
||||
|
||||
initPopupListener();
|
||||
|
||||
add_task(async function setup_storage() {
|
||||
await addAddress(MOCK_STORAGE[0]);
|
||||
await addAddress(MOCK_STORAGE[1]);
|
||||
await addAddress(MOCK_STORAGE[2]);
|
||||
});
|
||||
|
||||
function checkIsFormCleared(patch = {}) {
|
||||
const form = document.getElementById("form1");
|
||||
|
||||
for (const elem of form.elements) {
|
||||
const expectedValue = patch[elem.id] || "";
|
||||
is(elem.value, expectedValue, "checking value");
|
||||
checkFieldHighlighted(elem, false);
|
||||
checkFieldPreview(elem, "");
|
||||
}
|
||||
}
|
||||
|
||||
add_task(async function simple_clear() {
|
||||
await triggerPopupAndHoverItem("#organization", 0);
|
||||
await triggerAutofillAndCheckProfile(MOCK_STORAGE[0]);
|
||||
|
||||
await triggerPopupAndHoverItem("#tel", 0);
|
||||
doKey("return");
|
||||
checkIsFormCleared();
|
||||
});
|
||||
|
||||
add_task(async function clear_modified_form() {
|
||||
await triggerPopupAndHoverItem("#organization", 0);
|
||||
await triggerAutofillAndCheckProfile(MOCK_STORAGE[0]);
|
||||
|
||||
await setInput("#tel", "+1111111111", true);
|
||||
|
||||
await triggerPopupAndHoverItem("#street-address", 0);
|
||||
doKey("return");
|
||||
checkIsFormCleared({tel: "+1111111111"});
|
||||
});
|
||||
</script>
|
||||
|
||||
<p id="display"></p>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<form id="form1">
|
||||
<p>This is a basic form.</p>
|
||||
<p><label>organization: <input id="organization" autocomplete="organization"></label></p>
|
||||
<p><label>streetAddress: <input id="street-address" autocomplete="street-address"></label></p>
|
||||
<p><label>tel: <input id="tel" autocomplete="tel"></label></p>
|
||||
<p><label>country: <input id="country" autocomplete="country"></label></p>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</html>
|
@ -19,7 +19,6 @@ Form autofill test: preview and highlight
|
||||
|
||||
"use strict";
|
||||
|
||||
let defaultTextColor;
|
||||
const MOCK_STORAGE = [{
|
||||
organization: "Sesame Street",
|
||||
"street-address": "123 Sesame Street.",
|
||||
@ -32,66 +31,21 @@ const MOCK_STORAGE = [{
|
||||
tel: "+12223334444",
|
||||
}];
|
||||
|
||||
// We could not get ManuallyManagedState of element now, so directly check if
|
||||
// filter and text color style are applied.
|
||||
function checkFieldPreview(elem, expectedText) {
|
||||
const computedStyle = window.getComputedStyle(elem);
|
||||
const isStyleApplied = computedStyle.getPropertyValue("filter") !== "none" &&
|
||||
computedStyle.getPropertyValue("color") !== defaultTextColor;
|
||||
function checkFormFieldsStyle(profile, isPreviewing = true) {
|
||||
const elems = document.querySelectorAll("input, select");
|
||||
|
||||
is(SpecialPowers.wrap(elem).previewValue, expectedText, `Checking #${elem.id} previewValue`);
|
||||
is(isStyleApplied, !!expectedText, `Checking #${elem.id} preview style`);
|
||||
}
|
||||
for (const elem of elems) {
|
||||
const fillableValue = profile && profile[elem.id];
|
||||
const previewValue = isPreviewing && fillableValue || "";
|
||||
|
||||
function checkFilledFieldHighlight(elem, expectedValue) {
|
||||
const computedStyle = window.getComputedStyle(elem);
|
||||
const isStyleApplied = computedStyle.getPropertyValue("filter") !== "none" &&
|
||||
computedStyle.getPropertyValue("color") === defaultTextColor;
|
||||
|
||||
is(SpecialPowers.wrap(elem).previewValue, "", `Checking #${elem.id} filled previewValue`);
|
||||
is(isStyleApplied, expectedValue, `Checking #${elem.id} filled style`);
|
||||
}
|
||||
|
||||
function checkFormPreviewFields(previewingAddress) {
|
||||
const inputs = document.querySelectorAll("input");
|
||||
|
||||
for (const input of inputs) {
|
||||
const previewValue = previewingAddress && previewingAddress[input.id] || "";
|
||||
|
||||
checkFieldPreview(input, previewValue);
|
||||
checkFieldHighlighted(elem, !!fillableValue);
|
||||
checkFieldPreview(elem, previewValue);
|
||||
}
|
||||
}
|
||||
|
||||
function checkFormFilledFields(address) {
|
||||
const inputs = document.querySelectorAll("input");
|
||||
|
||||
for (const input of inputs) {
|
||||
const isFilledByAutofill = !!address[input.id];
|
||||
|
||||
checkFilledFieldHighlight(input, isFilledByAutofill);
|
||||
}
|
||||
}
|
||||
|
||||
function confirmAllFieldsFilled(address) {
|
||||
info("expecting form filled");
|
||||
const pendingPromises = [];
|
||||
|
||||
for (const prop in address) {
|
||||
const element = document.getElementById(prop);
|
||||
|
||||
pendingPromises.push(new Promise(resolve => {
|
||||
element.addEventListener("change", resolve, {once: true});
|
||||
}));
|
||||
}
|
||||
|
||||
return Promise.all(pendingPromises);
|
||||
}
|
||||
|
||||
initPopupListener();
|
||||
|
||||
add_task(async function setup_storage() {
|
||||
defaultTextColor = window.getComputedStyle(document.querySelector("input")).getPropertyValue("color");
|
||||
|
||||
await addAddress(MOCK_STORAGE[0]);
|
||||
await addAddress(MOCK_STORAGE[1]);
|
||||
await addAddress(MOCK_STORAGE[2]);
|
||||
@ -102,42 +56,31 @@ add_task(async function check_preview() {
|
||||
|
||||
doKey("down");
|
||||
await expectPopup();
|
||||
checkFormPreviewFields();
|
||||
checkFormFieldsStyle(null);
|
||||
|
||||
for (let i = 0; i < MOCK_STORAGE.length; i++) {
|
||||
doKey("down");
|
||||
await notifySelectedIndex(i);
|
||||
checkFormPreviewFields(MOCK_STORAGE[i]);
|
||||
checkFormFieldsStyle(MOCK_STORAGE[i]);
|
||||
}
|
||||
|
||||
// Navigate to the footer
|
||||
doKey("down");
|
||||
await notifySelectedIndex(MOCK_STORAGE.length);
|
||||
checkFormPreviewFields();
|
||||
checkFormFieldsStyle(null);
|
||||
|
||||
doKey("down");
|
||||
await notifySelectedIndex(-1);
|
||||
checkFormPreviewFields();
|
||||
checkFormFieldsStyle(null);
|
||||
|
||||
focusedInput.blur();
|
||||
});
|
||||
|
||||
add_task(async function check_filled_highlight() {
|
||||
const focusedInput = await setInput("#organization", "");
|
||||
|
||||
doKey("down");
|
||||
await expectPopup();
|
||||
|
||||
doKey("down");
|
||||
await notifySelectedIndex(0);
|
||||
const waitForFilled = confirmAllFieldsFilled(MOCK_STORAGE[0]);
|
||||
|
||||
await triggerPopupAndHoverItem("#organization", 0);
|
||||
// filled 1st address
|
||||
doKey("return");
|
||||
// blur to fire off change event from focusedInput
|
||||
focusedInput.blur();
|
||||
await waitForFilled;
|
||||
checkFormFilledFields(MOCK_STORAGE[0]);
|
||||
await triggerAutofillAndCheckProfile(MOCK_STORAGE[0]);
|
||||
checkFormFieldsStyle(MOCK_STORAGE[0], false);
|
||||
});
|
||||
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user