зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1325538 - Add mochitest-plain tests for form autofill. r=MattN
MozReview-Commit-ID: HK6dmI4m3co --HG-- extra : rebase_source : 8020505afe752d66cfc352dbe4d0696cbdcce545
This commit is contained in:
Родитель
64526e4433
Коммит
1c23a43ac9
|
@ -1634,7 +1634,7 @@ pref("browser.crashReports.unsubmittedCheck.autoSubmit", false);
|
|||
|
||||
// Preferences for the form autofill system extension
|
||||
pref("browser.formautofill.experimental", false);
|
||||
pref("browser.formautofill.enabled", false);
|
||||
pref("browser.formautofill.enabled", true);
|
||||
pref("browser.formautofill.loglevel", "Warn");
|
||||
|
||||
// Whether or not to restore a session with lazy-browser tabs.
|
||||
|
|
|
@ -21,6 +21,8 @@ BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
|
|||
|
||||
XPCSHELL_TESTS_MANIFESTS += ['test/unit/xpcshell.ini']
|
||||
|
||||
MOCHITEST_MANIFESTS += ['test/mochitest/mochitest.ini']
|
||||
|
||||
JAR_MANIFESTS += ['jar.mn']
|
||||
|
||||
with Files('**'):
|
||||
|
|
|
@ -22,28 +22,28 @@ add_task(function* test_aboutPreferences() {
|
|||
});
|
||||
|
||||
// Visibility of form autofill group should be visible when opening
|
||||
// directly to privacy page. Checkbox is not checked by default.
|
||||
// directly to privacy page. Checkbox is checked by default.
|
||||
add_task(function* test_aboutPreferencesPrivacy() {
|
||||
yield BrowserTestUtils.withNewTab({gBrowser, url: PAGE_PRIVACY}, function* (browser) {
|
||||
yield ContentTask.spawn(browser, TEST_SELECTORS, (args) => {
|
||||
is(content.document.querySelector(args.group).hidden, false,
|
||||
"Form Autofill group should be visible");
|
||||
is(content.document.querySelector(args.checkbox).checked, false,
|
||||
"Checkbox should be unchecked");
|
||||
is(content.document.querySelector(args.checkbox).checked, true,
|
||||
"Checkbox should be checked");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Checkbox should be checked when form autofill is enabled.
|
||||
add_task(function* test_autofillEnabledCheckbox() {
|
||||
SpecialPowers.pushPrefEnv({set: [[PREF_AUTOFILL_ENABLED, true]]});
|
||||
// Checkbox should be unchecked when form autofill is disabled.
|
||||
add_task(function* test_autofillDisabledCheckbox() {
|
||||
SpecialPowers.pushPrefEnv({set: [[PREF_AUTOFILL_ENABLED, false]]});
|
||||
|
||||
yield BrowserTestUtils.withNewTab({gBrowser, url: PAGE_PRIVACY}, function* (browser) {
|
||||
yield ContentTask.spawn(browser, TEST_SELECTORS, (args) => {
|
||||
is(content.document.querySelector(args.group).hidden, false,
|
||||
"Form Autofill group should be visible");
|
||||
is(content.document.querySelector(args.checkbox).checked, true,
|
||||
"Checkbox should be checked when Form Autofill is enabled");
|
||||
is(content.document.querySelector(args.checkbox).checked, false,
|
||||
"Checkbox should be unchecked when Form Autofill is disabled");
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
"extends": [
|
||||
"plugin:mozilla/mochitest-test"
|
||||
],
|
||||
};
|
|
@ -0,0 +1,75 @@
|
|||
/* import-globals-from ../../../../../testing/mochitest/tests/SimpleTest/SimpleTest.js */
|
||||
/* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */
|
||||
/* eslint-disable no-unused-vars */
|
||||
|
||||
"use strict";
|
||||
|
||||
let formFillChromeScript;
|
||||
|
||||
function setInput(selector, value) {
|
||||
let input = document.querySelector("input" + selector);
|
||||
input.value = value;
|
||||
input.focus();
|
||||
}
|
||||
|
||||
function checkMenuEntries(expectedValues) {
|
||||
let actualValues = getMenuEntries();
|
||||
|
||||
is(actualValues.length, expectedValues.length, " Checking length of expected menu");
|
||||
for (let i = 0; i < expectedValues.length; i++) {
|
||||
is(actualValues[i], expectedValues[i], " Checking menu entry #" + i);
|
||||
}
|
||||
}
|
||||
|
||||
function addProfile(profile) {
|
||||
return new Promise(resolve => {
|
||||
formFillChromeScript.sendAsyncMessage("FormAutofillTest:AddProfile", {profile});
|
||||
formFillChromeScript.addMessageListener("FormAutofillTest:ProfileAdded", function onAdded(data) {
|
||||
formFillChromeScript.removeMessageListener("FormAutofillTest:ProfileAdded", onAdded);
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function removeProfile(guid) {
|
||||
return new Promise(resolve => {
|
||||
formFillChromeScript.sendAsyncMessage("FormAutofillTest:RemoveProfile", {guid});
|
||||
formFillChromeScript.addMessageListener("FormAutofillTest:ProfileRemoved", function onDeleted(data) {
|
||||
formFillChromeScript.removeMessageListener("FormAutofillTest:ProfileRemoved", onDeleted);
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function updateProfile(guid, profile) {
|
||||
return new Promise(resolve => {
|
||||
formFillChromeScript.sendAsyncMessage("FormAutofillTest:UpdateProfile", {profile, guid});
|
||||
formFillChromeScript.addMessageListener("FormAutofillTest:ProfileUpdated", function onUpdated(data) {
|
||||
formFillChromeScript.removeMessageListener("FormAutofillTest:ProfileUpdated", onUpdated);
|
||||
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function formAutoFillCommonSetup() {
|
||||
let chromeURL = SimpleTest.getTestFileURL("formautofill_parent_utils.js");
|
||||
formFillChromeScript = SpecialPowers.loadChromeScript(chromeURL);
|
||||
SpecialPowers.setBoolPref("dom.forms.autocomplete.experimental", true);
|
||||
formFillChromeScript.addMessageListener("onpopupshown", ({results}) => {
|
||||
gLastAutoCompleteResults = results;
|
||||
if (gPopupShownListener) {
|
||||
gPopupShownListener({results});
|
||||
}
|
||||
});
|
||||
|
||||
SimpleTest.registerCleanupFunction(() => {
|
||||
SpecialPowers.clearUserPref("dom.forms.autocomplete.experimental");
|
||||
formFillChromeScript.sendAsyncMessage("cleanup");
|
||||
formFillChromeScript.destroy();
|
||||
});
|
||||
}
|
||||
|
||||
formAutoFillCommonSetup();
|
|
@ -0,0 +1,63 @@
|
|||
// assert is available to chrome scripts loaded via SpecialPowers.loadChromeScript.
|
||||
/* global assert */
|
||||
|
||||
"use strict";
|
||||
|
||||
const {classes: Cc, interfaces: Ci, utils: Cu} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var ParentUtils = {
|
||||
cleanUpProfile() {
|
||||
Services.cpmm.addMessageListener("FormAutofill:Profiles", function getResult(result) {
|
||||
Services.cpmm.removeMessageListener("FormAutofill:Profiles", getResult);
|
||||
|
||||
let profiles = result.data;
|
||||
Services.cpmm.sendAsyncMessage("FormAutofill:RemoveProfiles",
|
||||
{guids: profiles.map(profile => profile.guid)});
|
||||
});
|
||||
|
||||
Services.cpmm.sendAsyncMessage("FormAutofill:GetProfiles", {searchString: ""});
|
||||
},
|
||||
|
||||
updateProfile(type, chromeMsg, msgData, contentMsg) {
|
||||
Services.cpmm.sendAsyncMessage(chromeMsg, msgData);
|
||||
Services.obs.addObserver(function observer(subject, topic, data) {
|
||||
if (data != type) {
|
||||
return;
|
||||
}
|
||||
|
||||
Services.obs.removeObserver(observer, topic);
|
||||
sendAsyncMessage(contentMsg);
|
||||
}, "formautofill-storage-changed");
|
||||
},
|
||||
|
||||
observe(subject, topic, data) {
|
||||
assert.ok(topic === "formautofill-storage-changed");
|
||||
sendAsyncMessage("formautofill-storage-changed", {subject: null, topic, data});
|
||||
},
|
||||
|
||||
cleanup() {
|
||||
Services.obs.removeObserver(this, "formautofill-storage-changed");
|
||||
this.cleanUpProfile();
|
||||
},
|
||||
};
|
||||
|
||||
ParentUtils.cleanUpProfile();
|
||||
Services.obs.addObserver(ParentUtils, "formautofill-storage-changed");
|
||||
|
||||
addMessageListener("FormAutofillTest:AddProfile", (msg) => {
|
||||
ParentUtils.updateProfile("add", "FormAutofill:SaveProfile", msg, "FormAutofillTest:ProfileAdded");
|
||||
});
|
||||
|
||||
addMessageListener("FormAutofillTest:RemoveProfile", (msg) => {
|
||||
ParentUtils.updateProfile("remove", "FormAutofill:Removefile", msg, "FormAutofillTest:ProfileRemoved");
|
||||
});
|
||||
|
||||
addMessageListener("FormAutofillTest:UpdateProfile", (msg) => {
|
||||
ParentUtils.updateProfile("update", "FormAutofill:SaveProfile", msg, "FormAutofillTest:ProfileUpdated");
|
||||
});
|
||||
|
||||
addMessageListener("cleanup", () => {
|
||||
ParentUtils.cleanup();
|
||||
});
|
|
@ -0,0 +1,9 @@
|
|||
[DEFAULT]
|
||||
support-files =
|
||||
../../../../../toolkit/components/satchel/test/satchel_common.js
|
||||
../../../../../toolkit/components/satchel/test/parent_utils.js
|
||||
formautofill_common.js
|
||||
formautofill_parent_utils.js
|
||||
|
||||
[test_basic_autocomplete_form.html]
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test basic autofill</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: simple form profile autofill
|
||||
|
||||
<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";
|
||||
|
||||
let expectingPopup = null;
|
||||
let MOCK_STORAGE = [{
|
||||
organization: "Sesame Street",
|
||||
"street-address": "123 Sesame Street.",
|
||||
tel: "1-345-345-3456",
|
||||
}, {
|
||||
organization: "Mozilla",
|
||||
"street-address": "331 E. Evelyn Avenue",
|
||||
tel: "1-650-903-0800",
|
||||
}];
|
||||
|
||||
function expectPopup() {
|
||||
info("expecting a popup");
|
||||
return new Promise(resolve => {
|
||||
expectingPopup = resolve;
|
||||
});
|
||||
}
|
||||
|
||||
function popupShownListener() {
|
||||
info("popup shown for test ");
|
||||
if (expectingPopup) {
|
||||
expectingPopup();
|
||||
expectingPopup = null;
|
||||
}
|
||||
}
|
||||
|
||||
function checkInputFilled(element, expectedvalue) {
|
||||
return new Promise(resolve => {
|
||||
element.addEventListener("change", function onChange() {
|
||||
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(profile) {
|
||||
let promises = [];
|
||||
for (let prop in profile) {
|
||||
let element = document.getElementById(prop);
|
||||
if (document.activeElement == element) {
|
||||
promises.push(checkAutoCompleteInputFilled(element, profile[prop]));
|
||||
} else {
|
||||
promises.push(checkInputFilled(element, profile[prop]));
|
||||
}
|
||||
}
|
||||
doKey("return");
|
||||
return Promise.all(promises);
|
||||
}
|
||||
|
||||
function* setupProfileStorage() {
|
||||
yield addProfile(MOCK_STORAGE[0]);
|
||||
yield addProfile(MOCK_STORAGE[1]);
|
||||
}
|
||||
|
||||
function* setupFormHistory() {
|
||||
yield updateFormHistory([
|
||||
{op: "add", fieldname: "tel", value: "1-234-567-890"},
|
||||
{op: "add", fieldname: "country", value: "US"},
|
||||
]);
|
||||
}
|
||||
|
||||
// Form with history only.
|
||||
add_task(function* history_only_menu_checking() {
|
||||
yield setupFormHistory();
|
||||
|
||||
setInput("#tel", "");
|
||||
doKey("down");
|
||||
yield expectPopup();
|
||||
checkMenuEntries(["1-234-567-890"]);
|
||||
});
|
||||
|
||||
// Form with both history and profile storage.
|
||||
add_task(function* check_menu_when_both_existed() {
|
||||
yield setupProfileStorage();
|
||||
|
||||
setInput("#organization", "");
|
||||
doKey("down");
|
||||
yield expectPopup();
|
||||
checkMenuEntries(MOCK_STORAGE.map(profile =>
|
||||
JSON.stringify({primary: profile.organization, secondary: profile["street-address"]})
|
||||
));
|
||||
|
||||
setInput("#street-address", "");
|
||||
doKey("down");
|
||||
yield expectPopup();
|
||||
checkMenuEntries(MOCK_STORAGE.map(profile =>
|
||||
JSON.stringify({primary: profile["street-address"], secondary: profile.organization})
|
||||
));
|
||||
|
||||
setInput("#tel", "");
|
||||
doKey("down");
|
||||
yield expectPopup();
|
||||
checkMenuEntries(MOCK_STORAGE.map(profile =>
|
||||
JSON.stringify({primary: profile.tel, secondary: profile["street-address"]})
|
||||
));
|
||||
});
|
||||
|
||||
// Display history search result if no matched data in profiles.
|
||||
add_task(function* check_fallback_for_mismatched_field() {
|
||||
setInput("#country", "");
|
||||
doKey("down");
|
||||
yield expectPopup();
|
||||
checkMenuEntries(["US"]);
|
||||
});
|
||||
|
||||
// Autofill the profile from dropdown menu.
|
||||
add_task(function* check_fields_after_form_autofill() {
|
||||
setInput("#organization", "Moz");
|
||||
doKey("down");
|
||||
yield expectPopup();
|
||||
checkMenuEntries(MOCK_STORAGE.map(profile =>
|
||||
JSON.stringify({primary: profile.organization, secondary: profile["street-address"]})
|
||||
).slice(1));
|
||||
doKey("down");
|
||||
yield checkFormFilled(MOCK_STORAGE[1]);
|
||||
});
|
||||
|
||||
// Fallback to history search after autofill profile.
|
||||
add_task(function* check_fallback_after_form_autofill() {
|
||||
setInput("#tel", "");
|
||||
doKey("down");
|
||||
yield expectPopup();
|
||||
checkMenuEntries(["1-234-567-890"]);
|
||||
});
|
||||
|
||||
registerPopupShownListener(popupShownListener);
|
||||
|
||||
</script>
|
||||
|
||||
<p id="display"></p>
|
||||
|
||||
<div id="content">
|
||||
|
||||
<form id="form1">
|
||||
<p>This is a basic form.</p>
|
||||
<p><label>organization: <input id="organization" name="organization" autocomplete="organization" type="text"></label></p>
|
||||
<p><label>streetAddress: <input id="street-address" name="street-address" autocomplete="street-address" type="text"></label></p>
|
||||
<p><label>tel: <input id="tel" name="tel" autocomplete="tel" type="text"></label></p>
|
||||
<p><label>country: <input id="country" name="country" autocomplete="country" type="text"></label></p>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче