mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 01:05:45 +00:00
Bug 1388674 - Update tests to use setUserInput, ensuring we get an input event for field modifications. r=MattN
Depends on D53055 Differential Revision: https://phabricator.services.mozilla.com/D51718 --HG-- extra : moz-landing-system : lando
This commit is contained in:
parent
0150488e14
commit
2831a02039
@ -96,14 +96,14 @@ async function submitSomeCrossSiteFrames(locationMode) {
|
|||||||
|
|
||||||
await SpecialPowers.spawn(outerFrameBC, [], () => {
|
await SpecialPowers.spawn(outerFrameBC, [], () => {
|
||||||
let doc = content.document;
|
let doc = content.document;
|
||||||
doc.getElementById("outer-username").value = "outer";
|
doc.getElementById("outer-username").setUserInput("outer");
|
||||||
doc.getElementById("outer-password").value = "outerpass";
|
doc.getElementById("outer-password").setUserInput("outerpass");
|
||||||
});
|
});
|
||||||
|
|
||||||
await SpecialPowers.spawn(innerFrameBC, [locationMode], doClick => {
|
await SpecialPowers.spawn(innerFrameBC, [locationMode], doClick => {
|
||||||
let doc = content.document;
|
let doc = content.document;
|
||||||
doc.getElementById("inner-username").value = "inner";
|
doc.getElementById("inner-username").setUserInput("inner");
|
||||||
doc.getElementById("inner-password").value = "innerpass";
|
doc.getElementById("inner-password").setUserInput("innerpass");
|
||||||
if (doClick) {
|
if (doClick) {
|
||||||
doc.getElementById("inner-gobutton").click();
|
doc.getElementById("inner-gobutton").click();
|
||||||
} else {
|
} else {
|
||||||
@ -138,8 +138,8 @@ async function submitSomeCrossSiteFrames(locationMode) {
|
|||||||
|
|
||||||
await SpecialPowers.spawn(outerFrameBC2, [locationMode], doClick => {
|
await SpecialPowers.spawn(outerFrameBC2, [locationMode], doClick => {
|
||||||
let doc = content.document;
|
let doc = content.document;
|
||||||
doc.getElementById("outer-username").value = "outer2";
|
doc.getElementById("outer-username").setUserInput("outer2");
|
||||||
doc.getElementById("outer-password").value = "outerpass2";
|
doc.getElementById("outer-password").setUserInput("outerpass2");
|
||||||
if (doClick) {
|
if (doClick) {
|
||||||
doc.getElementById("outer-gobutton").click();
|
doc.getElementById("outer-gobutton").click();
|
||||||
} else {
|
} else {
|
||||||
|
@ -85,10 +85,12 @@ add_task(async function test_doorhanger_shown_on_un_with_invalid_ccnumber() {
|
|||||||
|
|
||||||
let processedPromise = listenForTestNotification("FormSubmit");
|
let processedPromise = listenForTestNotification("FormSubmit");
|
||||||
await ContentTask.spawn(browser, null, async () => {
|
await ContentTask.spawn(browser, null, async () => {
|
||||||
content.document.getElementById("form-basic-username").value =
|
content.document
|
||||||
"1234123412341234";
|
.getElementById("form-basic-username")
|
||||||
content.document.getElementById("form-basic-password").value = "411";
|
.setUserInput("1234123412341234");
|
||||||
|
content.document
|
||||||
|
.getElementById("form-basic-password")
|
||||||
|
.setUserInput("411");
|
||||||
content.document.getElementById("form-basic-submit").click();
|
content.document.getElementById("form-basic-submit").click();
|
||||||
});
|
});
|
||||||
await processedPromise;
|
await processedPromise;
|
||||||
|
@ -22,8 +22,8 @@ add_task(async function test_empty_password() {
|
|||||||
// case. This will cause the doorhanger notification to be displayed.
|
// case. This will cause the doorhanger notification to be displayed.
|
||||||
await ContentTask.spawn(browser, null, async function() {
|
await ContentTask.spawn(browser, null, async function() {
|
||||||
let doc = content.document;
|
let doc = content.document;
|
||||||
doc.getElementById("form-basic-username").value = "username";
|
doc.getElementById("form-basic-username").setUserInput("username");
|
||||||
doc.getElementById("form-basic-password").value = "pw";
|
doc.getElementById("form-basic-password").setUserInput("pw");
|
||||||
doc.getElementById("form-basic").submit();
|
doc.getElementById("form-basic").submit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -14,12 +14,14 @@
|
|||||||
add_task(async function test_edit_password() {
|
add_task(async function test_edit_password() {
|
||||||
let testCases = [
|
let testCases = [
|
||||||
{
|
{
|
||||||
|
description: "No saved logins, update password in doorhanger",
|
||||||
usernameInPage: "username",
|
usernameInPage: "username",
|
||||||
passwordInPage: "password",
|
passwordInPage: "password",
|
||||||
passwordChangedTo: "newPassword",
|
passwordChangedTo: "newPassword",
|
||||||
timesUsed: 1,
|
timesUsed: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
description: "Login is saved, update password in doorhanger",
|
||||||
usernameInPage: "username",
|
usernameInPage: "username",
|
||||||
usernameInPageExists: true,
|
usernameInPageExists: true,
|
||||||
passwordInPage: "password",
|
passwordInPage: "password",
|
||||||
@ -28,6 +30,8 @@ add_task(async function test_edit_password() {
|
|||||||
timesUsed: 2,
|
timesUsed: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
description:
|
||||||
|
"Change username in doorhanger to match saved login, update password in doorhanger",
|
||||||
usernameInPage: "username",
|
usernameInPage: "username",
|
||||||
usernameChangedTo: "newUsername",
|
usernameChangedTo: "newUsername",
|
||||||
usernameChangedToExists: true,
|
usernameChangedToExists: true,
|
||||||
@ -36,6 +40,8 @@ add_task(async function test_edit_password() {
|
|||||||
timesUsed: 2,
|
timesUsed: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
description:
|
||||||
|
"Change username in doorhanger to match saved login, dont update password in doorhanger",
|
||||||
usernameInPage: "username",
|
usernameInPage: "username",
|
||||||
usernameChangedTo: "newUsername",
|
usernameChangedTo: "newUsername",
|
||||||
usernameChangedToExists: true,
|
usernameChangedToExists: true,
|
||||||
@ -45,6 +51,8 @@ add_task(async function test_edit_password() {
|
|||||||
checkPasswordNotUpdated: true,
|
checkPasswordNotUpdated: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
description:
|
||||||
|
"Change username and password in doorhanger to match saved empty-username login",
|
||||||
usernameInPage: "newUsername",
|
usernameInPage: "newUsername",
|
||||||
usernameChangedTo: "",
|
usernameChangedTo: "",
|
||||||
usernameChangedToExists: true,
|
usernameChangedToExists: true,
|
||||||
@ -99,31 +107,22 @@ add_task(async function test_edit_password() {
|
|||||||
contentTestCase
|
contentTestCase
|
||||||
) {
|
) {
|
||||||
let doc = content.document;
|
let doc = content.document;
|
||||||
doc.getElementById("form-basic-username").value =
|
doc
|
||||||
contentTestCase.usernameInPage;
|
.getElementById("form-basic-username")
|
||||||
doc.getElementById("form-basic-password").value =
|
.setUserInput(contentTestCase.usernameInPage);
|
||||||
contentTestCase.passwordInPage;
|
doc
|
||||||
|
.getElementById("form-basic-password")
|
||||||
|
.setUserInput(contentTestCase.passwordInPage);
|
||||||
doc.getElementById("form-basic").submit();
|
doc.getElementById("form-basic").submit();
|
||||||
});
|
});
|
||||||
await promiseShown;
|
await promiseShown;
|
||||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||||
// Style flush to make sure binding is attached
|
|
||||||
notificationElement.querySelector("#password-notification-password")
|
|
||||||
.clientTop;
|
|
||||||
|
|
||||||
// Modify the username in the dialog if requested.
|
// Modify the username & password in the dialog if requested.
|
||||||
if (testCase.usernameChangedTo) {
|
await updateDoorhangerInputValues({
|
||||||
notificationElement.querySelector(
|
username: testCase.usernameChangedTo,
|
||||||
"#password-notification-username"
|
password: testCase.passwordChangedTo,
|
||||||
).value = testCase.usernameChangedTo;
|
});
|
||||||
}
|
|
||||||
|
|
||||||
// Modify the password in the dialog if requested.
|
|
||||||
if (testCase.passwordChangedTo) {
|
|
||||||
notificationElement.querySelector(
|
|
||||||
"#password-notification-password"
|
|
||||||
).value = testCase.passwordChangedTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We expect a modifyLogin notification if the final username used by the
|
// We expect a modifyLogin notification if the final username used by the
|
||||||
// dialog exists in the logins database, otherwise an addLogin one.
|
// dialog exists in the logins database, otherwise an addLogin one.
|
||||||
@ -142,8 +141,15 @@ add_task(async function test_edit_password() {
|
|||||||
"passwordmgr-storage-changed",
|
"passwordmgr-storage-changed",
|
||||||
(_, data) => data == expectedNotification
|
(_, data) => data == expectedNotification
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let promiseHidden = BrowserTestUtils.waitForEvent(
|
||||||
|
PopupNotifications.panel,
|
||||||
|
"popuphidden"
|
||||||
|
);
|
||||||
notificationElement.button.doCommand();
|
notificationElement.button.doCommand();
|
||||||
|
|
||||||
let [result] = await promiseLogin;
|
let [result] = await promiseLogin;
|
||||||
|
await promiseHidden;
|
||||||
|
|
||||||
// Check that the values in the database match the expected values.
|
// Check that the values in the database match the expected values.
|
||||||
let login = expectModifyLogin
|
let login = expectModifyLogin
|
||||||
@ -151,24 +157,27 @@ add_task(async function test_edit_password() {
|
|||||||
.QueryInterface(Ci.nsIArray)
|
.QueryInterface(Ci.nsIArray)
|
||||||
.queryElementAt(1, Ci.nsILoginInfo)
|
.queryElementAt(1, Ci.nsILoginInfo)
|
||||||
: result.QueryInterface(Ci.nsILoginInfo);
|
: result.QueryInterface(Ci.nsILoginInfo);
|
||||||
|
|
||||||
Assert.equal(
|
|
||||||
login.username,
|
|
||||||
testCase.usernameChangedTo || testCase.usernameInPage
|
|
||||||
);
|
|
||||||
Assert.equal(
|
|
||||||
login.password,
|
|
||||||
testCase.passwordChangedTo || testCase.passwordInPage
|
|
||||||
);
|
|
||||||
|
|
||||||
let meta = login.QueryInterface(Ci.nsILoginMetaInfo);
|
let meta = login.QueryInterface(Ci.nsILoginMetaInfo);
|
||||||
Assert.equal(meta.timesUsed, testCase.timesUsed);
|
|
||||||
|
|
||||||
|
let expectedLogin = {
|
||||||
|
username:
|
||||||
|
"usernameChangedTo" in testCase
|
||||||
|
? testCase.usernameChangedTo
|
||||||
|
: testCase.usernameInPage,
|
||||||
|
password:
|
||||||
|
"passwordChangedTo" in testCase
|
||||||
|
? testCase.passwordChangedTo
|
||||||
|
: testCase.passwordInPage,
|
||||||
|
timesUsed: testCase.timesUsed,
|
||||||
|
};
|
||||||
// Check that the password was not updated if the user is empty
|
// Check that the password was not updated if the user is empty
|
||||||
if (testCase.checkPasswordNotUpdated) {
|
if (testCase.checkPasswordNotUpdated) {
|
||||||
Assert.ok(meta.timeLastUsed > meta.timeCreated);
|
expectedLogin.usedSince = meta.timeCreated;
|
||||||
Assert.ok(meta.timeCreated == meta.timePasswordChanged);
|
expectedLogin.timeCreated = meta.timePasswordChanged;
|
||||||
}
|
}
|
||||||
|
verifyLogins([expectedLogin]);
|
||||||
|
|
||||||
|
await cleanupDoorhanger();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -93,55 +93,48 @@ add_task(async function test_save_change() {
|
|||||||
async function(browser) {
|
async function(browser) {
|
||||||
// Submit the form in the content page with the credentials from the test
|
// Submit the form in the content page with the credentials from the test
|
||||||
// case. This will cause the doorhanger notification to be displayed.
|
// case. This will cause the doorhanger notification to be displayed.
|
||||||
let promiseShown = BrowserTestUtils.waitForEvent(
|
|
||||||
PopupNotifications.panel,
|
|
||||||
"popupshown",
|
|
||||||
event => event.target == PopupNotifications.panel
|
|
||||||
);
|
|
||||||
await ContentTask.spawn(browser, [username, password], async function([
|
await ContentTask.spawn(browser, [username, password], async function([
|
||||||
contentUsername,
|
contentUsername,
|
||||||
contentPassword,
|
contentPassword,
|
||||||
]) {
|
]) {
|
||||||
let doc = content.document;
|
let doc = content.document;
|
||||||
doc.getElementById("form-basic-username").value = contentUsername;
|
doc
|
||||||
doc.getElementById("form-basic-password").value = contentPassword;
|
.getElementById("form-basic-username")
|
||||||
|
.setUserInput(contentUsername);
|
||||||
|
doc
|
||||||
|
.getElementById("form-basic-password")
|
||||||
|
.setUserInput(contentPassword);
|
||||||
doc.getElementById("form-basic").submit();
|
doc.getElementById("form-basic").submit();
|
||||||
});
|
});
|
||||||
await promiseShown;
|
|
||||||
let notif = PopupNotifications.getNotification("password", browser);
|
|
||||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
|
||||||
// Style flush to make sure binding is attached
|
|
||||||
notificationElement.querySelector("#password-notification-password")
|
|
||||||
.clientTop;
|
|
||||||
|
|
||||||
// Check the actual content of the popup notification.
|
|
||||||
Assert.equal(
|
|
||||||
notificationElement.querySelector("#password-notification-username")
|
|
||||||
.value,
|
|
||||||
username
|
|
||||||
);
|
|
||||||
Assert.equal(
|
|
||||||
notificationElement.querySelector("#password-notification-password")
|
|
||||||
.value,
|
|
||||||
password
|
|
||||||
);
|
|
||||||
|
|
||||||
// Simulate the action on the notification to request the login to be
|
// Simulate the action on the notification to request the login to be
|
||||||
// saved, and wait for the data to be updated or saved based on the type
|
// saved, and wait for the data to be updated or saved based on the type
|
||||||
// of operation we expect.
|
// of operation we expect.
|
||||||
let expectedNotification;
|
let expectedNotification, expectedDoorhanger;
|
||||||
if (oldPassword !== undefined && oldUsername !== undefined) {
|
if (oldPassword !== undefined && oldUsername !== undefined) {
|
||||||
expectedNotification = "addLogin";
|
expectedNotification = "addLogin";
|
||||||
|
expectedDoorhanger = "password-save";
|
||||||
} else if (oldPassword !== undefined) {
|
} else if (oldPassword !== undefined) {
|
||||||
expectedNotification = "modifyLogin";
|
expectedNotification = "modifyLogin";
|
||||||
|
expectedDoorhanger = "password-change";
|
||||||
} else {
|
} else {
|
||||||
expectedNotification = "addLogin";
|
expectedNotification = "addLogin";
|
||||||
|
expectedDoorhanger = "password-save";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let notif = getCaptureDoorhanger(
|
||||||
|
expectedDoorhanger,
|
||||||
|
PopupNotifications,
|
||||||
|
browser
|
||||||
|
);
|
||||||
|
// Check the actual content of the popup notification.
|
||||||
|
await checkDoorhangerUsernamePassword(username, password);
|
||||||
|
|
||||||
let promiseLogin = TestUtils.topicObserved(
|
let promiseLogin = TestUtils.topicObserved(
|
||||||
"passwordmgr-storage-changed",
|
"passwordmgr-storage-changed",
|
||||||
(_, data) => data == expectedNotification
|
(_, data) => data == expectedNotification
|
||||||
);
|
);
|
||||||
notificationElement.button.doCommand();
|
await clickDoorhangerButton(notif, REMEMBER_BUTTON);
|
||||||
await promiseLogin;
|
await promiseLogin;
|
||||||
await cleanupDoorhanger(notif); // clean slate for the next test
|
await cleanupDoorhanger(notif); // clean slate for the next test
|
||||||
|
|
||||||
|
@ -18,18 +18,17 @@ add_task(async function test_toggle_password() {
|
|||||||
async function(browser) {
|
async function(browser) {
|
||||||
// Submit the form in the content page with the credentials from the test
|
// Submit the form in the content page with the credentials from the test
|
||||||
// case. This will cause the doorhanger notification to be displayed.
|
// case. This will cause the doorhanger notification to be displayed.
|
||||||
let promiseShown = BrowserTestUtils.waitForEvent(
|
|
||||||
PopupNotifications.panel,
|
|
||||||
"popupshown",
|
|
||||||
event => event.target == PopupNotifications.panel
|
|
||||||
);
|
|
||||||
await ContentTask.spawn(browser, null, async function() {
|
await ContentTask.spawn(browser, null, async function() {
|
||||||
let doc = content.document;
|
let doc = content.document;
|
||||||
doc.getElementById("form-basic-username").value = "username";
|
doc.getElementById("form-basic-username").setUserInput("username");
|
||||||
doc.getElementById("form-basic-password").value = "pw";
|
doc.getElementById("form-basic-password").setUserInput("pw");
|
||||||
doc.getElementById("form-basic").submit();
|
doc.getElementById("form-basic").submit();
|
||||||
});
|
});
|
||||||
await promiseShown;
|
let notif = await getCaptureDoorhangerThatMayOpen("password-save");
|
||||||
|
ok(notif, "got notification popup");
|
||||||
|
|
||||||
|
// Check the actual content of the popup notification.
|
||||||
|
await checkDoorhangerUsernamePassword("username", "pw");
|
||||||
|
|
||||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||||
let passwordTextbox = notificationElement.querySelector(
|
let passwordTextbox = notificationElement.querySelector(
|
||||||
@ -40,7 +39,7 @@ add_task(async function test_toggle_password() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
await EventUtils.synthesizeMouseAtCenter(toggleCheckbox, {});
|
await EventUtils.synthesizeMouseAtCenter(toggleCheckbox, {});
|
||||||
Assert.ok(toggleCheckbox.checked);
|
Assert.ok(toggleCheckbox.checked, "Toggle is checked");
|
||||||
Assert.equal(
|
Assert.equal(
|
||||||
passwordTextbox.type,
|
passwordTextbox.type,
|
||||||
"text",
|
"text",
|
||||||
@ -54,6 +53,7 @@ add_task(async function test_toggle_password() {
|
|||||||
"password",
|
"password",
|
||||||
"Password textbox changed to * text"
|
"Password textbox changed to * text"
|
||||||
);
|
);
|
||||||
|
await cleanupDoorhanger(notif);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -72,21 +72,19 @@ add_task(async function test_checkbox_disabled_if_has_master_password() {
|
|||||||
async function(browser) {
|
async function(browser) {
|
||||||
// Submit the form in the content page with the credentials from the test
|
// Submit the form in the content page with the credentials from the test
|
||||||
// case. This will cause the doorhanger notification to be displayed.
|
// case. This will cause the doorhanger notification to be displayed.
|
||||||
let promiseShown = BrowserTestUtils.waitForEvent(
|
|
||||||
PopupNotifications.panel,
|
|
||||||
"popupshown",
|
|
||||||
event => event.target == PopupNotifications.panel
|
|
||||||
);
|
|
||||||
|
|
||||||
LoginTestUtils.masterPassword.enable();
|
LoginTestUtils.masterPassword.enable();
|
||||||
|
|
||||||
await ContentTask.spawn(browser, null, async function() {
|
await ContentTask.spawn(browser, null, async function() {
|
||||||
let doc = content.document;
|
let doc = content.document;
|
||||||
doc.getElementById("form-basic-username").value = "username";
|
doc.getElementById("form-basic-username").setUserInput("username");
|
||||||
doc.getElementById("form-basic-password").value = "pass";
|
doc.getElementById("form-basic-password").setUserInput("pass");
|
||||||
doc.getElementById("form-basic").submit();
|
doc.getElementById("form-basic").submit();
|
||||||
});
|
});
|
||||||
await promiseShown;
|
let notif = await getCaptureDoorhangerThatMayOpen("password-save");
|
||||||
|
ok(notif, "got notification popup");
|
||||||
|
|
||||||
|
// Check the actual content of the popup notification.
|
||||||
|
await checkDoorhangerUsernamePassword("username", "pass");
|
||||||
|
|
||||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||||
let passwordTextbox = notificationElement.querySelector(
|
let passwordTextbox = notificationElement.querySelector(
|
||||||
@ -105,6 +103,7 @@ add_task(async function test_checkbox_disabled_if_has_master_password() {
|
|||||||
toggleCheckbox.getAttribute("hidden"),
|
toggleCheckbox.getAttribute("hidden"),
|
||||||
"checkbox is hidden when master password is set"
|
"checkbox is hidden when master password is set"
|
||||||
);
|
);
|
||||||
|
await cleanupDoorhanger(notif);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -94,8 +94,10 @@ add_task(async function test_edit_username() {
|
|||||||
testCase.usernameInPage,
|
testCase.usernameInPage,
|
||||||
async function(usernameInPage) {
|
async function(usernameInPage) {
|
||||||
let doc = content.document;
|
let doc = content.document;
|
||||||
doc.getElementById("form-basic-username").value = usernameInPage;
|
doc
|
||||||
doc.getElementById("form-basic-password").value = "password";
|
.getElementById("form-basic-username")
|
||||||
|
.setUserInput(usernameInPage);
|
||||||
|
doc.getElementById("form-basic-password").setUserInput("password");
|
||||||
doc.getElementById("form-basic").submit();
|
doc.getElementById("form-basic").submit();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -107,9 +109,9 @@ add_task(async function test_edit_username() {
|
|||||||
|
|
||||||
// Modify the username in the dialog if requested.
|
// Modify the username in the dialog if requested.
|
||||||
if (testCase.usernameChangedTo) {
|
if (testCase.usernameChangedTo) {
|
||||||
notificationElement.querySelector(
|
await updateDoorhangerInputValues({
|
||||||
"#password-notification-username"
|
username: testCase.usernameChangedTo,
|
||||||
).value = testCase.usernameChangedTo;
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// We expect a modifyLogin notification if the final username used by the
|
// We expect a modifyLogin notification if the final username used by the
|
||||||
@ -128,8 +130,13 @@ add_task(async function test_edit_username() {
|
|||||||
"passwordmgr-storage-changed",
|
"passwordmgr-storage-changed",
|
||||||
(_, data) => data == expectedNotification
|
(_, data) => data == expectedNotification
|
||||||
);
|
);
|
||||||
|
let promiseHidden = BrowserTestUtils.waitForEvent(
|
||||||
|
PopupNotifications.panel,
|
||||||
|
"popuphidden"
|
||||||
|
);
|
||||||
notificationElement.button.doCommand();
|
notificationElement.button.doCommand();
|
||||||
let [result] = await promiseLogin;
|
let [result] = await promiseLogin;
|
||||||
|
await promiseHidden;
|
||||||
|
|
||||||
// Check that the values in the database match the expected values.
|
// Check that the values in the database match the expected values.
|
||||||
let login = expectModifyLogin
|
let login = expectModifyLogin
|
||||||
|
@ -6,10 +6,12 @@
|
|||||||
|
|
||||||
async function fillTestPage(aBrowser) {
|
async function fillTestPage(aBrowser) {
|
||||||
await ContentTask.spawn(aBrowser, null, async function() {
|
await ContentTask.spawn(aBrowser, null, async function() {
|
||||||
content.document.getElementById("form-basic-username").value =
|
content.document
|
||||||
"my_username";
|
.getElementById("form-basic-username")
|
||||||
content.document.getElementById("form-basic-password").value =
|
.setUserInput("my_username");
|
||||||
"my_password";
|
content.document
|
||||||
|
.getElementById("form-basic-password")
|
||||||
|
.setUserInput("my_password");
|
||||||
});
|
});
|
||||||
info("fields filled");
|
info("fields filled");
|
||||||
}
|
}
|
||||||
|
@ -88,6 +88,9 @@ function verifyLogins(expectedLogins = []) {
|
|||||||
"Check timePasswordChanged"
|
"Check timePasswordChanged"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (typeof expected.timeCreated !== "undefined") {
|
||||||
|
is(login.timeCreated, expected.timeCreated, "Check timeCreated");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return allLogins;
|
return allLogins;
|
||||||
@ -108,7 +111,11 @@ async function submitFormAndGetResults(
|
|||||||
selectorValues,
|
selectorValues,
|
||||||
responseSelectors
|
responseSelectors
|
||||||
) {
|
) {
|
||||||
function contentSubmitForm([contentFormAction, contentSelectorValues]) {
|
async function contentSubmitForm([contentFormAction, contentSelectorValues]) {
|
||||||
|
const { WrapPrivileged } = ChromeUtils.import(
|
||||||
|
"resource://specialpowers/WrapPrivileged.jsm",
|
||||||
|
this
|
||||||
|
);
|
||||||
let doc = content.document;
|
let doc = content.document;
|
||||||
let form = doc.querySelector("form");
|
let form = doc.querySelector("form");
|
||||||
if (contentFormAction) {
|
if (contentFormAction) {
|
||||||
@ -116,9 +123,20 @@ async function submitFormAndGetResults(
|
|||||||
}
|
}
|
||||||
for (let [sel, value] of Object.entries(contentSelectorValues)) {
|
for (let [sel, value] of Object.entries(contentSelectorValues)) {
|
||||||
try {
|
try {
|
||||||
doc.querySelector(sel).setUserInput(value);
|
let field = doc.querySelector(sel);
|
||||||
|
let gotInput = ContentTaskUtils.waitForEvent(
|
||||||
|
field,
|
||||||
|
"input",
|
||||||
|
"Got input event on " + sel
|
||||||
|
);
|
||||||
|
// we don't get an input event if the new value == the old
|
||||||
|
field.value = "###";
|
||||||
|
WrapPrivileged.wrap(field).setUserInput(value);
|
||||||
|
await gotInput;
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
throw new Error(`submitForm: Couldn't set value of field at: ${sel}`);
|
throw new Error(
|
||||||
|
`submitForm: Couldn't set value of field at: ${sel}: ${ex.message}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
form.submit();
|
form.submit();
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
userField.value = "notifyu1";
|
SpecialPowers.wrap(userField).setUserInput("notifyu1");
|
||||||
passField.value = "notifyp1";
|
SpecialPowers.wrap(passField).setUserInput("notifyp1");
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
passField.value = "notifyp1";
|
SpecialPowers.wrap(passField).setUserInput("notifyp1");
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
function submitForm() {
|
function submitForm() {
|
||||||
// Get the password from the query string (exclude '?').
|
// Get the password from the query string (exclude '?').
|
||||||
let [username, password] = window.location.search.substring(1).split("|");
|
let [username, password] = window.location.search.substring(1).split("|");
|
||||||
userField.value = username;
|
SpecialPowers.wrap(userField).setUserInput(username);
|
||||||
passField.value = password;
|
SpecialPowers.wrap(passField).setUserInput(password);
|
||||||
form.submit();
|
form.submit();
|
||||||
window.opener.formSubmitted();
|
window.opener.formSubmitted();
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
userField.value = "notifyu1";
|
SpecialPowers.wrap(userField).setUserInput("notifyu1");
|
||||||
passField.value = "notifyp1";
|
SpecialPowers.wrap(passField).setUserInput("notifyp1");
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
pass.value = "notifyp1";
|
SpecialPowers.wrap(pass).setUserInput("notifyp1");
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
userField.value = "notifyu1";
|
SpecialPowers.wrap(userField).setUserInput("notifyu1");
|
||||||
passField.value = "notifyp1";
|
SpecialPowers.wrap(passField).setUserInput("notifyp1");
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
userField.value = "notifyu1";
|
SpecialPowers.wrap(userField).setUserInput("notifyu1");
|
||||||
passField.value = "notifyp1";
|
SpecialPowers.wrap(passField).setUserInput("notifyp1");
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
userField.value = "notifyu1";
|
SpecialPowers.wrap(userField).setUserInput("notifyu1");
|
||||||
passField.value = "notifyp1";
|
SpecialPowers.wrap(passField).setUserInput("notifyp1");
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
userField.value = "notifyu1";
|
SpecialPowers.wrap(userField).setUserInput("notifyu1");
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
passField.value = "notifyp1";
|
SpecialPowers.wrap(passField).setUserInput("notifyp1");
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
userField.value = "notifyu1";
|
SpecialPowers.wrap(userField).setUserInput("notifyu1");
|
||||||
passField.value = "pass2";
|
SpecialPowers.wrap(passField).setUserInput("pass2");
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
userField.value = "";
|
SpecialPowers.wrap(userField).setUserInput("");
|
||||||
passField.value = "pass2";
|
SpecialPowers.wrap(passField).setUserInput("pass2");
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
function submitForm() {
|
function submitForm() {
|
||||||
passField.value = "pass2";
|
SpecialPowers.wrap(passField).setUserInput("pass2");
|
||||||
passConfirmField.value = "pass2";
|
SpecialPowers.wrap(passConfirmField).setUserInput("pass2");
|
||||||
|
|
||||||
form.submit();
|
form.submit();
|
||||||
}
|
}
|
||||||
|
@ -113,6 +113,57 @@ function getIframeBrowsingContext(window, iframeNumber = 0) {
|
|||||||
return SpecialPowers.unwrap(bc.getChildren()[iframeNumber]);
|
return SpecialPowers.unwrap(bc.getChildren()[iframeNumber]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set input values via setUserInput to emulate user input
|
||||||
|
* and distinguish them from declarative or script-assigned values
|
||||||
|
*/
|
||||||
|
function setUserInputValues(parentNode, selectorValues) {
|
||||||
|
for (let [selector, newValue] of Object.entries(selectorValues)) {
|
||||||
|
info(`setUserInputValues, selector: ${selector}`);
|
||||||
|
try {
|
||||||
|
let field = SpecialPowers.wrap(parentNode.querySelector(selector));
|
||||||
|
if (field.value == newValue) {
|
||||||
|
// we don't get an input event if the new value == the old
|
||||||
|
field.value += "#";
|
||||||
|
}
|
||||||
|
field.setUserInput(newValue);
|
||||||
|
} catch (ex) {
|
||||||
|
info(ex.message);
|
||||||
|
info(ex.stack);
|
||||||
|
ok(
|
||||||
|
false,
|
||||||
|
`setUserInputValues: Couldn't set value of field: ${ex.message}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Function} [aFilterFn = undefined] Function to filter out irrelevant submissions.
|
||||||
|
* @return {Promise} resolving when a relevant form submission was processed.
|
||||||
|
*/
|
||||||
|
function getSubmitMessage(aFilterFn = undefined) {
|
||||||
|
info("getSubmitMessage");
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
PWMGR_COMMON_PARENT.addMessageListener(
|
||||||
|
"formSubmissionProcessed",
|
||||||
|
function processed(...args) {
|
||||||
|
if (aFilterFn && !aFilterFn(...args)) {
|
||||||
|
// This submission isn't the one we're waiting for.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
info("got formSubmissionProcessed");
|
||||||
|
PWMGR_COMMON_PARENT.removeMessageListener(
|
||||||
|
"formSubmissionProcessed",
|
||||||
|
processed
|
||||||
|
);
|
||||||
|
resolve(...args);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for expected username/password in form.
|
* Check for expected username/password in form.
|
||||||
* @see `checkForm` below for a similar function.
|
* @see `checkForm` below for a similar function.
|
||||||
|
@ -36,9 +36,9 @@ function startTest() {
|
|||||||
|
|
||||||
// Fill in the username and password fields, for account creation.
|
// Fill in the username and password fields, for account creation.
|
||||||
// Form 1
|
// Form 1
|
||||||
$_(1, "uname").value = "newuser1";
|
SpecialPowers.wrap($_(1, "uname")).setUserInput("newuser1");
|
||||||
$_(1, "pword").value = "newpass1";
|
SpecialPowers.wrap($_(1, "pword")).setUserInput("newpass1");
|
||||||
$_(1, "qword").value = "newpass1";
|
SpecialPowers.wrap($_(1, "qword")).setUserInput("newpass1");
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
var button = getFormSubmitButton(1);
|
var button = getFormSubmitButton(1);
|
||||||
|
@ -46,7 +46,10 @@ const DEFAULT_ORIGIN = "http://mochi.test:8888";
|
|||||||
const TESTCASES = [
|
const TESTCASES = [
|
||||||
{
|
{
|
||||||
// Inputs
|
// Inputs
|
||||||
document: `<input type=password value="pass1">`,
|
document: `<input type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"[type=password]": "pass1",
|
||||||
|
},
|
||||||
inputIndexForFormLike: 0,
|
inputIndexForFormLike: 0,
|
||||||
|
|
||||||
// Expected outputs similar to PasswordManager:onFormSubmit
|
// Expected outputs similar to PasswordManager:onFormSubmit
|
||||||
@ -57,8 +60,12 @@ const TESTCASES = [
|
|||||||
oldPasswordFieldValue: null,
|
oldPasswordFieldValue: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
document: `<input value="user1">
|
document: `<input id="u1" value="">
|
||||||
<input type=password value="pass1">`,
|
<input type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"#u1": "user1",
|
||||||
|
"[type=password]": "pass1",
|
||||||
|
},
|
||||||
inputIndexForFormLike: 0,
|
inputIndexForFormLike: 0,
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -67,8 +74,12 @@ const TESTCASES = [
|
|||||||
oldPasswordFieldValue: null,
|
oldPasswordFieldValue: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
document: `<input value="user1">
|
document: `<input id="u1" value="">
|
||||||
<input type=password value="pass1">`,
|
<input type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"#u1": "user1",
|
||||||
|
"[type=password]": "pass1",
|
||||||
|
},
|
||||||
inputIndexForFormLike: 1,
|
inputIndexForFormLike: 1,
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -77,9 +88,14 @@ const TESTCASES = [
|
|||||||
oldPasswordFieldValue: null,
|
oldPasswordFieldValue: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
document: `<input value="user1">
|
document: `<input id="u1" value="">
|
||||||
<input type=password value="pass1">
|
<input id="p1" type=password value="">
|
||||||
<input type=password value="pass2">`,
|
<input id="p2" type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"#u1": "user1",
|
||||||
|
"#p1": "pass1",
|
||||||
|
"#p2": "pass2",
|
||||||
|
},
|
||||||
inputIndexForFormLike: 2,
|
inputIndexForFormLike: 2,
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -88,10 +104,16 @@ const TESTCASES = [
|
|||||||
oldPasswordFieldValue: "pass1",
|
oldPasswordFieldValue: "pass1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
document: `<input value="user1">
|
document: `<input id="u1" value="">
|
||||||
<input type=password value="pass1">
|
<input id="p1" type=password value="">
|
||||||
<input type=password value="pass2">
|
<input id="p2" type=password value="">
|
||||||
<input type=password value="pass2">`,
|
<input id="p3" type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"#u1": "user1",
|
||||||
|
"#p1": "pass1",
|
||||||
|
"#p2": "pass2",
|
||||||
|
"#p3": "pass2",
|
||||||
|
},
|
||||||
inputIndexForFormLike: 3,
|
inputIndexForFormLike: 3,
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -100,13 +122,20 @@ const TESTCASES = [
|
|||||||
oldPasswordFieldValue: "pass1",
|
oldPasswordFieldValue: "pass1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
document: `<input value="user1">
|
document: `<input id="u1" value="">
|
||||||
<input type=password value="user2" form="form1">
|
<input id="p1" type=password value="" form="form1">
|
||||||
<input type=password value="pass1">
|
<input id="p2" type=password value="">
|
||||||
<form id="form1">
|
<form id="form1">
|
||||||
<input value="user3">
|
<input id="u2" value="">
|
||||||
<input type=password value="pass2">
|
<input id="p3" type=password value="">
|
||||||
</form>`,
|
</form>`,
|
||||||
|
selectorValues: {
|
||||||
|
"#u1": "user1",
|
||||||
|
"#p1": "user2",
|
||||||
|
"#p2": "pass1",
|
||||||
|
"#u2": "user3",
|
||||||
|
"#p3": "pass2",
|
||||||
|
},
|
||||||
inputIndexForFormLike: 2,
|
inputIndexForFormLike: 2,
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -116,10 +145,16 @@ const TESTCASES = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
document: `<!-- recipe field override -->
|
document: `<!-- recipe field override -->
|
||||||
<input name="recipeuname" value="username from recipe">
|
<input name="recipeuname" value="">
|
||||||
<input value="default field username">
|
<input id="u1" value="">
|
||||||
<input type=password value="pass1">
|
<input id="p1" type=password value="">
|
||||||
<input name="recipepword" type=password value="pass2">`,
|
<input name="recipepword" type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"[name='recipeuname']": "username from recipe",
|
||||||
|
"#u1": "default field username",
|
||||||
|
"#p1": "pass1",
|
||||||
|
"[name='recipepword']": "pass2",
|
||||||
|
},
|
||||||
inputIndexForFormLike: 2,
|
inputIndexForFormLike: 2,
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -129,36 +164,30 @@ const TESTCASES = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function getSubmitMessage() {
|
|
||||||
info("getSubmitMessage");
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
PWMGR_COMMON_PARENT.addMessageListener("formSubmissionProcessed", function processed(...args) {
|
|
||||||
info("got formSubmissionProcessed");
|
|
||||||
PWMGR_COMMON_PARENT.removeMessageListener("formSubmissionProcessed", processed);
|
|
||||||
resolve(...args);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
add_task(async function test() {
|
add_task(async function test() {
|
||||||
let count = 0;
|
let count = 0;
|
||||||
let loginFrame = document.getElementById("loginFrame");
|
let loginFrame = document.getElementById("loginFrame");
|
||||||
|
|
||||||
for (let tc of TESTCASES) {
|
for (let tc of TESTCASES) {
|
||||||
let frameDoc = loginFrame.contentWindow.document;
|
let frameDoc = SpecialPowers.wrap(loginFrame.contentWindow).document;
|
||||||
info("Starting testcase: " + JSON.stringify(tc));
|
info("Starting testcase: " + JSON.stringify(tc));
|
||||||
|
|
||||||
|
let formProcessed = promiseFormsProcessed();
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
// eslint-disable-next-line no-unsanitized/property
|
||||||
frameDoc.documentElement.innerHTML = tc.document;
|
frameDoc.documentElement.innerHTML = tc.document;
|
||||||
|
await formProcessed;
|
||||||
|
// We eliminate no user input as a reason for not capturing by modifying the value
|
||||||
|
setUserInputValues(frameDoc.documentElement, tc.selectorValues);
|
||||||
|
|
||||||
let inputForFormLike = frameDoc.querySelectorAll("input")[tc.inputIndexForFormLike];
|
let inputForFormLike = frameDoc.querySelectorAll("input")[tc.inputIndexForFormLike];
|
||||||
|
|
||||||
let formLike = LoginFormFactory.createFromField(inputForFormLike);
|
let formLike = LoginFormFactory.createFromField(inputForFormLike);
|
||||||
|
|
||||||
info("Calling _onFormSubmit with FormLike");
|
info("Calling _onFormSubmit with FormLike");
|
||||||
let processedPromise = getSubmitMessage();
|
let submitProcessed = getSubmitMessage();
|
||||||
LoginManagerChild.forWindow(frameDoc.defaultView)._onFormSubmit(formLike);
|
LoginManagerChild.forWindow(frameDoc.defaultView)._onFormSubmit(formLike);
|
||||||
|
|
||||||
let submittedResult = await processedPromise;
|
let submittedResult = await submitProcessed;
|
||||||
|
|
||||||
// Check data sent via PasswordManager:onFormSubmit
|
// Check data sent via PasswordManager:onFormSubmit
|
||||||
is(submittedResult.origin, tc.origin, "Check origin");
|
is(submittedResult.origin, tc.origin, "Check origin");
|
||||||
|
@ -47,7 +47,10 @@ const SCRIPTS = {
|
|||||||
const TESTCASES = [
|
const TESTCASES = [
|
||||||
{
|
{
|
||||||
// Inputs
|
// Inputs
|
||||||
document: `<input type=password value="pass1">`,
|
document: `<input type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"[type=password]": "pass1",
|
||||||
|
},
|
||||||
|
|
||||||
// Expected outputs similar to PasswordManager:onFormSubmit
|
// Expected outputs similar to PasswordManager:onFormSubmit
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
@ -57,8 +60,12 @@ const TESTCASES = [
|
|||||||
oldPasswordFieldValue: null,
|
oldPasswordFieldValue: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
document: `<input value="user1">
|
document: `<input id="u1" value="">
|
||||||
<input type=password value="pass1">`,
|
<input type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"#u1": "user1",
|
||||||
|
"[type=password]": "pass1",
|
||||||
|
},
|
||||||
|
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -67,9 +74,14 @@ const TESTCASES = [
|
|||||||
oldPasswordFieldValue: null,
|
oldPasswordFieldValue: null,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
document: `<input value="user1">
|
document: `<input id="u1" value="">
|
||||||
<input type=password value="pass1">
|
<input id="p1" type=password value="">
|
||||||
<input type=password value="pass2">`,
|
<input id="p2" type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"#u1": "user1",
|
||||||
|
"#p1": "pass1",
|
||||||
|
"#p2": "pass2",
|
||||||
|
},
|
||||||
|
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -78,10 +90,16 @@ const TESTCASES = [
|
|||||||
oldPasswordFieldValue: "pass1",
|
oldPasswordFieldValue: "pass1",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
document: `<input value="user1">
|
document: `<input id="u1" value="">
|
||||||
<input type=password value="pass1">
|
<input id="p1" type=password value="">
|
||||||
<input type=password value="pass2">
|
<input id="p2" type=password value="">
|
||||||
<input type=password value="pass2">`,
|
<input id="p3" type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"#u1": "user1",
|
||||||
|
"#p1": "pass1",
|
||||||
|
"#p2": "pass2",
|
||||||
|
"#p3": "pass2",
|
||||||
|
},
|
||||||
|
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -94,13 +112,20 @@ const TESTCASES = [
|
|||||||
// one FormLike's password fields with a magic "ignore-form-submission"
|
// one FormLike's password fields with a magic "ignore-form-submission"
|
||||||
// value so we can just focus on the other form. We then repeat the testcase
|
// value so we can just focus on the other form. We then repeat the testcase
|
||||||
// below with the other FormLike ignored.
|
// below with the other FormLike ignored.
|
||||||
document: `<input value="user1">
|
document: `<input id="u1" value="">
|
||||||
<input type=password value="ignore-form-submission" form="form1">
|
<input type=password id="p1" value="" form="form1">
|
||||||
<input type=password value="pass1">
|
<input type=password id="p2" value="">
|
||||||
<form id="form1">
|
<form id="form1">
|
||||||
<input value="user3">
|
<input id="u2" value="">
|
||||||
<input type=password value="ignore-form-submission">
|
<input id="p3" type=password value="">
|
||||||
</form>`,
|
</form>`,
|
||||||
|
selectorValues: {
|
||||||
|
"#u1": "user1",
|
||||||
|
"#p1": "ignore-form-submission",
|
||||||
|
"#p2": "pass1",
|
||||||
|
"#u2": "user3",
|
||||||
|
"#p3": "ignore-form-submission",
|
||||||
|
},
|
||||||
|
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -109,13 +134,20 @@ const TESTCASES = [
|
|||||||
oldPasswordFieldValue: null,
|
oldPasswordFieldValue: null,
|
||||||
},
|
},
|
||||||
{ // Same as above but with the other form ignored.
|
{ // Same as above but with the other form ignored.
|
||||||
document: `<input value="user1">
|
document: `<input id="u1" value="">
|
||||||
<input type=password value="pass2" form="form1">
|
<input id="p1" type=password value="" form="form1">
|
||||||
<input type=password value="ignore-form-submission">
|
<input id="p2" type=password value="">
|
||||||
<form id="form1">
|
<form id="form1">
|
||||||
<input value="user3">
|
<input id="u2" value="">
|
||||||
<input type=password value="pass2">
|
<input id="p3" type=password value="">
|
||||||
</form>`,
|
</form>`,
|
||||||
|
selectorValues: {
|
||||||
|
"#u1": "user1",
|
||||||
|
"#p1": "pass2",
|
||||||
|
"#p2": "ignore-form-submission",
|
||||||
|
"#u2": "user3",
|
||||||
|
"#p3": "pass2",
|
||||||
|
},
|
||||||
|
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -125,10 +157,16 @@ const TESTCASES = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
document: `<!-- recipe field override -->
|
document: `<!-- recipe field override -->
|
||||||
<input name="recipeuname" value="username from recipe">
|
<input name="recipeuname" value="">
|
||||||
<input value="default field username">
|
<input id="u1" value="">
|
||||||
<input type=password value="pass1">
|
<input id="p1" type=password value="">
|
||||||
<input name="recipepword" type=password value="pass2">`,
|
<input name="recipepword" type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"[name='recipeuname']": "username from recipe",
|
||||||
|
"#u1": "default field username",
|
||||||
|
"#p1": "pass1",
|
||||||
|
"[name='recipepword']": "pass2",
|
||||||
|
},
|
||||||
|
|
||||||
origin: DEFAULT_ORIGIN,
|
origin: DEFAULT_ORIGIN,
|
||||||
formActionOrigin: DEFAULT_ORIGIN,
|
formActionOrigin: DEFAULT_ORIGIN,
|
||||||
@ -138,26 +176,6 @@ const TESTCASES = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {Function} [aFilterFn = undefined] Function to filter out irrelevant submissions.
|
|
||||||
* @return {Promise} resolving when a relevant form submission was processed.
|
|
||||||
*/
|
|
||||||
function getSubmitMessage(aFilterFn = undefined) {
|
|
||||||
info("getSubmitMessage");
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
PWMGR_COMMON_PARENT.addMessageListener("formSubmissionProcessed", function processed(...args) {
|
|
||||||
if (aFilterFn && !aFilterFn(...args)) {
|
|
||||||
// This submission isn't the one we're waiting for.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
info("got formSubmissionProcessed");
|
|
||||||
PWMGR_COMMON_PARENT.removeMessageListener("formSubmissionProcessed", processed);
|
|
||||||
resolve(...args);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function filterFormSubmissions(data) {
|
function filterFormSubmissions(data) {
|
||||||
return data.newPasswordField.value != "ignore-form-submission";
|
return data.newPasswordField.value != "ignore-form-submission";
|
||||||
}
|
}
|
||||||
@ -189,15 +207,20 @@ add_task(async function test() {
|
|||||||
testDoc = "<form>" + testDoc + "</form>";
|
testDoc = "<form>" + testDoc + "</form>";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let formProcessed = promiseFormsProcessed();
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
// eslint-disable-next-line no-unsanitized/property
|
||||||
frameDoc.documentElement.innerHTML = testDoc;
|
frameDoc.documentElement.innerHTML = testDoc;
|
||||||
// Wait for the form to be processed before trying to submit.
|
await formProcessed;
|
||||||
await promiseFormsProcessed();
|
// We eliminate no user input as a reason for not capturing by modifying the value
|
||||||
let processedPromise = getSubmitMessage(filterFormSubmissions);
|
setUserInputValues(frameDoc.documentElement, tc.selectorValues)
|
||||||
|
|
||||||
|
let submitProcessed = getSubmitMessage(filterFormSubmissions);
|
||||||
info("Running " + scriptName + " script to cause a submission");
|
info("Running " + scriptName + " script to cause a submission");
|
||||||
frameDoc.defaultView.eval(SCRIPTS[scriptName]);
|
frameDoc.defaultView.eval(SCRIPTS[scriptName]);
|
||||||
|
|
||||||
let submittedResult = await processedPromise;
|
info("Waiting for formSubmissionProcsssed message");
|
||||||
|
let submittedResult = await submitProcessed;
|
||||||
|
info("Got for formSubmissionProcsssed message");
|
||||||
|
|
||||||
// Check data sent via PasswordManager:onFormSubmit
|
// Check data sent via PasswordManager:onFormSubmit
|
||||||
is(submittedResult.origin, tc.origin, "Check origin");
|
is(submittedResult.origin, tc.origin, "Check origin");
|
||||||
|
@ -53,22 +53,34 @@ const TESTCASES = [
|
|||||||
// Begin test cases that shouldn't trigger capture.
|
// Begin test cases that shouldn't trigger capture.
|
||||||
{
|
{
|
||||||
// Empty password field in a form
|
// Empty password field in a form
|
||||||
document: `<form><input type=password value=""></form>`,
|
document: `<form><input type=password value="xxx"></form>`,
|
||||||
|
selectorValues: {
|
||||||
|
"[type=password]": "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Empty password field
|
// Empty password field
|
||||||
document: `<input type=password value="">`,
|
document: `<input type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"[type=password]": "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Test with an input that would normally be captured but with SCRIPTS that
|
// Test with an input that would normally be captured but with SCRIPTS that
|
||||||
// shouldn't trigger capture.
|
// shouldn't trigger capture.
|
||||||
document: `<input type=password value="pass2">`,
|
document: `<input type=password value="">`,
|
||||||
|
selectorValues: {
|
||||||
|
"[type=password]": "pass2",
|
||||||
|
},
|
||||||
wouldCapture: true,
|
wouldCapture: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// Test with an input that would normally be captured but with SCRIPTS that
|
// Test with an input that would normally be captured but with SCRIPTS that
|
||||||
// shouldn't trigger capture.
|
// shouldn't trigger capture.
|
||||||
document: `<form><input type=password value="pass2"></form>`,
|
document: `<form><input type=password value=""></form>`,
|
||||||
|
selectorValues: {
|
||||||
|
"[type=password]": "pass2",
|
||||||
|
},
|
||||||
wouldCapture: true,
|
wouldCapture: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -104,9 +116,8 @@ add_task(async function test() {
|
|||||||
let frameDoc = SpecialPowers.wrap(loginFrame.contentWindow).document;
|
let frameDoc = SpecialPowers.wrap(loginFrame.contentWindow).document;
|
||||||
// eslint-disable-next-line no-unsanitized/property
|
// eslint-disable-next-line no-unsanitized/property
|
||||||
frameDoc.documentElement.innerHTML = tc.document;
|
frameDoc.documentElement.innerHTML = tc.document;
|
||||||
|
// We eliminate no user input as a reason for not capturing by modifying the value
|
||||||
// Wait for the form to be processed before trying to submit.
|
setUserInputValues(frameDoc.documentElement, tc.selectorValues);
|
||||||
await promiseFormsProcessed();
|
|
||||||
|
|
||||||
info("Running " + scriptName + " script to check for a submission");
|
info("Running " + scriptName + " script to check for a submission");
|
||||||
frameDoc.defaultView.eval(SCRIPTS[scriptName]);
|
frameDoc.defaultView.eval(SCRIPTS[scriptName]);
|
||||||
|
@ -63,6 +63,15 @@ async function loadFormIntoIframe(origin, html) {
|
|||||||
|
|
||||||
// Wait for the form to be processed before trying to submit.
|
// Wait for the form to be processed before trying to submit.
|
||||||
await promiseFormsProcessed();
|
await promiseFormsProcessed();
|
||||||
|
|
||||||
|
await SpecialPowers.spawn(getIframeBrowsingContext(window, 0), [html], function(contentHtml) {
|
||||||
|
let doc = this.content.document;
|
||||||
|
for (let field of doc.querySelectorAll("input")) {
|
||||||
|
let actualValue = field.value;
|
||||||
|
field.value = "";
|
||||||
|
SpecialPowers.wrap(field).setUserInput(actualValue);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
add_task(async function setup() {
|
add_task(async function setup() {
|
||||||
@ -127,20 +136,6 @@ const TESTCASES = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* @return {Promise} resolving when form submission was processed.
|
|
||||||
*/
|
|
||||||
function getSubmitMessage() {
|
|
||||||
info("getSubmitMessage");
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
PWMGR_COMMON_PARENT.addMessageListener("formSubmissionProcessed", function processed(...args) {
|
|
||||||
info("got formSubmissionProcessed");
|
|
||||||
PWMGR_COMMON_PARENT.removeMessageListener("formSubmissionProcessed", processed);
|
|
||||||
resolve(...args);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
add_task(async function test_new_logins() {
|
add_task(async function test_new_logins() {
|
||||||
for (let tc of TESTCASES) {
|
for (let tc of TESTCASES) {
|
||||||
info("Starting testcase: " + JSON.stringify(tc));
|
info("Starting testcase: " + JSON.stringify(tc));
|
||||||
@ -193,8 +188,8 @@ add_task(async function test_no_autofill_munged_username_matching_password() {
|
|||||||
await SpecialPowers.spawn(getIframeBrowsingContext(window, 0), [], function() {
|
await SpecialPowers.spawn(getIframeBrowsingContext(window, 0), [], function() {
|
||||||
let doc = this.content.document;
|
let doc = this.content.document;
|
||||||
Assert.equal(doc.querySelector("[name='uname']").value, "", "Check username didn't get autofilled");
|
Assert.equal(doc.querySelector("[name='uname']").value, "", "Check username didn't get autofilled");
|
||||||
doc.querySelector("[name='uname']").setUserInput("real••••user");
|
SpecialPowers.wrap(doc.querySelector("[name='uname']")).setUserInput("real••••user");
|
||||||
doc.querySelector("[name='pword']").setUserInput("pass1");
|
SpecialPowers.wrap(doc.querySelector("[name='pword']")).setUserInput("pass1");
|
||||||
});
|
});
|
||||||
|
|
||||||
// we shouldn't get the save password doorhanger...
|
// we shouldn't get the save password doorhanger...
|
||||||
|
@ -12,17 +12,6 @@
|
|||||||
<script>
|
<script>
|
||||||
let chromeScript = runChecksAfterCommonInit();
|
let chromeScript = runChecksAfterCommonInit();
|
||||||
|
|
||||||
function getSubmitMessage() {
|
|
||||||
info("getSubmitMessage");
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
chromeScript.addMessageListener("formSubmissionProcessed", function processed(...args) {
|
|
||||||
info("got formSubmissionProcessed");
|
|
||||||
chromeScript.removeMessageListener("formSubmissionProcessed", processed);
|
|
||||||
resolve(...args);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
SimpleTest.requestFlakyTimeout("Giving a chance for the unexpected popupshown to occur");
|
SimpleTest.requestFlakyTimeout("Giving a chance for the unexpected popupshown to occur");
|
||||||
</script>
|
</script>
|
||||||
<p id="display"></p>
|
<p id="display"></p>
|
||||||
@ -45,8 +34,8 @@
|
|||||||
let password = document.getElementById("pfield");
|
let password = document.getElementById("pfield");
|
||||||
let submitButton = document.getElementById("submitBtn");
|
let submitButton = document.getElementById("submitBtn");
|
||||||
|
|
||||||
username.value = "user";
|
SpecialPowers.wrap(username).setUserInput("user");
|
||||||
password.value = "pass";
|
SpecialPowers.wrap(password).setUserInput("pass");
|
||||||
|
|
||||||
let processedPromise = getSubmitMessage();
|
let processedPromise = getSubmitMessage();
|
||||||
let promptShownPromise = promisePromptShown("passwordmgr-prompt-save");
|
let promptShownPromise = promisePromptShown("passwordmgr-prompt-save");
|
||||||
|
@ -40,12 +40,15 @@ Login Manager test: input value change right after onsubmit event
|
|||||||
<script>
|
<script>
|
||||||
/** Test for Login Manager: input value change right after onsubmit event **/
|
/** Test for Login Manager: input value change right after onsubmit event **/
|
||||||
add_task(async function checkFormValues() {
|
add_task(async function checkFormValues() {
|
||||||
document.getElementById("ufield").value = "testuser";
|
SpecialPowers.wrap(document.getElementById("ufield")).setUserInput("testuser");
|
||||||
document.getElementById("pfield").value = "testpass";
|
SpecialPowers.wrap(document.getElementById("pfield")).setUserInput("testpass");
|
||||||
is($_(1, "uname").value, "testuser", "Checking for filled username");
|
is($_(1, "uname").value, "testuser", "Checking for filled username");
|
||||||
is($_(1, "pword").value, "testpass", "Checking for filled password");
|
is($_(1, "pword").value, "testpass", "Checking for filled password");
|
||||||
|
|
||||||
document.getElementById("form1").addEventListener("submit", () => {
|
document.getElementById("form1").addEventListener("submit", () => {
|
||||||
|
// deliberately assign to .value rather than setUserInput:
|
||||||
|
// the scenario under test here is that script is changing/populating
|
||||||
|
// fields after the user has clicked the submit button
|
||||||
document.getElementById("ufield").value = "newuser";
|
document.getElementById("ufield").value = "newuser";
|
||||||
document.getElementById("pfield").value = "newpass";
|
document.getElementById("pfield").value = "newpass";
|
||||||
}, true);
|
}, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user