gecko-dev/toolkit/components/passwordmgr/test/browser/head.js

146 lines
5.6 KiB
JavaScript

const DIRECTORY_PATH = "/browser/toolkit/components/passwordmgr/test/browser/";
Cu.import("resource://testing-common/LoginTestUtils.jsm", this);
Cu.import("resource://testing-common/ContentTaskUtils.jsm", this);
add_task(async function common_initialize() {
await SpecialPowers.pushPrefEnv({"set": [["signon.rememberSignons", true]]});
});
registerCleanupFunction(async function cleanup_removeAllLoginsAndResetRecipes() {
await SpecialPowers.popPrefEnv();
Services.logins.removeAllLogins();
let recipeParent = LoginTestUtils.recipes.getRecipeParent();
if (!recipeParent) {
// No need to reset the recipes if the recipe module wasn't even loaded.
return;
}
await recipeParent.then(recipeParentResult => recipeParentResult.reset());
});
/**
* Loads a test page in `DIRECTORY_URL` which automatically submits to formsubmit.sjs and returns a
* promise resolving with the field values when the optional `aTaskFn` is done.
*
* @param {String} aPageFile - test page file name which auto-submits to formsubmit.sjs
* @param {Function} aTaskFn - task which can be run before the tab closes.
* @param {String} [aOrigin="http://example.com"] - origin of the server to use
* to load `aPageFile`.
*/
function testSubmittingLoginForm(aPageFile, aTaskFn, aOrigin = "http://example.com") {
return BrowserTestUtils.withNewTab({
gBrowser,
url: aOrigin + DIRECTORY_PATH + aPageFile,
}, async function(browser) {
ok(true, "loaded " + aPageFile);
let fieldValues = await ContentTask.spawn(browser, undefined, async function() {
await ContentTaskUtils.waitForCondition(() => {
return content.location.pathname.endsWith("/formsubmit.sjs") &&
content.document.readyState == "complete";
}, "Wait for form submission load (formsubmit.sjs)");
let username = content.document.getElementById("user").textContent;
let password = content.document.getElementById("pass").textContent;
return {
username,
password,
};
});
ok(true, "form submission loaded");
if (aTaskFn) {
await aTaskFn(fieldValues);
}
return fieldValues;
});
}
function checkOnlyLoginWasUsedTwice({ justChanged }) {
// Check to make sure we updated the timestamps and use count on the
// existing login that was submitted for the test.
let logins = Services.logins.getAllLogins();
is(logins.length, 1, "Should only have 1 login");
ok(logins[0] instanceof Ci.nsILoginMetaInfo, "metainfo QI");
is(logins[0].timesUsed, 2, "check .timesUsed for existing login submission");
ok(logins[0].timeCreated < logins[0].timeLastUsed, "timeLastUsed bumped");
if (justChanged) {
is(logins[0].timeLastUsed, logins[0].timePasswordChanged, "timeLastUsed == timePasswordChanged");
} else {
is(logins[0].timeCreated, logins[0].timePasswordChanged, "timeChanged not updated");
}
}
// Begin popup notification (doorhanger) functions //
const REMEMBER_BUTTON = 0;
const NEVER_BUTTON = 2;
const CHANGE_BUTTON = 0;
const DONT_CHANGE_BUTTON = 1;
/**
* Checks if we have a password capture popup notification
* of the right type and with the right label.
*
* @param {String} aKind The desired `passwordNotificationType`
* @param {Object} [popupNotifications = PopupNotifications]
* @return the found password popup notification.
*/
function getCaptureDoorhanger(aKind, popupNotifications = PopupNotifications) {
ok(true, "Looking for " + aKind + " popup notification");
let notification = popupNotifications.getNotification("password");
if (notification) {
is(notification.options.passwordNotificationType, aKind, "Notification type matches.");
if (aKind == "password-change") {
is(notification.mainAction.label, "Update", "Main action label matches update doorhanger.");
} else if (aKind == "password-save") {
is(notification.mainAction.label, "Save", "Main action label matches save doorhanger.");
}
}
return notification;
}
/**
* Clicks the specified popup notification button.
*
* @param {Element} aPopup Popup Notification element
* @param {Number} aButtonIndex Number indicating which button to click.
* See the constants in this file.
*/
function clickDoorhangerButton(aPopup, aButtonIndex) {
ok(true, "Looking for action at index " + aButtonIndex);
let notifications = aPopup.owner.panel.childNodes;
ok(notifications.length > 0, "at least one notification displayed");
ok(true, notifications.length + " notification(s)");
let notification = notifications[0];
if (aButtonIndex == 0) {
ok(true, "Triggering main action");
notification.button.doCommand();
} else if (aButtonIndex == 1) {
ok(true, "Triggering secondary action");
notification.secondaryButton.doCommand();
} else if (aButtonIndex <= aPopup.secondaryActions.length) {
ok(true, "Triggering secondary action " + aButtonIndex);
notification.childNodes[aButtonIndex - 1].doCommand();
}
}
/**
* Checks the doorhanger's username and password.
*
* @param {String} username The username.
* @param {String} password The password.
*/
async function checkDoorhangerUsernamePassword(username, password) {
await BrowserTestUtils.waitForCondition(() => {
return document.getElementById("password-notification-username").value == username;
}, "Wait for nsLoginManagerPrompter writeDataToUI()");
is(document.getElementById("password-notification-username").value, username,
"Check doorhanger username");
is(document.getElementById("password-notification-password").value, password,
"Check doorhanger password");
}
// End popup notification (doorhanger) functions //