mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1243729 - (m-b) Part II, Test on username selection dialog, r=MattN, a=lizzard
MozReview-Commit-ID: 3OKA17mVjMs
This commit is contained in:
parent
cacbaf2742
commit
f53414a463
@ -243,3 +243,15 @@ this.LoginTestUtils.testData = {
|
||||
];
|
||||
},
|
||||
};
|
||||
|
||||
this.LoginTestUtils.recipes = {
|
||||
getRecipeParent() {
|
||||
let { LoginManagerParent } = Cu.import("resource://gre/modules/LoginManagerParent.jsm", {});
|
||||
if (!LoginManagerParent.recipeParentPromise) {
|
||||
return null;
|
||||
}
|
||||
return LoginManagerParent.recipeParentPromise.then((recipeParent) => {
|
||||
return recipeParent;
|
||||
});
|
||||
},
|
||||
};
|
||||
|
@ -1,12 +1,17 @@
|
||||
[DEFAULT]
|
||||
support-files =
|
||||
../formsubmit.sjs
|
||||
../subtst_notifications_change_p.html
|
||||
authenticate.sjs
|
||||
form_basic.html
|
||||
head.js
|
||||
insecure_test.html
|
||||
insecure_test_subframe.html
|
||||
multiple_forms.html
|
||||
streamConverter_content.sjs
|
||||
|
||||
[browser_username_select_dialog.js]
|
||||
skip-if = e10s # bug 1263760
|
||||
[browser_DOMFormHasPassword.js]
|
||||
[browser_DOMInputPasswordAdded.js]
|
||||
[browser_filldoorhanger.js]
|
||||
|
@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Test username selection dialog, on password update from a p-only form,
|
||||
* when there are multiple saved logins on the domain.
|
||||
*/
|
||||
|
||||
// Copied from prompt_common.js. TODO: share the code.
|
||||
function getSelectDialogDoc() {
|
||||
// Trudge through all the open windows, until we find the one
|
||||
// that has selectDialog.xul loaded.
|
||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
|
||||
getService(Ci.nsIWindowMediator);
|
||||
//var enumerator = wm.getEnumerator("navigator:browser");
|
||||
var enumerator = wm.getXULWindowEnumerator(null);
|
||||
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var win = enumerator.getNext();
|
||||
var windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell;
|
||||
|
||||
var containedDocShells = windowDocShell.getDocShellEnumerator(
|
||||
Ci.nsIDocShellTreeItem.typeChrome,
|
||||
Ci.nsIDocShell.ENUMERATE_FORWARDS);
|
||||
while (containedDocShells.hasMoreElements()) {
|
||||
// Get the corresponding document for this docshell
|
||||
var childDocShell = containedDocShells.getNext();
|
||||
// We don't want it if it's not done loading.
|
||||
if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
|
||||
continue;
|
||||
var childDoc = childDocShell.QueryInterface(Ci.nsIDocShell)
|
||||
.contentViewer
|
||||
.DOMDocument;
|
||||
|
||||
if (childDoc.location.href == "chrome://global/content/selectDialog.xul")
|
||||
return childDoc;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
|
||||
Ci.nsILoginInfo, "init");
|
||||
let login1 = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
|
||||
"notifyu1", "notifyp1", "user", "pass");
|
||||
let login1B = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null,
|
||||
"notifyu1B", "notifyp1B", "user", "pass");
|
||||
|
||||
add_task(function* test_changeUPLoginOnPUpdateForm_accept() {
|
||||
info("Select an u+p login from multiple logins, on password update form, and accept.");
|
||||
Services.logins.addLogin(login1);
|
||||
Services.logins.addLogin(login1B);
|
||||
|
||||
yield testSubmittingLoginForm("subtst_notifications_change_p.html", function*(fieldValues) {
|
||||
is(fieldValues.username, "null", "Checking submitted username");
|
||||
is(fieldValues.password, "pass2", "Checking submitted password");
|
||||
|
||||
yield ContentTaskUtils.waitForCondition(() => {
|
||||
return getSelectDialogDoc();
|
||||
}, "Wait for selection dialog to be accessible.");
|
||||
|
||||
let doc = getSelectDialogDoc();
|
||||
let dialog = doc.getElementsByTagName("dialog")[0];
|
||||
let listbox = doc.getElementById("list");
|
||||
|
||||
is(listbox.selectedIndex, 0, "Checking selected index");
|
||||
is(listbox.itemCount, 2, "Checking selected length");
|
||||
['notifyu1', 'notifyu1B'].forEach((username, i) => {
|
||||
is(listbox.getItemAtIndex(i).label, username, "Check username selection on dialog");
|
||||
});
|
||||
|
||||
dialog.acceptDialog();
|
||||
|
||||
yield ContentTaskUtils.waitForCondition(() => {
|
||||
return !getSelectDialogDoc();
|
||||
}, "Wait for selection dialog to disappear.");
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 2, "Should have 2 logins");
|
||||
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username unchanged");
|
||||
is(login.password, "pass2", "Check the password changed");
|
||||
is(login.timesUsed, 2, "Check times used");
|
||||
|
||||
login = SpecialPowers.wrap(logins[1]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1B", "Check the username unchanged");
|
||||
is(login.password, "notifyp1B", "Check the password unchanged");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
|
||||
// cleanup
|
||||
login1.password = "pass2";
|
||||
Services.logins.removeLogin(login1);
|
||||
login1.password = "notifyp1";
|
||||
|
||||
Services.logins.removeLogin(login1B);
|
||||
});
|
||||
|
||||
add_task(function* test_changeUPLoginOnPUpdateForm_cancel() {
|
||||
info("Select an u+p login from multiple logins, on password update form, and cancel.");
|
||||
Services.logins.addLogin(login1);
|
||||
Services.logins.addLogin(login1B);
|
||||
|
||||
yield testSubmittingLoginForm("subtst_notifications_change_p.html", function*(fieldValues) {
|
||||
is(fieldValues.username, "null", "Checking submitted username");
|
||||
is(fieldValues.password, "pass2", "Checking submitted password");
|
||||
|
||||
yield ContentTaskUtils.waitForCondition(() => {
|
||||
return getSelectDialogDoc();
|
||||
}, "Wait for selection dialog to be accessible.");
|
||||
|
||||
let doc = getSelectDialogDoc();
|
||||
let dialog = doc.getElementsByTagName("dialog")[0];
|
||||
let listbox = doc.getElementById("list");
|
||||
|
||||
is(listbox.selectedIndex, 0, "Checking selected index");
|
||||
is(listbox.itemCount, 2, "Checking selected length");
|
||||
['notifyu1', 'notifyu1B'].forEach((username, i) => {
|
||||
is(listbox.getItemAtIndex(i).label, username, "Check username selection on dialog");
|
||||
});
|
||||
|
||||
dialog.cancelDialog();
|
||||
|
||||
yield ContentTaskUtils.waitForCondition(() => {
|
||||
return !getSelectDialogDoc();
|
||||
}, "Wait for selection dialog to disappear.");
|
||||
});
|
||||
|
||||
let logins = Services.logins.getAllLogins();
|
||||
is(logins.length, 2, "Should have 2 logins");
|
||||
|
||||
let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1", "Check the username unchanged");
|
||||
is(login.password, "notifyp1", "Check the password unchanged");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
|
||||
login = SpecialPowers.wrap(logins[1]).QueryInterface(Ci.nsILoginMetaInfo);
|
||||
is(login.username, "notifyu1B", "Check the username unchanged");
|
||||
is(login.password, "notifyp1B", "Check the password unchanged");
|
||||
is(login.timesUsed, 1, "Check times used");
|
||||
|
||||
// cleanup
|
||||
Services.logins.removeLogin(login1);
|
||||
Services.logins.removeLogin(login1B);
|
||||
});
|
119
toolkit/components/passwordmgr/test/browser/head.js
Normal file
119
toolkit/components/passwordmgr/test/browser/head.js
Normal file
@ -0,0 +1,119 @@
|
||||
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);
|
||||
|
||||
registerCleanupFunction(function* cleanup_removeAllLoginsAndResetRecipes() {
|
||||
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;
|
||||
}
|
||||
yield recipeParent.then(recipeParent => recipeParent.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://mochi.test:8888"] - origin of the server to
|
||||
* use to load `aPageFile`.
|
||||
*/
|
||||
function testSubmittingLoginForm(aPageFile, aTaskFn, aOrigin = "http://mochi.test:8888") {
|
||||
return BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: aOrigin + DIRECTORY_PATH + aPageFile,
|
||||
}, function*(browser) {
|
||||
ok(true, "loaded " + aPageFile);
|
||||
let fieldValues = yield ContentTask.spawn(browser, undefined, function*() {
|
||||
yield 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) {
|
||||
yield* 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 = 1;
|
||||
|
||||
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`
|
||||
* @return the found password popup notification.
|
||||
*/
|
||||
function getCaptureDoorhanger(aKind) {
|
||||
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, "Remember", "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 <= aPopup.secondaryActions.length) {
|
||||
ok(true, "Triggering secondary action " + aButtonIndex);
|
||||
notification.childNodes[aButtonIndex].doCommand();
|
||||
}
|
||||
}
|
||||
|
||||
// End popup notification (doorhanger) functions //
|
@ -0,0 +1,32 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Subtest for Login Manager notifications</title>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Change password</h2>
|
||||
<form id="form" action="formsubmit.sjs">
|
||||
<input id="pass_current" name="pass_current" type="password" value="notifyp1">
|
||||
<input id="pass" name="pass" type="password">
|
||||
<input id="pass_confirm" name="pass_confirm" type="password">
|
||||
<button type='submit'>Submit</button>
|
||||
</form>
|
||||
|
||||
<script>
|
||||
function submitForm() {
|
||||
passField.value = "pass2";
|
||||
passConfirmField.value = "pass2";
|
||||
|
||||
form.submit();
|
||||
}
|
||||
|
||||
window.onload = submitForm;
|
||||
var form = document.getElementById("form");
|
||||
var userField = document.getElementById("user");
|
||||
var passField = document.getElementById("pass");
|
||||
var passConfirmField = document.getElementById("pass_confirm");
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user