Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/**
* Test that after we autofill, the site makes changes to the login, and then the
* user modifies their login, a save/update doorhanger is shown.
*
* This is a regression test for Bug 1632405.
*/
const testCases = [
{
name: "autofill, then delete u/p, then fill new u/p should show 'save'",
oldUsername: "oldUsername",
oldPassword: "oldPassword",
actions: [
{
setUsername: "newUsername",
},
{
setPassword: "newPassword",
},
],
expectedNotification: "addLogin",
expectedDoorhanger: "password-save",
},
{
name: "autofill, then delete password, then fill new password should show 'update'",
oldUsername: "oldUsername",
oldPassword: "oldPassword",
actions: [
{
setPassword: "newPassword",
},
],
expectedNotification: "modifyLogin",
expectedDoorhanger: "password-change",
},
];
for (let testData of testCases) {
let tmp = {
async [testData.name]() {
info("testing with: " + JSON.stringify(testData));
await test_save_change(testData);
},
};
add_task(tmp[testData.name]);
}
async function test_save_change({
name,
oldUsername,
oldPassword,
actions,
expectedNotification,
expectedDoorhanger,
}) {
let originalPrefValue = await Services.prefs.getBoolPref(
"signon.testOnlyUserHasInteractedByPrefValue"
);
Services.prefs.setBoolPref(
"signon.testOnlyUserHasInteractedByPrefValue",
false
);
info("Starting test: " + name);
await LoginTestUtils.addLogin({
username: oldUsername,
password: oldPassword,
origin: "https://example.com",
formActionOrigin: "https://example.com",
});
await BrowserTestUtils.withNewTab(
{
gBrowser,
url:
"passwordmgr/test/browser/form_basic.html",
},
async function (browser) {
await SimpleTest.promiseFocus(browser.ownerGlobal);
await ContentTask.spawn(
browser,
{ oldUsername, oldPassword },
async function awaitAutofill({ oldUsername, oldPassword }) {
await ContentTaskUtils.waitForCondition(
() =>
content.document.querySelector("#form-basic-username").value ==
oldUsername &&
content.document.querySelector("#form-basic-password").value ==
oldPassword,
"Await and verify autofill"
);
info(
"Triggering a page navigation that is not initiated by the user"
);
content.history.replaceState({}, "", "");
}
);
Services.prefs.setBoolPref(
"signon.testOnlyUserHasInteractedByPrefValue",
true
);
for (let action of actions) {
info(`As the user, update form with action: ${JSON.stringify(action)}`);
if (typeof action.setUsername !== "undefined") {
await changeContentFormValues(browser, {
"#form-basic-username": action.setUsername,
});
}
if (typeof action.setPassword !== "undefined") {
await changeContentFormValues(browser, {
"#form-basic-password": action.setPassword,
});
}
}
let expectedUsername =
[...actions]
.reverse()
.map(action => action.setUsername)
.find(username => !!username) ?? oldUsername;
let expectedPassword =
[...actions]
.reverse()
.map(action => action.setPassword)
.find(username => !!username) ?? oldPassword;
await ContentTask.spawn(
browser,
{ expectedUsername, expectedPassword },
async function awaitAutofill({ expectedUsername, expectedPassword }) {
info("Validating updated fields");
Assert.equal(
expectedUsername,
content.document.querySelector("#form-basic-username").value,
"Verify username field updated"
);
Assert.equal(
expectedPassword,
content.document.querySelector("#form-basic-password").value,
"Verify password field updated"
);
}
);
const formSubmittedPromise = listenForTestNotification("ShowDoorhanger");
await SpecialPowers.spawn(browser, [], async function () {
let doc = this.content.document;
doc.getElementById("form-basic").submit();
});
await formSubmittedPromise;
info("Waiting for doorhanger of type: " + expectedDoorhanger);
const notif = await waitForDoorhanger(browser, expectedDoorhanger);
await checkDoorhangerUsernamePassword(expectedUsername, expectedPassword);
const promiseLogin = TestUtils.topicObserved(
"passwordmgr-storage-changed",
(_, data) => data == expectedNotification
);
await clickDoorhangerButton(notif, REMEMBER_BUTTON);
await promiseLogin;
await cleanupDoorhanger(notif); // clean slate for the next test
Services.prefs.setBoolPref(
"signon.testOnlyUserHasInteractedByPrefValue",
originalPrefValue
);
}
);
// Clean up the database before the next test case is executed.
Services.logins.removeAllUserFacingLogins();
}