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:
Ray Lin 2017-10-24 12:10:09 +08:00
parent 6e6989c8a6
commit b17ff5950f
6 changed files with 181 additions and 159 deletions

View File

@ -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();

View File

@ -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]

View File

@ -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);

View File

@ -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);

View File

@ -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>

View File

@ -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>