зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1386283 - Enable eslint 'indent' rule on passwordmgr with --fix. r=mconley
ignore-this-changeset for blame Differential Revision: https://phabricator.services.mozilla.com/D16109 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
d9469a1400
Коммит
3f7baf5de6
|
@ -7,6 +7,24 @@ module.exports = {
|
|||
// be removed & synced with the mozilla/recommended value.
|
||||
"complexity": ["error", 56],
|
||||
|
||||
"indent": ["error", 2, {
|
||||
ignoredNodes: ["ConditionalExpression"],
|
||||
ArrayExpression: "first",
|
||||
SwitchCase: 1,
|
||||
CallExpression: {
|
||||
arguments: "first",
|
||||
},
|
||||
FunctionExpression: {
|
||||
parameters: "first",
|
||||
},
|
||||
FunctionDeclaration: {
|
||||
parameters: "first",
|
||||
},
|
||||
MemberExpression: "off",
|
||||
ObjectExpression: "first",
|
||||
outerIIFEBody: 0,
|
||||
}],
|
||||
|
||||
"no-unused-vars": ["error", {"args": "none", "vars": "local", "varsIgnorePattern": "^(ids|ignored|unused)$"}],
|
||||
}
|
||||
};
|
||||
|
|
|
@ -46,9 +46,9 @@ var gLastRightClickTimeStamp = Number.NEGATIVE_INFINITY;
|
|||
|
||||
var observer = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
|
||||
Ci.nsIFormSubmitObserver,
|
||||
Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
Ci.nsIFormSubmitObserver,
|
||||
Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
// nsIFormSubmitObserver
|
||||
notify(formElement, aWindow, actionURI) {
|
||||
|
@ -222,7 +222,7 @@ var LoginManagerContent = {
|
|||
},
|
||||
|
||||
_sendRequest(messageManager, requestData,
|
||||
name, messageData) {
|
||||
name, messageData) {
|
||||
let count;
|
||||
if (!(count = this._managers.get(messageManager))) {
|
||||
this._managers.set(messageManager, 1);
|
||||
|
@ -309,7 +309,7 @@ var LoginManagerContent = {
|
|||
},
|
||||
|
||||
_autoCompleteSearchAsync(aSearchString, aPreviousResult,
|
||||
aElement, aRect) {
|
||||
aElement, aRect) {
|
||||
let doc = aElement.ownerDocument;
|
||||
let form = LoginFormFactory.createFromField(aElement);
|
||||
let win = doc.defaultView;
|
||||
|
@ -332,7 +332,7 @@ var LoginManagerContent = {
|
|||
rect: aRect,
|
||||
isSecure: InsecurePasswordUtils.isFormSecure(form),
|
||||
isPasswordField: aElement.type == "password",
|
||||
};
|
||||
};
|
||||
|
||||
return this._sendRequest(messageManager, requestData,
|
||||
"RemoteLogins:autoCompleteLogins",
|
||||
|
@ -694,9 +694,9 @@ var LoginManagerContent = {
|
|||
}
|
||||
|
||||
pwFields[pwFields.length] = {
|
||||
index: i,
|
||||
element,
|
||||
};
|
||||
index: i,
|
||||
element,
|
||||
};
|
||||
}
|
||||
|
||||
// If too few or too many fields, bail out.
|
||||
|
@ -1167,7 +1167,7 @@ var LoginManagerContent = {
|
|||
var username = usernameField.value.toLowerCase();
|
||||
|
||||
let matchingLogins = logins.filter(l =>
|
||||
l.username.toLowerCase() == username);
|
||||
l.username.toLowerCase() == username);
|
||||
if (matchingLogins.length == 0) {
|
||||
log("Password not filled. None of the stored logins match the username already present.");
|
||||
autofillResult = AUTOFILL_RESULT.EXISTING_USERNAME;
|
||||
|
@ -1486,7 +1486,7 @@ function UserAutoCompleteResult(aSearchString, matchingLogins, {isSecure, messag
|
|||
|
||||
UserAutoCompleteResult.prototype = {
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIAutoCompleteResult,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
// private
|
||||
logins: null,
|
||||
|
|
|
@ -41,27 +41,27 @@ var LoginManagerContextMenu = {
|
|||
let fragment = browser.ownerDocument.createDocumentFragment();
|
||||
let duplicateUsernames = this._findDuplicates(foundLogins);
|
||||
for (let login of foundLogins) {
|
||||
let item = fragment.ownerDocument.createXULElement("menuitem");
|
||||
let item = fragment.ownerDocument.createXULElement("menuitem");
|
||||
|
||||
let username = login.username;
|
||||
// If login is empty or duplicated we want to append a modification date to it.
|
||||
if (!username || duplicateUsernames.has(username)) {
|
||||
if (!username) {
|
||||
username = this._getLocalizedString("noUsername");
|
||||
}
|
||||
let meta = login.QueryInterface(Ci.nsILoginMetaInfo);
|
||||
let time = this.dateAndTimeFormatter.format(new Date(meta.timePasswordChanged));
|
||||
username = this._getLocalizedString("loginHostAge", [username, time]);
|
||||
let username = login.username;
|
||||
// If login is empty or duplicated we want to append a modification date to it.
|
||||
if (!username || duplicateUsernames.has(username)) {
|
||||
if (!username) {
|
||||
username = this._getLocalizedString("noUsername");
|
||||
}
|
||||
item.setAttribute("label", username);
|
||||
item.setAttribute("class", "context-login-item");
|
||||
let meta = login.QueryInterface(Ci.nsILoginMetaInfo);
|
||||
let time = this.dateAndTimeFormatter.format(new Date(meta.timePasswordChanged));
|
||||
username = this._getLocalizedString("loginHostAge", [username, time]);
|
||||
}
|
||||
item.setAttribute("label", username);
|
||||
item.setAttribute("class", "context-login-item");
|
||||
|
||||
// login is bound so we can keep the reference to each object.
|
||||
item.addEventListener("command", function(login, event) {
|
||||
this._fillTargetField(login, inputElement, browser, documentURI);
|
||||
}.bind(this, login));
|
||||
// login is bound so we can keep the reference to each object.
|
||||
item.addEventListener("command", function(login, event) {
|
||||
this._fillTargetField(login, inputElement, browser, documentURI);
|
||||
}.bind(this, login));
|
||||
|
||||
fragment.appendChild(item);
|
||||
fragment.appendChild(item);
|
||||
}
|
||||
|
||||
return fragment;
|
||||
|
|
|
@ -150,7 +150,7 @@ var LoginManagerParent = {
|
|||
* Send relevant data (e.g. logins and recipes) to the child process (LoginManagerContent).
|
||||
*/
|
||||
async sendLoginDataToChild(showMasterPassword, formOrigin, actionOrigin,
|
||||
requestId, target) {
|
||||
requestId, target) {
|
||||
let recipes = [];
|
||||
if (formOrigin) {
|
||||
let formHost;
|
||||
|
@ -230,7 +230,7 @@ var LoginManagerParent = {
|
|||
doAutocompleteSearch({ formOrigin, actionOrigin,
|
||||
searchString, previousResult,
|
||||
rect, requestId, isSecure, isPasswordField,
|
||||
}, target) {
|
||||
}, target) {
|
||||
// Note: previousResult is a regular object, not an
|
||||
// nsIAutoCompleteResult.
|
||||
|
||||
|
@ -287,9 +287,9 @@ var LoginManagerParent = {
|
|||
},
|
||||
|
||||
onFormSubmit(hostname, formSubmitURL,
|
||||
usernameField, newPasswordField,
|
||||
oldPasswordField, openerTopWindowID,
|
||||
target) {
|
||||
usernameField, newPasswordField,
|
||||
oldPasswordField, openerTopWindowID,
|
||||
target) {
|
||||
function getPrompter() {
|
||||
var prompterSvc = Cc["@mozilla.org/login-manager/prompter;1"].
|
||||
createInstance(Ci.nsILoginManagerPrompter);
|
||||
|
@ -366,7 +366,7 @@ var LoginManagerParent = {
|
|||
// changing a second account to the new password so we ask anyways.
|
||||
|
||||
prompter.promptToChangePasswordWithUsernames(
|
||||
logins, logins.length, formLogin);
|
||||
logins, logins.length, formLogin);
|
||||
}
|
||||
|
||||
return;
|
||||
|
@ -500,4 +500,4 @@ XPCOMUtils.defineLazyGetter(LoginManagerParent, "recipeParentPromise", function(
|
|||
});
|
||||
|
||||
XPCOMUtils.defineLazyPreferenceGetter(LoginManagerParent, "_repromptTimeout",
|
||||
"signon.masterPasswordReprompt.timeout_ms", 900000); // 15 Minutes
|
||||
"signon.masterPasswordReprompt.timeout_ms", 900000); // 15 Minutes
|
||||
|
|
|
@ -167,9 +167,9 @@ OSCrypto.prototype = {
|
|||
}
|
||||
|
||||
let status = this._functions.get("CryptUnprotectData")(inData.address(), null,
|
||||
entropyParam,
|
||||
null, null, FLAGS_NOT_SET,
|
||||
outData.address());
|
||||
entropyParam,
|
||||
null, null, FLAGS_NOT_SET,
|
||||
outData.address());
|
||||
if (status === 0) {
|
||||
throw new Error("decryptData failed: " + status);
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ OSCrypto.prototype = {
|
|||
|
||||
this._functions.get("LocalFree")(outData.pbData);
|
||||
return decryptedData;
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* Encrypt a string using the windows CryptProtectData API.
|
||||
|
|
|
@ -59,10 +59,10 @@ let signonReloadDisplay = {
|
|||
|
||||
// Formatter for localization.
|
||||
let dateFormatter = new Services.intl.DateTimeFormat(undefined,
|
||||
{ dateStyle: "medium" });
|
||||
{ dateStyle: "medium" });
|
||||
let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
|
||||
{ dateStyle: "medium",
|
||||
timeStyle: "short" });
|
||||
{ dateStyle: "medium",
|
||||
timeStyle: "short" });
|
||||
|
||||
function Startup() {
|
||||
// be prepared to reload the display if anything changes
|
||||
|
@ -195,7 +195,7 @@ let signonsTreeView = {
|
|||
}
|
||||
|
||||
if (col.id == "userCol") {
|
||||
_editLogin("username");
|
||||
_editLogin("username");
|
||||
|
||||
} else if (col.id == "passwordCol") {
|
||||
if (!value) {
|
||||
|
@ -380,10 +380,10 @@ function DeleteAllSignons() {
|
|||
// Confirm the user wants to remove all passwords
|
||||
let dummy = { value: false };
|
||||
if (Services.prompt.confirmEx(window,
|
||||
kSignonBundle.getString("removeAllPasswordsTitle"),
|
||||
kSignonBundle.getString("removeAllPasswordsPrompt"),
|
||||
Services.prompt.STD_YES_NO_BUTTONS + Services.prompt.BUTTON_POS_1_DEFAULT,
|
||||
null, null, null, null, dummy) == 1) // 1 == "No" button
|
||||
kSignonBundle.getString("removeAllPasswordsTitle"),
|
||||
kSignonBundle.getString("removeAllPasswordsPrompt"),
|
||||
Services.prompt.STD_YES_NO_BUTTONS + Services.prompt.BUTTON_POS_1_DEFAULT,
|
||||
null, null, null, null, dummy) == 1) // 1 == "No" button
|
||||
return;
|
||||
|
||||
let syncNeeded = signonsTreeView._filterSet.length != 0;
|
||||
|
@ -435,9 +435,9 @@ function AskUserShowPasswords() {
|
|||
|
||||
// Confirm the user wants to display passwords
|
||||
return Services.prompt.confirmEx(window,
|
||||
null,
|
||||
kSignonBundle.getString("noMasterPasswordPrompt"), Services.prompt.STD_YES_NO_BUTTONS,
|
||||
null, null, null, null, dummy) == 0; // 0=="Yes" button
|
||||
null,
|
||||
kSignonBundle.getString("noMasterPasswordPrompt"), Services.prompt.STD_YES_NO_BUTTONS,
|
||||
null, null, null, null, dummy) == 0; // 0=="Yes" button
|
||||
}
|
||||
|
||||
function FinalizeSignonDeletions(syncNeeded) {
|
||||
|
@ -714,7 +714,7 @@ function masterPasswordLogin(noPasswordCallback) {
|
|||
try {
|
||||
// Relogin and ask for the master password.
|
||||
token.login(true); // 'true' means always prompt for token password. User will be prompted until
|
||||
// clicking 'Cancel' or entering the correct password.
|
||||
// clicking 'Cancel' or entering the correct password.
|
||||
} catch (e) {
|
||||
// An exception will be thrown if the user cancels the login prompt dialog.
|
||||
// User is also logged out of Software Security Device.
|
||||
|
|
|
@ -28,8 +28,8 @@ nsLoginInfo.prototype = {
|
|||
passwordField: null,
|
||||
|
||||
init(aHostname, aFormSubmitURL, aHttpRealm,
|
||||
aUsername, aPassword,
|
||||
aUsernameField, aPasswordField) {
|
||||
aUsername, aPassword,
|
||||
aUsernameField, aPasswordField) {
|
||||
this.hostname = aHostname;
|
||||
this.formSubmitURL = aFormSubmitURL;
|
||||
this.httpRealm = aHttpRealm;
|
||||
|
|
|
@ -151,7 +151,7 @@ LoginManager.prototype = {
|
|||
this._pwmgr._initStorage();
|
||||
await this._pwmgr.initializationPromise;
|
||||
Services.obs.notifyObservers(null,
|
||||
"passwordmgr-storage-replace-complete");
|
||||
"passwordmgr-storage-replace-complete");
|
||||
})();
|
||||
} else if (topic == "gather-telemetry") {
|
||||
// When testing, the "data" parameter is a string containing the
|
||||
|
|
|
@ -241,8 +241,8 @@ LoginManagerPrompter.prototype = {
|
|||
|
||||
classID: Components.ID("{8aa66d77-1bbb-45a6-991e-b8f47751c291}"),
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsIAuthPrompt,
|
||||
Ci.nsIAuthPrompt2,
|
||||
Ci.nsILoginManagerPrompter]),
|
||||
Ci.nsIAuthPrompt2,
|
||||
Ci.nsILoginManagerPrompter]),
|
||||
|
||||
_factory: null,
|
||||
_chromeWindow: null,
|
||||
|
@ -253,7 +253,7 @@ LoginManagerPrompter.prototype = {
|
|||
get _strBundle() {
|
||||
if (!this.__strBundle) {
|
||||
this.__strBundle = Services.strings.createBundle(
|
||||
"chrome://passwordmgr/locale/passwordmgr.properties");
|
||||
"chrome://passwordmgr/locale/passwordmgr.properties");
|
||||
if (!this.__strBundle)
|
||||
throw new Error("String bundle for Login Manager not present!");
|
||||
}
|
||||
|
@ -268,7 +268,7 @@ LoginManagerPrompter.prototype = {
|
|||
this.__ellipsis = "\u2026";
|
||||
try {
|
||||
this.__ellipsis = Services.prefs.getComplexValue(
|
||||
"intl.ellipsis", Ci.nsIPrefLocalizedString).data;
|
||||
"intl.ellipsis", Ci.nsIPrefLocalizedString).data;
|
||||
} catch (e) { }
|
||||
}
|
||||
return this.__ellipsis;
|
||||
|
@ -300,7 +300,7 @@ LoginManagerPrompter.prototype = {
|
|||
* doesn't really make sense and therefore isn't implemented.
|
||||
*/
|
||||
prompt(aDialogTitle, aText, aPasswordRealm,
|
||||
aSavePassword, aDefaultText, aResult) {
|
||||
aSavePassword, aDefaultText, aResult) {
|
||||
if (aSavePassword != Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER)
|
||||
throw new Components.Exception("prompt only supports SAVE_PASSWORD_NEVER",
|
||||
Cr.NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
@ -312,7 +312,7 @@ LoginManagerPrompter.prototype = {
|
|||
}
|
||||
|
||||
return Services.prompt.prompt(this._chromeWindow,
|
||||
aDialogTitle, aText, aResult, null, {});
|
||||
aDialogTitle, aText, aResult, null, {});
|
||||
},
|
||||
|
||||
|
||||
|
@ -321,7 +321,7 @@ LoginManagerPrompter.prototype = {
|
|||
* with a dialog, even if a username and password are found.
|
||||
*/
|
||||
promptUsernameAndPassword(aDialogTitle, aText, aPasswordRealm,
|
||||
aSavePassword, aUsername, aPassword) {
|
||||
aSavePassword, aUsername, aPassword) {
|
||||
this.log("===== promptUsernameAndPassword() called =====");
|
||||
|
||||
if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION)
|
||||
|
@ -374,8 +374,8 @@ LoginManagerPrompter.prototype = {
|
|||
}
|
||||
|
||||
var ok = Services.prompt.promptUsernameAndPassword(this._chromeWindow,
|
||||
aDialogTitle, aText, aUsername, aPassword,
|
||||
checkBoxLabel, checkBox);
|
||||
aDialogTitle, aText, aUsername, aPassword,
|
||||
checkBoxLabel, checkBox);
|
||||
|
||||
if (!ok || !checkBox.value || !hostname)
|
||||
return ok;
|
||||
|
@ -422,7 +422,7 @@ LoginManagerPrompter.prototype = {
|
|||
* allows it, then the password will be saved in the database.
|
||||
*/
|
||||
promptPassword(aDialogTitle, aText, aPasswordRealm,
|
||||
aSavePassword, aPassword) {
|
||||
aSavePassword, aPassword) {
|
||||
this.log("===== promptPassword called() =====");
|
||||
|
||||
if (aSavePassword == Ci.nsIAuthPrompt.SAVE_PASSWORD_FOR_SESSION)
|
||||
|
@ -562,7 +562,7 @@ LoginManagerPrompter.prototype = {
|
|||
if (foundLogins.length > 0) {
|
||||
selectedLogin = foundLogins[0];
|
||||
this._SetAuthInfo(aAuthInfo, selectedLogin.username,
|
||||
selectedLogin.password);
|
||||
selectedLogin.password);
|
||||
|
||||
// Allow automatic proxy login
|
||||
if (aAuthInfo.flags & Ci.nsIAuthInformation.AUTH_PROXY &&
|
||||
|
@ -756,8 +756,8 @@ LoginManagerPrompter.prototype = {
|
|||
|
||||
this.log("Adding new " + aName + " notification bar");
|
||||
var newBar = aNotifyBox.appendNotification(
|
||||
aText, aName, "",
|
||||
priority, aButtons);
|
||||
aText, aName, "",
|
||||
priority, aButtons);
|
||||
|
||||
// The page we're going to hasn't loaded yet, so we want to persist
|
||||
// across the first location change.
|
||||
|
@ -1078,9 +1078,8 @@ LoginManagerPrompter.prototype = {
|
|||
this._getLocalizedString("notifyBarRememberPasswordButtonAccessKey");
|
||||
|
||||
var displayHost = this._getShortDisplayHost(aLogin.hostname);
|
||||
var notificationText = this._getLocalizedString(
|
||||
"rememberPasswordMsgNoUsername",
|
||||
[displayHost]);
|
||||
var notificationText = this._getLocalizedString("rememberPasswordMsgNoUsername",
|
||||
[displayHost]);
|
||||
|
||||
// Notification is a PopupNotification
|
||||
if (aNotifyObj == this._getPopupNote()) {
|
||||
|
@ -1166,23 +1165,17 @@ LoginManagerPrompter.prototype = {
|
|||
var dialogText;
|
||||
if (aLogin.username) {
|
||||
var displayUser = this._sanitizeUsername(aLogin.username);
|
||||
dialogText = this._getLocalizedString(
|
||||
"rememberPasswordMsg",
|
||||
[displayUser, displayHost]);
|
||||
dialogText = this._getLocalizedString("rememberPasswordMsg",
|
||||
[displayUser, displayHost]);
|
||||
} else {
|
||||
dialogText = this._getLocalizedString(
|
||||
"rememberPasswordMsgNoUsername",
|
||||
[displayHost]);
|
||||
dialogText = this._getLocalizedString("rememberPasswordMsgNoUsername",
|
||||
[displayHost]);
|
||||
|
||||
}
|
||||
var dialogTitle = this._getLocalizedString(
|
||||
"savePasswordTitle");
|
||||
var neverButtonText = this._getLocalizedString(
|
||||
"neverForSiteButtonText");
|
||||
var rememberButtonText = this._getLocalizedString(
|
||||
"rememberButtonText");
|
||||
var notNowButtonText = this._getLocalizedString(
|
||||
"notNowButtonText");
|
||||
var dialogTitle = this._getLocalizedString("savePasswordTitle");
|
||||
var neverButtonText = this._getLocalizedString("neverForSiteButtonText");
|
||||
var rememberButtonText = this._getLocalizedString("rememberButtonText");
|
||||
var notNowButtonText = this._getLocalizedString("notNowButtonText");
|
||||
|
||||
this.log("Prompting user to save/ignore login");
|
||||
var userChoice = Services.prompt.confirmEx(this._chromeWindow,
|
||||
|
@ -1306,15 +1299,12 @@ LoginManagerPrompter.prototype = {
|
|||
|
||||
var dialogText;
|
||||
if (aOldLogin.username)
|
||||
dialogText = this._getLocalizedString(
|
||||
"updatePasswordMsg",
|
||||
[aOldLogin.username]);
|
||||
dialogText = this._getLocalizedString("updatePasswordMsg",
|
||||
[aOldLogin.username]);
|
||||
else
|
||||
dialogText = this._getLocalizedString(
|
||||
"updatePasswordMsgNoUser");
|
||||
dialogText = this._getLocalizedString("updatePasswordMsgNoUser");
|
||||
|
||||
var dialogTitle = this._getLocalizedString(
|
||||
"passwordChangeTitle");
|
||||
var dialogTitle = this._getLocalizedString("passwordChangeTitle");
|
||||
|
||||
// returns 0 for yes, 1 for no.
|
||||
var ok = !Services.prompt.confirmEx(this._chromeWindow,
|
||||
|
@ -1509,7 +1499,7 @@ LoginManagerPrompter.prototype = {
|
|||
_getLocalizedString(key, formatArgs) {
|
||||
if (formatArgs)
|
||||
return this._strBundle.formatStringFromName(
|
||||
key, formatArgs, formatArgs.length);
|
||||
key, formatArgs, formatArgs.length);
|
||||
return this._strBundle.GetStringFromName(key);
|
||||
},
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ function LoginManagerStorage_mozStorage() { }
|
|||
LoginManagerStorage_mozStorage.prototype = {
|
||||
classID: Components.ID("{8c2023b9-175c-477e-9761-44ae7b549756}"),
|
||||
QueryInterface: ChromeUtils.generateQI([Ci.nsILoginManagerStorage,
|
||||
Ci.nsIInterfaceRequestor]),
|
||||
Ci.nsIInterfaceRequestor]),
|
||||
|
||||
_xpcom_factory: XPCOMUtils.generateSingletonFactory(this.LoginManagerStorage_mozStorage),
|
||||
|
||||
|
@ -124,16 +124,16 @@ LoginManagerStorage_mozStorage.prototype = {
|
|||
columns: ["hostname", "formSubmitURL"],
|
||||
},
|
||||
moz_logins_hostname_httpRealm_index: {
|
||||
table: "moz_logins",
|
||||
columns: ["hostname", "httpRealm"],
|
||||
table: "moz_logins",
|
||||
columns: ["hostname", "httpRealm"],
|
||||
},
|
||||
moz_logins_guid_index: {
|
||||
table: "moz_logins",
|
||||
columns: ["guid"],
|
||||
table: "moz_logins",
|
||||
columns: ["guid"],
|
||||
},
|
||||
moz_logins_encType_index: {
|
||||
table: "moz_logins",
|
||||
columns: ["encType"],
|
||||
table: "moz_logins",
|
||||
columns: ["encType"],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -853,7 +853,7 @@ LoginManagerStorage_mozStorage.prototype = {
|
|||
case "profile-before-change":
|
||||
Services.obs.removeObserver(this, "profile-before-change");
|
||||
this._dbClose();
|
||||
break;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ function task(contentConsts) {
|
|||
function test_inputAddHandler(evt) {
|
||||
removeEventListener(evt.type, test_inputAddHandler, false);
|
||||
Assert.equal(evt.target.id, contentConsts.INPUT_ID,
|
||||
evt.type + " event targets correct input element (added password element)");
|
||||
evt.type + " event targets correct input element (added password element)");
|
||||
gDoc.defaultView.setTimeout(test_inputAddOutsideForm, 0);
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ function task(contentConsts) {
|
|||
function test_inputAddOutsideFormHandler(evt) {
|
||||
removeEventListener(evt.type, test_inputAddOutsideFormHandler, false);
|
||||
Assert.equal(evt.target.id, contentConsts.BODY_INPUT_ID,
|
||||
evt.type + " event targets correct input element (added password element outside form)");
|
||||
evt.type + " event targets correct input element (added password element outside form)");
|
||||
gDoc.defaultView.setTimeout(test_inputChangesType, 0);
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,7 @@ function task(contentConsts) {
|
|||
function test_inputChangesTypeHandler(evt) {
|
||||
removeEventListener(evt.type, test_inputChangesTypeHandler, false);
|
||||
Assert.equal(evt.target.id, contentConsts.CHANGE_INPUT_ID,
|
||||
evt.type + " event targets correct input element (changed type)");
|
||||
evt.type + " event targets correct input element (changed type)");
|
||||
gDoc.defaultView.setTimeout(completeTest, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ add_task(async function test_context_menu_password_fill() {
|
|||
.spawn(browser, {inputId}, async function({inputId}) {
|
||||
let input = content.document.getElementById(inputId);
|
||||
return input.disabled || input.readOnly;
|
||||
});
|
||||
});
|
||||
|
||||
// If the password field is disabled or read-only, we want to see
|
||||
// the disabled Fill Password popup header.
|
||||
|
@ -196,7 +196,7 @@ add_task(async function test_context_menu_username_login_fill() {
|
|||
let formElement = content.document.querySelector(`[description="${description}"]`);
|
||||
let inputs = Array.from(formElement.querySelectorAll("input[type='text']"));
|
||||
return inputs.map((p) => p.id);
|
||||
});
|
||||
});
|
||||
|
||||
for (let inputId of usernameInputIds) {
|
||||
info("Testing username field: " + inputId);
|
||||
|
@ -245,7 +245,7 @@ add_task(async function test_context_menu_username_login_fill() {
|
|||
.spawn(browser, {description}, async function({description}) {
|
||||
let formElement = content.document.querySelector(`[description="${description}"]`);
|
||||
return formElement.querySelector("input[type='password']").id;
|
||||
});
|
||||
});
|
||||
|
||||
// We shouldn't change any field that's not the target username field or the first password field
|
||||
await assertContextMenuFill(browser, description, inputId, passwordFieldId, 1);
|
||||
|
|
|
@ -83,7 +83,7 @@ add_task(async function test_streamConverter() {
|
|||
|
||||
let tab = BrowserTestUtils.addTab(gBrowser, "http://example.com/browser/toolkit/components/" +
|
||||
"passwordmgr/test/browser/streamConverter_content.sjs",
|
||||
{ sameProcessAsFrameLoader: originalBrowser.frameLoader });
|
||||
{ sameProcessAsFrameLoader: originalBrowser.frameLoader });
|
||||
let browser = tab.linkedBrowser;
|
||||
await Promise.all([
|
||||
BrowserTestUtils.switchTab(gBrowser, tab),
|
||||
|
|
|
@ -41,12 +41,12 @@ add_task(async function test_save_change() {
|
|||
"popupshown",
|
||||
(event) => event.target == PopupNotifications.panel);
|
||||
await ContentTask.spawn(browser, [username, password],
|
||||
async function([contentUsername, contentPassword]) {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = contentUsername;
|
||||
doc.getElementById("form-basic-password").value = contentPassword;
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
async function([contentUsername, contentPassword]) {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = contentUsername;
|
||||
doc.getElementById("form-basic-password").value = contentPassword;
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
await promiseShown;
|
||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||
// Style flush to make sure binding is attached
|
||||
|
@ -63,7 +63,7 @@ add_task(async function test_save_change() {
|
|||
// of operation we expect.
|
||||
let expectedNotification = oldPassword ? "modifyLogin" : "addLogin";
|
||||
let promiseLogin = TestUtils.topicObserved("passwordmgr-storage-changed",
|
||||
(_, data) => data == expectedNotification);
|
||||
(_, data) => data == expectedNotification);
|
||||
notificationElement.button.doCommand();
|
||||
let [result] = await promiseLogin;
|
||||
|
||||
|
|
|
@ -12,36 +12,35 @@ add_task(async function setup() {
|
|||
*/
|
||||
add_task(async function test_empty_password() {
|
||||
await BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: "https://example.com/browser/toolkit/components/" +
|
||||
"passwordmgr/test/browser/form_basic.html",
|
||||
}, async function(browser) {
|
||||
// Submit the form in the content page with the credentials from the test
|
||||
// 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() {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = "username";
|
||||
doc.getElementById("form-basic-password").value = "p";
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
await promiseShown;
|
||||
gBrowser,
|
||||
url: "https://example.com/browser/toolkit/components/passwordmgr/test/browser/form_basic.html",
|
||||
}, async function(browser) {
|
||||
// Submit the form in the content page with the credentials from the test
|
||||
// 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() {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = "username";
|
||||
doc.getElementById("form-basic-password").value = "p";
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
await promiseShown;
|
||||
|
||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||
let passwordTextbox = notificationElement.querySelector("#password-notification-password");
|
||||
let toggleCheckbox = notificationElement.querySelector("#password-notification-visibilityToggle");
|
||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||
let passwordTextbox = notificationElement.querySelector("#password-notification-password");
|
||||
let toggleCheckbox = notificationElement.querySelector("#password-notification-visibilityToggle");
|
||||
|
||||
// Synthesize input to empty the field
|
||||
passwordTextbox.focus();
|
||||
await EventUtils.synthesizeKey("KEY_ArrowRight");
|
||||
await EventUtils.synthesizeKey("KEY_Backspace");
|
||||
// Synthesize input to empty the field
|
||||
passwordTextbox.focus();
|
||||
await EventUtils.synthesizeKey("KEY_ArrowRight");
|
||||
await EventUtils.synthesizeKey("KEY_Backspace");
|
||||
|
||||
let mainActionButton = notificationElement.button;
|
||||
Assert.ok(mainActionButton.disabled, "Main action button is disabled");
|
||||
});
|
||||
let mainActionButton = notificationElement.button;
|
||||
Assert.ok(mainActionButton.disabled, "Main action button is disabled");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -50,36 +49,35 @@ add_task(async function test_empty_password() {
|
|||
*/
|
||||
add_task(async function test_toggle_password() {
|
||||
await BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: "https://example.com/browser/toolkit/components/" +
|
||||
"passwordmgr/test/browser/form_basic.html",
|
||||
}, async function(browser) {
|
||||
// Submit the form in the content page with the credentials from the test
|
||||
// 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() {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = "username";
|
||||
doc.getElementById("form-basic-password").value = "p";
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
await promiseShown;
|
||||
gBrowser,
|
||||
url: "https://example.com/browser/toolkit/components/passwordmgr/test/browser/form_basic.html",
|
||||
}, async function(browser) {
|
||||
// Submit the form in the content page with the credentials from the test
|
||||
// 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() {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = "username";
|
||||
doc.getElementById("form-basic-password").value = "p";
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
await promiseShown;
|
||||
|
||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||
let passwordTextbox = notificationElement.querySelector("#password-notification-password");
|
||||
let toggleCheckbox = notificationElement.querySelector("#password-notification-visibilityToggle");
|
||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||
let passwordTextbox = notificationElement.querySelector("#password-notification-password");
|
||||
let toggleCheckbox = notificationElement.querySelector("#password-notification-visibilityToggle");
|
||||
|
||||
await EventUtils.synthesizeMouseAtCenter(toggleCheckbox, {});
|
||||
Assert.ok(toggleCheckbox.checked);
|
||||
Assert.equal(passwordTextbox.type, "", "Password textbox changed to plain text");
|
||||
await EventUtils.synthesizeMouseAtCenter(toggleCheckbox, {});
|
||||
Assert.ok(toggleCheckbox.checked);
|
||||
Assert.equal(passwordTextbox.type, "", "Password textbox changed to plain text");
|
||||
|
||||
await EventUtils.synthesizeMouseAtCenter(toggleCheckbox, {});
|
||||
Assert.ok(!toggleCheckbox.checked);
|
||||
Assert.equal(passwordTextbox.type, "password", "Password textbox changed to * text");
|
||||
});
|
||||
await EventUtils.synthesizeMouseAtCenter(toggleCheckbox, {});
|
||||
Assert.ok(!toggleCheckbox.checked);
|
||||
Assert.equal(passwordTextbox.type, "password", "Password textbox changed to * text");
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -88,33 +86,32 @@ add_task(async function test_toggle_password() {
|
|||
*/
|
||||
add_task(async function test_checkbox_disabled_if_has_master_password() {
|
||||
await BrowserTestUtils.withNewTab({
|
||||
gBrowser,
|
||||
url: "https://example.com/browser/toolkit/components/" +
|
||||
"passwordmgr/test/browser/form_basic.html",
|
||||
}, async function(browser) {
|
||||
// Submit the form in the content page with the credentials from the test
|
||||
// case. This will cause the doorhanger notification to be displayed.
|
||||
let promiseShown = BrowserTestUtils.waitForEvent(PopupNotifications.panel,
|
||||
"popupshown",
|
||||
(event) => event.target == PopupNotifications.panel);
|
||||
gBrowser,
|
||||
url: "https://example.com/browser/toolkit/components/passwordmgr/test/browser/form_basic.html",
|
||||
}, async function(browser) {
|
||||
// Submit the form in the content page with the credentials from the test
|
||||
// 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() {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = "username";
|
||||
doc.getElementById("form-basic-password").value = "p";
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
await promiseShown;
|
||||
|
||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||
let passwordTextbox = notificationElement.querySelector("#password-notification-password");
|
||||
let toggleCheckbox = notificationElement.querySelector("#password-notification-visibilityToggle");
|
||||
|
||||
Assert.equal(passwordTextbox.type, "password", "Password textbox should show * text");
|
||||
Assert.ok(toggleCheckbox.getAttribute("hidden"), "checkbox is hidden when master password is set");
|
||||
await ContentTask.spawn(browser, null, async function() {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = "username";
|
||||
doc.getElementById("form-basic-password").value = "p";
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
await promiseShown;
|
||||
|
||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||
let passwordTextbox = notificationElement.querySelector("#password-notification-password");
|
||||
let toggleCheckbox = notificationElement.querySelector("#password-notification-visibilityToggle");
|
||||
|
||||
Assert.equal(passwordTextbox.type, "password", "Password textbox should show * text");
|
||||
Assert.ok(toggleCheckbox.getAttribute("hidden"), "checkbox is hidden when master password is set");
|
||||
});
|
||||
|
||||
LoginTestUtils.masterPassword.disable();
|
||||
});
|
||||
|
|
|
@ -81,12 +81,12 @@ add_task(async function test_edit_password() {
|
|||
"popupshown",
|
||||
(event) => event.target == PopupNotifications.panel);
|
||||
await ContentTask.spawn(browser, testCase,
|
||||
async function(contentTestCase) {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = contentTestCase.usernameInPage;
|
||||
doc.getElementById("form-basic-password").value = contentTestCase.passwordInPage;
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
async function(contentTestCase) {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = contentTestCase.usernameInPage;
|
||||
doc.getElementById("form-basic-password").value = contentTestCase.passwordInPage;
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
await promiseShown;
|
||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||
// Style flush to make sure binding is attached
|
||||
|
@ -115,7 +115,7 @@ add_task(async function test_edit_password() {
|
|||
// of operation we expect.
|
||||
let expectedNotification = expectModifyLogin ? "modifyLogin" : "addLogin";
|
||||
let promiseLogin = TestUtils.topicObserved("passwordmgr-storage-changed",
|
||||
(_, data) => data == expectedNotification);
|
||||
(_, data) => data == expectedNotification);
|
||||
notificationElement.button.doCommand();
|
||||
let [result] = await promiseLogin;
|
||||
|
||||
|
|
|
@ -72,12 +72,12 @@ add_task(async function test_edit_username() {
|
|||
"popupshown",
|
||||
(event) => event.target == PopupNotifications.panel);
|
||||
await ContentTask.spawn(browser, testCase.usernameInPage,
|
||||
async function(usernameInPage) {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = usernameInPage;
|
||||
doc.getElementById("form-basic-password").value = "password";
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
async function(usernameInPage) {
|
||||
let doc = content.document;
|
||||
doc.getElementById("form-basic-username").value = usernameInPage;
|
||||
doc.getElementById("form-basic-password").value = "password";
|
||||
doc.getElementById("form-basic").submit();
|
||||
});
|
||||
await promiseShown;
|
||||
let notificationElement = PopupNotifications.panel.childNodes[0];
|
||||
// Style flush to make sure binding is attached
|
||||
|
@ -100,7 +100,7 @@ add_task(async function test_edit_username() {
|
|||
// of operation we expect.
|
||||
let expectedNotification = expectModifyLogin ? "modifyLogin" : "addLogin";
|
||||
let promiseLogin = TestUtils.topicObserved("passwordmgr-storage-changed",
|
||||
(_, data) => data == expectedNotification);
|
||||
(_, data) => data == expectedNotification);
|
||||
notificationElement.button.doCommand();
|
||||
let [result] = await promiseLogin;
|
||||
|
||||
|
|
|
@ -8,20 +8,20 @@ add_task(async function test() {
|
|||
|
||||
// Add some initial logins
|
||||
let urls = [
|
||||
"http://example.com/",
|
||||
"http://mozilla.org/",
|
||||
"http://spreadfirefox.com/",
|
||||
"https://support.mozilla.org/",
|
||||
"http://hg.mozilla.org/",
|
||||
"http://example.com/",
|
||||
"http://mozilla.org/",
|
||||
"http://spreadfirefox.com/",
|
||||
"https://support.mozilla.org/",
|
||||
"http://hg.mozilla.org/",
|
||||
];
|
||||
let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
|
||||
Ci.nsILoginInfo, "init");
|
||||
let logins = [
|
||||
new nsLoginInfo(urls[0], urls[0], null, "", "o hai", "u1", "p1"),
|
||||
new nsLoginInfo(urls[1], urls[1], null, "ehsan", "coded", "u2", "p2"),
|
||||
new nsLoginInfo(urls[2], urls[2], null, "this", "awesome", "u3", "p3"),
|
||||
new nsLoginInfo(urls[3], urls[3], null, "array of", "logins", "u4", "p4"),
|
||||
new nsLoginInfo(urls[4], urls[4], null, "then", "i wrote the test", "u5", "p5"),
|
||||
new nsLoginInfo(urls[0], urls[0], null, "", "o hai", "u1", "p1"),
|
||||
new nsLoginInfo(urls[1], urls[1], null, "ehsan", "coded", "u2", "p2"),
|
||||
new nsLoginInfo(urls[2], urls[2], null, "this", "awesome", "u3", "p3"),
|
||||
new nsLoginInfo(urls[3], urls[3], null, "array of", "logins", "u4", "p4"),
|
||||
new nsLoginInfo(urls[4], urls[4], null, "then", "i wrote the test", "u5", "p5"),
|
||||
];
|
||||
logins.forEach(login => Services.logins.addLogin(login));
|
||||
|
||||
|
@ -32,86 +32,86 @@ add_task(async function test() {
|
|||
|
||||
// Test if "Copy Username" and "Copy Password" works
|
||||
function doTest() {
|
||||
let doc = pwmgrdlg.document;
|
||||
let selection = doc.getElementById("signonsTree").view.selection;
|
||||
let menuitem = doc.getElementById("context-copyusername");
|
||||
let doc = pwmgrdlg.document;
|
||||
let selection = doc.getElementById("signonsTree").view.selection;
|
||||
let menuitem = doc.getElementById("context-copyusername");
|
||||
|
||||
function copyField() {
|
||||
info("Select all");
|
||||
selection.selectAll();
|
||||
assertMenuitemEnabled("copysiteurl", false);
|
||||
assertMenuitemEnabled("launchsiteurl", false);
|
||||
assertMenuitemEnabled("copyusername", false);
|
||||
assertMenuitemEnabled("editusername", false);
|
||||
assertMenuitemEnabled("copypassword", false);
|
||||
assertMenuitemEnabled("editpassword", false);
|
||||
function copyField() {
|
||||
info("Select all");
|
||||
selection.selectAll();
|
||||
assertMenuitemEnabled("copysiteurl", false);
|
||||
assertMenuitemEnabled("launchsiteurl", false);
|
||||
assertMenuitemEnabled("copyusername", false);
|
||||
assertMenuitemEnabled("editusername", false);
|
||||
assertMenuitemEnabled("copypassword", false);
|
||||
assertMenuitemEnabled("editpassword", false);
|
||||
|
||||
info("Select the first row (with an empty username)");
|
||||
selection.select(0);
|
||||
assertMenuitemEnabled("copysiteurl", true);
|
||||
assertMenuitemEnabled("launchsiteurl", true);
|
||||
assertMenuitemEnabled("copyusername", false, "empty username");
|
||||
assertMenuitemEnabled("editusername", true);
|
||||
assertMenuitemEnabled("copypassword", true);
|
||||
assertMenuitemEnabled("editpassword", false, "password column hidden");
|
||||
info("Select the first row (with an empty username)");
|
||||
selection.select(0);
|
||||
assertMenuitemEnabled("copysiteurl", true);
|
||||
assertMenuitemEnabled("launchsiteurl", true);
|
||||
assertMenuitemEnabled("copyusername", false, "empty username");
|
||||
assertMenuitemEnabled("editusername", true);
|
||||
assertMenuitemEnabled("copypassword", true);
|
||||
assertMenuitemEnabled("editpassword", false, "password column hidden");
|
||||
|
||||
info("Clear the selection");
|
||||
selection.clearSelection();
|
||||
assertMenuitemEnabled("copysiteurl", false);
|
||||
assertMenuitemEnabled("launchsiteurl", false);
|
||||
assertMenuitemEnabled("copyusername", false);
|
||||
assertMenuitemEnabled("editusername", false);
|
||||
assertMenuitemEnabled("copypassword", false);
|
||||
assertMenuitemEnabled("editpassword", false);
|
||||
info("Clear the selection");
|
||||
selection.clearSelection();
|
||||
assertMenuitemEnabled("copysiteurl", false);
|
||||
assertMenuitemEnabled("launchsiteurl", false);
|
||||
assertMenuitemEnabled("copyusername", false);
|
||||
assertMenuitemEnabled("editusername", false);
|
||||
assertMenuitemEnabled("copypassword", false);
|
||||
assertMenuitemEnabled("editpassword", false);
|
||||
|
||||
info("Select the third row and making the password column visible");
|
||||
selection.select(2);
|
||||
doc.getElementById("passwordCol").hidden = false;
|
||||
assertMenuitemEnabled("copysiteurl", true);
|
||||
assertMenuitemEnabled("launchsiteurl", true);
|
||||
assertMenuitemEnabled("copyusername", true);
|
||||
assertMenuitemEnabled("editusername", true);
|
||||
assertMenuitemEnabled("copypassword", true);
|
||||
assertMenuitemEnabled("editpassword", true, "password column visible");
|
||||
info("Select the third row and making the password column visible");
|
||||
selection.select(2);
|
||||
doc.getElementById("passwordCol").hidden = false;
|
||||
assertMenuitemEnabled("copysiteurl", true);
|
||||
assertMenuitemEnabled("launchsiteurl", true);
|
||||
assertMenuitemEnabled("copyusername", true);
|
||||
assertMenuitemEnabled("editusername", true);
|
||||
assertMenuitemEnabled("copypassword", true);
|
||||
assertMenuitemEnabled("editpassword", true, "password column visible");
|
||||
|
||||
menuitem.doCommand();
|
||||
}
|
||||
menuitem.doCommand();
|
||||
}
|
||||
|
||||
function assertMenuitemEnabled(idSuffix, expected, reason = "") {
|
||||
doc.defaultView.UpdateContextMenu();
|
||||
let actual = !doc.getElementById("context-" + idSuffix).getAttribute("disabled");
|
||||
is(actual, expected, idSuffix + " should be " + (expected ? "enabled" : "disabled") +
|
||||
(reason ? ": " + reason : ""));
|
||||
}
|
||||
function assertMenuitemEnabled(idSuffix, expected, reason = "") {
|
||||
doc.defaultView.UpdateContextMenu();
|
||||
let actual = !doc.getElementById("context-" + idSuffix).getAttribute("disabled");
|
||||
is(actual, expected, idSuffix + " should be " + (expected ? "enabled" : "disabled") +
|
||||
(reason ? ": " + reason : ""));
|
||||
}
|
||||
|
||||
function cleanUp() {
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
Services.ww.unregisterNotification(notification);
|
||||
Services.logins.removeAllLogins();
|
||||
doc.getElementById("passwordCol").hidden = true;
|
||||
resolve();
|
||||
});
|
||||
pwmgrdlg.close();
|
||||
}
|
||||
function cleanUp() {
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
Services.ww.unregisterNotification(notification);
|
||||
Services.logins.removeAllLogins();
|
||||
doc.getElementById("passwordCol").hidden = true;
|
||||
resolve();
|
||||
});
|
||||
pwmgrdlg.close();
|
||||
}
|
||||
|
||||
function testSiteUrl() {
|
||||
info("Testing Copy Site URL");
|
||||
waitForClipboard("http://mozilla.org/", function copySiteUrl() {
|
||||
menuitem = doc.getElementById("context-copysiteurl");
|
||||
menuitem.doCommand();
|
||||
}, cleanUp, cleanUp);
|
||||
}
|
||||
function testSiteUrl() {
|
||||
info("Testing Copy Site URL");
|
||||
waitForClipboard("http://mozilla.org/", function copySiteUrl() {
|
||||
menuitem = doc.getElementById("context-copysiteurl");
|
||||
menuitem.doCommand();
|
||||
}, cleanUp, cleanUp);
|
||||
}
|
||||
|
||||
function testPassword() {
|
||||
info("Testing Copy Password");
|
||||
waitForClipboard("coded", function copyPassword() {
|
||||
menuitem = doc.getElementById("context-copypassword");
|
||||
menuitem.doCommand();
|
||||
}, testSiteUrl, testSiteUrl);
|
||||
}
|
||||
function testPassword() {
|
||||
info("Testing Copy Password");
|
||||
waitForClipboard("coded", function copyPassword() {
|
||||
menuitem = doc.getElementById("context-copypassword");
|
||||
menuitem.doCommand();
|
||||
}, testSiteUrl, testSiteUrl);
|
||||
}
|
||||
|
||||
info("Testing Copy Username");
|
||||
waitForClipboard("ehsan", copyField, testPassword, testPassword);
|
||||
info("Testing Copy Username");
|
||||
waitForClipboard("ehsan", copyField, testPassword, testPassword);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,61 +5,61 @@
|
|||
add_task(async function test() {
|
||||
await new Promise(resolve => {
|
||||
|
||||
Services.logins.removeAllLogins();
|
||||
Services.logins.removeAllLogins();
|
||||
|
||||
// add login data
|
||||
let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
|
||||
// add login data
|
||||
let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
|
||||
Ci.nsILoginInfo, "init");
|
||||
let login = new nsLoginInfo("http://example.com/", "http://example.com/", null,
|
||||
"user", "password", "u1", "p1");
|
||||
Services.logins.addLogin(login);
|
||||
let login = new nsLoginInfo("http://example.com/", "http://example.com/", null,
|
||||
"user", "password", "u1", "p1");
|
||||
Services.logins.addLogin(login);
|
||||
|
||||
// Open the password manager dialog
|
||||
const PWMGR_DLG = "chrome://passwordmgr/content/passwordManager.xul";
|
||||
let pwmgrdlg = window.openDialog(PWMGR_DLG, "Toolkit:PasswordManager", "");
|
||||
SimpleTest.waitForFocus(doTest, pwmgrdlg);
|
||||
// Open the password manager dialog
|
||||
const PWMGR_DLG = "chrome://passwordmgr/content/passwordManager.xul";
|
||||
let pwmgrdlg = window.openDialog(PWMGR_DLG, "Toolkit:PasswordManager", "");
|
||||
SimpleTest.waitForFocus(doTest, pwmgrdlg);
|
||||
|
||||
function doTest() {
|
||||
let doc = pwmgrdlg.document;
|
||||
function doTest() {
|
||||
let doc = pwmgrdlg.document;
|
||||
|
||||
let signonsTree = doc.querySelector("#signonsTree");
|
||||
is(signonsTree.view.rowCount, 1, "One entry in the passwords list");
|
||||
let signonsTree = doc.querySelector("#signonsTree");
|
||||
is(signonsTree.view.rowCount, 1, "One entry in the passwords list");
|
||||
|
||||
is(signonsTree.view.getCellText(0, signonsTree.columns.getNamedColumn("siteCol")),
|
||||
"http://example.com/",
|
||||
"Correct website saved");
|
||||
is(signonsTree.view.getCellText(0, signonsTree.columns.getNamedColumn("siteCol")),
|
||||
"http://example.com/",
|
||||
"Correct website saved");
|
||||
|
||||
is(signonsTree.view.getCellText(0, signonsTree.columns.getNamedColumn("userCol")),
|
||||
"user",
|
||||
"Correct user saved");
|
||||
is(signonsTree.view.getCellText(0, signonsTree.columns.getNamedColumn("userCol")),
|
||||
"user",
|
||||
"Correct user saved");
|
||||
|
||||
let timeCreatedCol = doc.getElementById("timeCreatedCol");
|
||||
is(timeCreatedCol.getAttribute("hidden"), "true",
|
||||
"Time created column is not displayed");
|
||||
let timeCreatedCol = doc.getElementById("timeCreatedCol");
|
||||
is(timeCreatedCol.getAttribute("hidden"), "true",
|
||||
"Time created column is not displayed");
|
||||
|
||||
|
||||
let timeLastUsedCol = doc.getElementById("timeLastUsedCol");
|
||||
is(timeLastUsedCol.getAttribute("hidden"), "true",
|
||||
"Last Used column is not displayed");
|
||||
let timeLastUsedCol = doc.getElementById("timeLastUsedCol");
|
||||
is(timeLastUsedCol.getAttribute("hidden"), "true",
|
||||
"Last Used column is not displayed");
|
||||
|
||||
let timePasswordChangedCol = doc.getElementById("timePasswordChangedCol");
|
||||
is(timePasswordChangedCol.getAttribute("hidden"), "",
|
||||
"Last Changed column is displayed");
|
||||
let timePasswordChangedCol = doc.getElementById("timePasswordChangedCol");
|
||||
is(timePasswordChangedCol.getAttribute("hidden"), "",
|
||||
"Last Changed column is displayed");
|
||||
|
||||
// cleanup
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
if (aSubject.location == pwmgrdlg.location && aTopic == "domwindowclosed") {
|
||||
// cleanup
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
if (aSubject.location == pwmgrdlg.location && aTopic == "domwindowclosed") {
|
||||
// unregister ourself
|
||||
Services.ww.unregisterNotification(notification);
|
||||
Services.ww.unregisterNotification(notification);
|
||||
|
||||
Services.logins.removeAllLogins();
|
||||
Services.logins.removeAllLogins();
|
||||
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
|
||||
pwmgrdlg.close();
|
||||
}
|
||||
pwmgrdlg.close();
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,128 +4,128 @@
|
|||
add_task(async function test() {
|
||||
await new Promise(resolve => {
|
||||
|
||||
const LOGIN_HOST = "http://example.com";
|
||||
const LOGIN_COUNT = 5;
|
||||
const LOGIN_HOST = "http://example.com";
|
||||
const LOGIN_COUNT = 5;
|
||||
|
||||
let nsLoginInfo = new Components.Constructor(
|
||||
"@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo, "init");
|
||||
let pmDialog = window.openDialog(
|
||||
"chrome://passwordmgr/content/passwordManager.xul",
|
||||
"Toolkit:PasswordManager", "");
|
||||
let nsLoginInfo = new Components.Constructor(
|
||||
"@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo, "init");
|
||||
let pmDialog = window.openDialog(
|
||||
"chrome://passwordmgr/content/passwordManager.xul",
|
||||
"Toolkit:PasswordManager", "");
|
||||
|
||||
let logins = [];
|
||||
let loginCounter = 0;
|
||||
let loginOrder = null;
|
||||
let modifiedLogin;
|
||||
let testNumber = 0;
|
||||
let testObserver = {
|
||||
observe(subject, topic, data) {
|
||||
if (topic == "passwordmgr-dialog-updated") {
|
||||
switch (testNumber) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
is(countLogins(), loginCounter, "Verify login added");
|
||||
ok(getLoginOrder().startsWith(loginOrder), "Verify login order");
|
||||
runNextTest();
|
||||
break;
|
||||
case 6:
|
||||
is(countLogins(), loginCounter, "Verify login count");
|
||||
is(getLoginOrder(), loginOrder, "Verify login order");
|
||||
is(getLoginPassword(), "newpassword0", "Verify login modified");
|
||||
runNextTest();
|
||||
break;
|
||||
case 7:
|
||||
is(countLogins(), loginCounter, "Verify login removed");
|
||||
ok(loginOrder.endsWith(getLoginOrder()), "Verify login order");
|
||||
runNextTest();
|
||||
break;
|
||||
case 8:
|
||||
is(countLogins(), 0, "Verify all logins removed");
|
||||
runNextTest();
|
||||
break;
|
||||
let logins = [];
|
||||
let loginCounter = 0;
|
||||
let loginOrder = null;
|
||||
let modifiedLogin;
|
||||
let testNumber = 0;
|
||||
let testObserver = {
|
||||
observe(subject, topic, data) {
|
||||
if (topic == "passwordmgr-dialog-updated") {
|
||||
switch (testNumber) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 4:
|
||||
case 5:
|
||||
is(countLogins(), loginCounter, "Verify login added");
|
||||
ok(getLoginOrder().startsWith(loginOrder), "Verify login order");
|
||||
runNextTest();
|
||||
break;
|
||||
case 6:
|
||||
is(countLogins(), loginCounter, "Verify login count");
|
||||
is(getLoginOrder(), loginOrder, "Verify login order");
|
||||
is(getLoginPassword(), "newpassword0", "Verify login modified");
|
||||
runNextTest();
|
||||
break;
|
||||
case 7:
|
||||
is(countLogins(), loginCounter, "Verify login removed");
|
||||
ok(loginOrder.endsWith(getLoginOrder()), "Verify login order");
|
||||
runNextTest();
|
||||
break;
|
||||
case 8:
|
||||
is(countLogins(), 0, "Verify all logins removed");
|
||||
runNextTest();
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
SimpleTest.waitForFocus(startTest, pmDialog);
|
||||
|
||||
function createLogins() {
|
||||
let login;
|
||||
for (let i = 0; i < LOGIN_COUNT; i++) {
|
||||
login = new nsLoginInfo(LOGIN_HOST + "?n=" + i, LOGIN_HOST + "?n=" + i,
|
||||
null, "user" + i, "password" + i, "u" + i, "p" + i);
|
||||
logins.push(login);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
SimpleTest.waitForFocus(startTest, pmDialog);
|
||||
|
||||
function createLogins() {
|
||||
let login;
|
||||
for (let i = 0; i < LOGIN_COUNT; i++) {
|
||||
login = new nsLoginInfo(LOGIN_HOST + "?n=" + i, LOGIN_HOST + "?n=" + i,
|
||||
null, "user" + i, "password" + i, "u" + i, "p" + i);
|
||||
logins.push(login);
|
||||
modifiedLogin = new nsLoginInfo(LOGIN_HOST + "?n=0", LOGIN_HOST + "?n=0",
|
||||
null, "user0", "newpassword0", "u0", "p0");
|
||||
is(logins.length, LOGIN_COUNT, "Verify logins created");
|
||||
}
|
||||
modifiedLogin = new nsLoginInfo(LOGIN_HOST + "?n=0", LOGIN_HOST + "?n=0",
|
||||
null, "user0", "newpassword0", "u0", "p0");
|
||||
is(logins.length, LOGIN_COUNT, "Verify logins created");
|
||||
}
|
||||
|
||||
function countLogins() {
|
||||
let doc = pmDialog.document;
|
||||
let signonsTree = doc.getElementById("signonsTree");
|
||||
return signonsTree.view.rowCount;
|
||||
}
|
||||
|
||||
function getLoginOrder() {
|
||||
let doc = pmDialog.document;
|
||||
let signonsTree = doc.getElementById("signonsTree");
|
||||
let column = signonsTree.columns[0]; // host column
|
||||
let order = [];
|
||||
for (let i = 0; i < signonsTree.view.rowCount; i++) {
|
||||
order.push(signonsTree.view.getCellText(i, column));
|
||||
function countLogins() {
|
||||
let doc = pmDialog.document;
|
||||
let signonsTree = doc.getElementById("signonsTree");
|
||||
return signonsTree.view.rowCount;
|
||||
}
|
||||
return order.join(",");
|
||||
}
|
||||
|
||||
function getLoginPassword() {
|
||||
let doc = pmDialog.document;
|
||||
let loginsTree = doc.getElementById("signonsTree");
|
||||
let column = loginsTree.columns[2]; // password column
|
||||
return loginsTree.view.getCellText(0, column);
|
||||
}
|
||||
function getLoginOrder() {
|
||||
let doc = pmDialog.document;
|
||||
let signonsTree = doc.getElementById("signonsTree");
|
||||
let column = signonsTree.columns[0]; // host column
|
||||
let order = [];
|
||||
for (let i = 0; i < signonsTree.view.rowCount; i++) {
|
||||
order.push(signonsTree.view.getCellText(i, column));
|
||||
}
|
||||
return order.join(",");
|
||||
}
|
||||
|
||||
function startTest() {
|
||||
Services.obs.addObserver(
|
||||
testObserver, "passwordmgr-dialog-updated");
|
||||
is(countLogins(), 0, "Verify starts with 0 logins");
|
||||
createLogins();
|
||||
runNextTest();
|
||||
}
|
||||
function getLoginPassword() {
|
||||
let doc = pmDialog.document;
|
||||
let loginsTree = doc.getElementById("signonsTree");
|
||||
let column = loginsTree.columns[2]; // password column
|
||||
return loginsTree.view.getCellText(0, column);
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
switch (++testNumber) {
|
||||
case 1: // add the logins
|
||||
for (let i = 0; i < logins.length; i++) {
|
||||
loginCounter++;
|
||||
function startTest() {
|
||||
Services.obs.addObserver(
|
||||
testObserver, "passwordmgr-dialog-updated");
|
||||
is(countLogins(), 0, "Verify starts with 0 logins");
|
||||
createLogins();
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
switch (++testNumber) {
|
||||
case 1: // add the logins
|
||||
for (let i = 0; i < logins.length; i++) {
|
||||
loginCounter++;
|
||||
loginOrder = getLoginOrder();
|
||||
Services.logins.addLogin(logins[i]);
|
||||
}
|
||||
break;
|
||||
case 6: // modify a login
|
||||
loginOrder = getLoginOrder();
|
||||
Services.logins.addLogin(logins[i]);
|
||||
}
|
||||
break;
|
||||
case 6: // modify a login
|
||||
loginOrder = getLoginOrder();
|
||||
Services.logins.modifyLogin(logins[0], modifiedLogin);
|
||||
break;
|
||||
case 7: // remove a login
|
||||
loginCounter--;
|
||||
loginOrder = getLoginOrder();
|
||||
Services.logins.removeLogin(modifiedLogin);
|
||||
break;
|
||||
case 8: // remove all logins
|
||||
Services.logins.removeAllLogins();
|
||||
break;
|
||||
case 9: // finish
|
||||
Services.obs.removeObserver(
|
||||
testObserver, "passwordmgr-dialog-updated");
|
||||
pmDialog.close();
|
||||
resolve();
|
||||
break;
|
||||
Services.logins.modifyLogin(logins[0], modifiedLogin);
|
||||
break;
|
||||
case 7: // remove a login
|
||||
loginCounter--;
|
||||
loginOrder = getLoginOrder();
|
||||
Services.logins.removeLogin(modifiedLogin);
|
||||
break;
|
||||
case 8: // remove all logins
|
||||
Services.logins.removeAllLogins();
|
||||
break;
|
||||
case 9: // finish
|
||||
Services.obs.removeObserver(
|
||||
testObserver, "passwordmgr-dialog-updated");
|
||||
pmDialog.close();
|
||||
resolve();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,40 +8,40 @@ add_task(async function test() {
|
|||
|
||||
// Add some initial logins
|
||||
let urls = [
|
||||
"http://example.com/",
|
||||
"http://example.org/",
|
||||
"http://mozilla.com/",
|
||||
"http://mozilla.org/",
|
||||
"http://spreadfirefox.com/",
|
||||
"http://planet.mozilla.org/",
|
||||
"https://developer.mozilla.org/",
|
||||
"http://hg.mozilla.org/",
|
||||
"http://dxr.mozilla.org/",
|
||||
"http://feeds.mozilla.org/",
|
||||
"http://example.com/",
|
||||
"http://example.org/",
|
||||
"http://mozilla.com/",
|
||||
"http://mozilla.org/",
|
||||
"http://spreadfirefox.com/",
|
||||
"http://planet.mozilla.org/",
|
||||
"https://developer.mozilla.org/",
|
||||
"http://hg.mozilla.org/",
|
||||
"http://dxr.mozilla.org/",
|
||||
"http://feeds.mozilla.org/",
|
||||
];
|
||||
let users = [
|
||||
"user",
|
||||
"username",
|
||||
"ehsan",
|
||||
"ehsan",
|
||||
"john",
|
||||
"what?",
|
||||
"really?",
|
||||
"you sure?",
|
||||
"my user name",
|
||||
"my username",
|
||||
"user",
|
||||
"username",
|
||||
"ehsan",
|
||||
"ehsan",
|
||||
"john",
|
||||
"what?",
|
||||
"really?",
|
||||
"you sure?",
|
||||
"my user name",
|
||||
"my username",
|
||||
];
|
||||
let pwds = [
|
||||
"password",
|
||||
"password",
|
||||
"mypass",
|
||||
"mypass",
|
||||
"smith",
|
||||
"very secret",
|
||||
"super secret",
|
||||
"absolutely",
|
||||
"mozilla",
|
||||
"mozilla.com",
|
||||
"password",
|
||||
"password",
|
||||
"mypass",
|
||||
"mypass",
|
||||
"smith",
|
||||
"very secret",
|
||||
"super secret",
|
||||
"absolutely",
|
||||
"mozilla",
|
||||
"mozilla.com",
|
||||
];
|
||||
let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
|
||||
Ci.nsILoginInfo, "init");
|
||||
|
@ -56,151 +56,151 @@ add_task(async function test() {
|
|||
|
||||
// the meat of the test
|
||||
function doTest() {
|
||||
let doc = pwmgrdlg.document;
|
||||
let win = doc.defaultView;
|
||||
let sTree = doc.getElementById("signonsTree");
|
||||
let filter = doc.getElementById("filter");
|
||||
let siteCol = doc.getElementById("siteCol");
|
||||
let userCol = doc.getElementById("userCol");
|
||||
let passwordCol = doc.getElementById("passwordCol");
|
||||
let doc = pwmgrdlg.document;
|
||||
let win = doc.defaultView;
|
||||
let sTree = doc.getElementById("signonsTree");
|
||||
let filter = doc.getElementById("filter");
|
||||
let siteCol = doc.getElementById("siteCol");
|
||||
let userCol = doc.getElementById("userCol");
|
||||
let passwordCol = doc.getElementById("passwordCol");
|
||||
|
||||
let toggleCalls = 0;
|
||||
function toggleShowPasswords(func) {
|
||||
let toggleButton = doc.getElementById("togglePasswords");
|
||||
let showMode = (toggleCalls++ % 2) == 0;
|
||||
let toggleCalls = 0;
|
||||
function toggleShowPasswords(func) {
|
||||
let toggleButton = doc.getElementById("togglePasswords");
|
||||
let showMode = (toggleCalls++ % 2) == 0;
|
||||
|
||||
// only watch for a confirmation dialog every other time being called
|
||||
if (showMode) {
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowclosed")
|
||||
Services.ww.unregisterNotification(notification);
|
||||
else if (aTopic == "domwindowopened") {
|
||||
let targetWin = aSubject;
|
||||
SimpleTest.waitForFocus(function() {
|
||||
EventUtils.sendKey("RETURN", targetWin);
|
||||
}, targetWin);
|
||||
}
|
||||
});
|
||||
// only watch for a confirmation dialog every other time being called
|
||||
if (showMode) {
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowclosed")
|
||||
Services.ww.unregisterNotification(notification);
|
||||
else if (aTopic == "domwindowopened") {
|
||||
let targetWin = aSubject;
|
||||
SimpleTest.waitForFocus(function() {
|
||||
EventUtils.sendKey("RETURN", targetWin);
|
||||
}, targetWin);
|
||||
}
|
||||
|
||||
Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
|
||||
if (aTopic == "passwordmgr-password-toggle-complete") {
|
||||
Services.obs.removeObserver(observer, aTopic);
|
||||
func();
|
||||
}
|
||||
}, "passwordmgr-password-toggle-complete");
|
||||
|
||||
EventUtils.synthesizeMouse(toggleButton, 1, 1, {}, win);
|
||||
});
|
||||
}
|
||||
|
||||
function clickCol(col) {
|
||||
EventUtils.synthesizeMouse(col, 20, 1, {}, win);
|
||||
setTimeout(runNextTest, 0);
|
||||
Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
|
||||
if (aTopic == "passwordmgr-password-toggle-complete") {
|
||||
Services.obs.removeObserver(observer, aTopic);
|
||||
func();
|
||||
}
|
||||
}, "passwordmgr-password-toggle-complete");
|
||||
|
||||
EventUtils.synthesizeMouse(toggleButton, 1, 1, {}, win);
|
||||
}
|
||||
|
||||
function clickCol(col) {
|
||||
EventUtils.synthesizeMouse(col, 20, 1, {}, win);
|
||||
setTimeout(runNextTest, 0);
|
||||
}
|
||||
|
||||
function setFilter(string) {
|
||||
filter.value = string;
|
||||
filter.doCommand();
|
||||
setTimeout(runNextTest, 0);
|
||||
}
|
||||
|
||||
function checkSortMarkers(activeCol) {
|
||||
let isOk = true;
|
||||
let col = null;
|
||||
let hasAttr = false;
|
||||
let treecols = activeCol.parentNode;
|
||||
for (let i = 0; i < treecols.childNodes.length; i++) {
|
||||
col = treecols.childNodes[i];
|
||||
if (col.nodeName != "treecol")
|
||||
continue;
|
||||
hasAttr = col.hasAttribute("sortDirection");
|
||||
isOk &= col == activeCol ? hasAttr : !hasAttr;
|
||||
}
|
||||
ok(isOk, "Only " + activeCol.id + " has a sort marker");
|
||||
}
|
||||
|
||||
function setFilter(string) {
|
||||
filter.value = string;
|
||||
filter.doCommand();
|
||||
setTimeout(runNextTest, 0);
|
||||
function checkSortDirection(col, ascending) {
|
||||
checkSortMarkers(col);
|
||||
let direction = ascending ? "ascending" : "descending";
|
||||
is(col.getAttribute("sortDirection"), direction,
|
||||
col.id + ": sort direction is " + direction);
|
||||
}
|
||||
|
||||
function checkColumnEntries(aCol, expectedValues) {
|
||||
let actualValues = getColumnEntries(aCol);
|
||||
is(actualValues.length, expectedValues.length, "Checking length of expected column");
|
||||
for (let i = 0; i < expectedValues.length; i++)
|
||||
is(actualValues[i], expectedValues[i], "Checking column entry #" + i);
|
||||
}
|
||||
|
||||
function getColumnEntries(aCol) {
|
||||
let entries = [];
|
||||
let column = sTree.columns[aCol];
|
||||
let numRows = sTree.view.rowCount;
|
||||
for (let i = 0; i < numRows; i++)
|
||||
entries.push(sTree.view.getCellText(i, column));
|
||||
return entries;
|
||||
}
|
||||
|
||||
let testCounter = 0;
|
||||
let expectedValues;
|
||||
function runNextTest() {
|
||||
switch (testCounter++) {
|
||||
case 0:
|
||||
expectedValues = urls.slice().sort();
|
||||
checkColumnEntries(0, expectedValues);
|
||||
checkSortDirection(siteCol, true);
|
||||
// Toggle sort direction on Host column
|
||||
clickCol(siteCol);
|
||||
break;
|
||||
case 1:
|
||||
expectedValues.reverse();
|
||||
checkColumnEntries(0, expectedValues);
|
||||
checkSortDirection(siteCol, false);
|
||||
// Sort by Username
|
||||
clickCol(userCol);
|
||||
break;
|
||||
case 2:
|
||||
expectedValues = users.slice().sort();
|
||||
checkColumnEntries(1, expectedValues);
|
||||
checkSortDirection(userCol, true);
|
||||
// Sort by Password
|
||||
clickCol(passwordCol);
|
||||
break;
|
||||
case 3:
|
||||
expectedValues = pwds.slice().sort();
|
||||
checkColumnEntries(2, expectedValues);
|
||||
checkSortDirection(passwordCol, true);
|
||||
// Set filter
|
||||
setFilter("moz");
|
||||
break;
|
||||
case 4:
|
||||
expectedValues = [ "absolutely", "mozilla", "mozilla.com",
|
||||
"mypass", "mypass", "super secret",
|
||||
"very secret" ];
|
||||
checkColumnEntries(2, expectedValues);
|
||||
checkSortDirection(passwordCol, true);
|
||||
// Reset filter
|
||||
setFilter("");
|
||||
break;
|
||||
case 5:
|
||||
expectedValues = pwds.slice().sort();
|
||||
checkColumnEntries(2, expectedValues);
|
||||
checkSortDirection(passwordCol, true);
|
||||
// cleanup
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
// unregister ourself
|
||||
Services.ww.unregisterNotification(notification);
|
||||
|
||||
Services.logins.removeAllLogins();
|
||||
resolve();
|
||||
});
|
||||
pwmgrdlg.close();
|
||||
}
|
||||
}
|
||||
|
||||
function checkSortMarkers(activeCol) {
|
||||
let isOk = true;
|
||||
let col = null;
|
||||
let hasAttr = false;
|
||||
let treecols = activeCol.parentNode;
|
||||
for (let i = 0; i < treecols.childNodes.length; i++) {
|
||||
col = treecols.childNodes[i];
|
||||
if (col.nodeName != "treecol")
|
||||
continue;
|
||||
hasAttr = col.hasAttribute("sortDirection");
|
||||
isOk &= col == activeCol ? hasAttr : !hasAttr;
|
||||
}
|
||||
ok(isOk, "Only " + activeCol.id + " has a sort marker");
|
||||
}
|
||||
|
||||
function checkSortDirection(col, ascending) {
|
||||
checkSortMarkers(col);
|
||||
let direction = ascending ? "ascending" : "descending";
|
||||
is(col.getAttribute("sortDirection"), direction,
|
||||
col.id + ": sort direction is " + direction);
|
||||
}
|
||||
|
||||
function checkColumnEntries(aCol, expectedValues) {
|
||||
let actualValues = getColumnEntries(aCol);
|
||||
is(actualValues.length, expectedValues.length, "Checking length of expected column");
|
||||
for (let i = 0; i < expectedValues.length; i++)
|
||||
is(actualValues[i], expectedValues[i], "Checking column entry #" + i);
|
||||
}
|
||||
|
||||
function getColumnEntries(aCol) {
|
||||
let entries = [];
|
||||
let column = sTree.columns[aCol];
|
||||
let numRows = sTree.view.rowCount;
|
||||
for (let i = 0; i < numRows; i++)
|
||||
entries.push(sTree.view.getCellText(i, column));
|
||||
return entries;
|
||||
}
|
||||
|
||||
let testCounter = 0;
|
||||
let expectedValues;
|
||||
function runNextTest() {
|
||||
switch (testCounter++) {
|
||||
case 0:
|
||||
expectedValues = urls.slice().sort();
|
||||
checkColumnEntries(0, expectedValues);
|
||||
checkSortDirection(siteCol, true);
|
||||
// Toggle sort direction on Host column
|
||||
clickCol(siteCol);
|
||||
break;
|
||||
case 1:
|
||||
expectedValues.reverse();
|
||||
checkColumnEntries(0, expectedValues);
|
||||
checkSortDirection(siteCol, false);
|
||||
// Sort by Username
|
||||
clickCol(userCol);
|
||||
break;
|
||||
case 2:
|
||||
expectedValues = users.slice().sort();
|
||||
checkColumnEntries(1, expectedValues);
|
||||
checkSortDirection(userCol, true);
|
||||
// Sort by Password
|
||||
clickCol(passwordCol);
|
||||
break;
|
||||
case 3:
|
||||
expectedValues = pwds.slice().sort();
|
||||
checkColumnEntries(2, expectedValues);
|
||||
checkSortDirection(passwordCol, true);
|
||||
// Set filter
|
||||
setFilter("moz");
|
||||
break;
|
||||
case 4:
|
||||
expectedValues = [ "absolutely", "mozilla", "mozilla.com",
|
||||
"mypass", "mypass", "super secret",
|
||||
"very secret" ];
|
||||
checkColumnEntries(2, expectedValues);
|
||||
checkSortDirection(passwordCol, true);
|
||||
// Reset filter
|
||||
setFilter("");
|
||||
break;
|
||||
case 5:
|
||||
expectedValues = pwds.slice().sort();
|
||||
checkColumnEntries(2, expectedValues);
|
||||
checkSortDirection(passwordCol, true);
|
||||
// cleanup
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
// unregister ourself
|
||||
Services.ww.unregisterNotification(notification);
|
||||
|
||||
Services.logins.removeAllLogins();
|
||||
resolve();
|
||||
});
|
||||
pwmgrdlg.close();
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle Show Passwords to display Password column, then start tests
|
||||
toggleShowPasswords(runNextTest);
|
||||
// Toggle Show Passwords to display Password column, then start tests
|
||||
toggleShowPasswords(runNextTest);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,34 +7,34 @@ const PROMPT_URL = "chrome://global/content/commonDialog.xul";
|
|||
add_task(async function test() {
|
||||
await new Promise(resolve => {
|
||||
|
||||
let tab = BrowserTestUtils.addTab(gBrowser);
|
||||
isnot(tab, gBrowser.selectedTab, "New tab shouldn't be selected");
|
||||
let tab = BrowserTestUtils.addTab(gBrowser);
|
||||
isnot(tab, gBrowser.selectedTab, "New tab shouldn't be selected");
|
||||
|
||||
let listener = {
|
||||
onOpenWindow(xulWin) {
|
||||
var domwindow = xulWin.docShell.domWindow;
|
||||
waitForFocus(() => {
|
||||
is(domwindow.document.location.href, PROMPT_URL, "Should have seen a prompt window");
|
||||
is(domwindow.args.promptType, "promptUserAndPass", "Should be an authenticate prompt");
|
||||
let listener = {
|
||||
onOpenWindow(xulWin) {
|
||||
var domwindow = xulWin.docShell.domWindow;
|
||||
waitForFocus(() => {
|
||||
is(domwindow.document.location.href, PROMPT_URL, "Should have seen a prompt window");
|
||||
is(domwindow.args.promptType, "promptUserAndPass", "Should be an authenticate prompt");
|
||||
|
||||
is(gBrowser.selectedTab, tab, "Should have selected the new tab");
|
||||
is(gBrowser.selectedTab, tab, "Should have selected the new tab");
|
||||
|
||||
domwindow.document.documentElement.cancelDialog();
|
||||
}, domwindow);
|
||||
},
|
||||
domwindow.document.documentElement.cancelDialog();
|
||||
}, domwindow);
|
||||
},
|
||||
|
||||
onCloseWindow() {
|
||||
},
|
||||
};
|
||||
onCloseWindow() {
|
||||
},
|
||||
};
|
||||
|
||||
Services.wm.addListener(listener);
|
||||
registerCleanupFunction(() => {
|
||||
Services.wm.removeListener(listener);
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
Services.wm.addListener(listener);
|
||||
registerCleanupFunction(() => {
|
||||
Services.wm.removeListener(listener);
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => finish());
|
||||
BrowserTestUtils.loadURI(tab.linkedBrowser, "http://example.com/browser/toolkit/components/passwordmgr/test/browser/authenticate.sjs");
|
||||
BrowserTestUtils.browserLoaded(tab.linkedBrowser).then(() => finish());
|
||||
BrowserTestUtils.loadURI(tab.linkedBrowser, "http://example.com/browser/toolkit/components/passwordmgr/test/browser/authenticate.sjs");
|
||||
|
||||
});
|
||||
});
|
||||
|
|
|
@ -8,30 +8,30 @@ add_task(async function test() {
|
|||
|
||||
// Add some initial logins
|
||||
let urls = [
|
||||
"http://example.com/",
|
||||
"http://example.org/",
|
||||
"http://mozilla.com/",
|
||||
"http://mozilla.org/",
|
||||
"http://spreadfirefox.com/",
|
||||
"http://planet.mozilla.org/",
|
||||
"https://developer.mozilla.org/",
|
||||
"http://hg.mozilla.org/",
|
||||
"http://dxr.mozilla.org/",
|
||||
"http://feeds.mozilla.org/",
|
||||
"http://example.com/",
|
||||
"http://example.org/",
|
||||
"http://mozilla.com/",
|
||||
"http://mozilla.org/",
|
||||
"http://spreadfirefox.com/",
|
||||
"http://planet.mozilla.org/",
|
||||
"https://developer.mozilla.org/",
|
||||
"http://hg.mozilla.org/",
|
||||
"http://dxr.mozilla.org/",
|
||||
"http://feeds.mozilla.org/",
|
||||
];
|
||||
let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1",
|
||||
Ci.nsILoginInfo, "init");
|
||||
let logins = [
|
||||
new nsLoginInfo(urls[0], urls[0], null, "user", "password", "u1", "p1"),
|
||||
new nsLoginInfo(urls[1], urls[1], null, "username", "password", "u2", "p2"),
|
||||
new nsLoginInfo(urls[2], urls[2], null, "ehsan", "mypass", "u3", "p3"),
|
||||
new nsLoginInfo(urls[3], urls[3], null, "ehsan", "mypass", "u4", "p4"),
|
||||
new nsLoginInfo(urls[4], urls[4], null, "john", "smith", "u5", "p5"),
|
||||
new nsLoginInfo(urls[5], urls[5], null, "what?", "very secret", "u6", "p6"),
|
||||
new nsLoginInfo(urls[6], urls[6], null, "really?", "super secret", "u7", "p7"),
|
||||
new nsLoginInfo(urls[7], urls[7], null, "you sure?", "absolutely", "u8", "p8"),
|
||||
new nsLoginInfo(urls[8], urls[8], null, "my user name", "mozilla", "u9", "p9"),
|
||||
new nsLoginInfo(urls[9], urls[9], null, "my username", "mozilla.com", "u10", "p10"),
|
||||
new nsLoginInfo(urls[0], urls[0], null, "user", "password", "u1", "p1"),
|
||||
new nsLoginInfo(urls[1], urls[1], null, "username", "password", "u2", "p2"),
|
||||
new nsLoginInfo(urls[2], urls[2], null, "ehsan", "mypass", "u3", "p3"),
|
||||
new nsLoginInfo(urls[3], urls[3], null, "ehsan", "mypass", "u4", "p4"),
|
||||
new nsLoginInfo(urls[4], urls[4], null, "john", "smith", "u5", "p5"),
|
||||
new nsLoginInfo(urls[5], urls[5], null, "what?", "very secret", "u6", "p6"),
|
||||
new nsLoginInfo(urls[6], urls[6], null, "really?", "super secret", "u7", "p7"),
|
||||
new nsLoginInfo(urls[7], urls[7], null, "you sure?", "absolutely", "u8", "p8"),
|
||||
new nsLoginInfo(urls[8], urls[8], null, "my user name", "mozilla", "u9", "p9"),
|
||||
new nsLoginInfo(urls[9], urls[9], null, "my username", "mozilla.com", "u10", "p10"),
|
||||
];
|
||||
logins.forEach(login => Services.logins.addLogin(login));
|
||||
|
||||
|
@ -42,149 +42,149 @@ add_task(async function test() {
|
|||
|
||||
// the meat of the test
|
||||
function doTest() {
|
||||
let doc = pwmgrdlg.document;
|
||||
let win = doc.defaultView;
|
||||
let filter = doc.getElementById("filter");
|
||||
let tree = doc.getElementById("signonsTree");
|
||||
let view = tree.view;
|
||||
let doc = pwmgrdlg.document;
|
||||
let win = doc.defaultView;
|
||||
let filter = doc.getElementById("filter");
|
||||
let tree = doc.getElementById("signonsTree");
|
||||
let view = tree.view;
|
||||
|
||||
is(filter.value, "", "Filter box should initially be empty");
|
||||
is(view.rowCount, 10, "There should be 10 passwords initially");
|
||||
is(filter.value, "", "Filter box should initially be empty");
|
||||
is(view.rowCount, 10, "There should be 10 passwords initially");
|
||||
|
||||
// Prepare a set of tests
|
||||
// filter: the text entered in the filter search box
|
||||
// count: the number of logins which should match the respective filter
|
||||
// count2: the number of logins which should match the respective filter
|
||||
// if the passwords are being shown as well
|
||||
// Note: if a test doesn't have count2 set, count is used instead.
|
||||
let tests = [
|
||||
{filter: "pass", count: 0, count2: 4},
|
||||
{filter: "", count: 10}, // test clearing the filter
|
||||
{filter: "moz", count: 7},
|
||||
{filter: "mozi", count: 7},
|
||||
{filter: "mozil", count: 7},
|
||||
{filter: "mozill", count: 7},
|
||||
{filter: "mozilla", count: 7},
|
||||
{filter: "mozilla.com", count: 1, count2: 2},
|
||||
{filter: "user", count: 4},
|
||||
{filter: "user ", count: 1},
|
||||
{filter: " user", count: 2},
|
||||
{filter: "http", count: 10},
|
||||
{filter: "https", count: 1},
|
||||
{filter: "secret", count: 0, count2: 2},
|
||||
{filter: "secret!", count: 0},
|
||||
];
|
||||
// Prepare a set of tests
|
||||
// filter: the text entered in the filter search box
|
||||
// count: the number of logins which should match the respective filter
|
||||
// count2: the number of logins which should match the respective filter
|
||||
// if the passwords are being shown as well
|
||||
// Note: if a test doesn't have count2 set, count is used instead.
|
||||
let tests = [
|
||||
{filter: "pass", count: 0, count2: 4},
|
||||
{filter: "", count: 10}, // test clearing the filter
|
||||
{filter: "moz", count: 7},
|
||||
{filter: "mozi", count: 7},
|
||||
{filter: "mozil", count: 7},
|
||||
{filter: "mozill", count: 7},
|
||||
{filter: "mozilla", count: 7},
|
||||
{filter: "mozilla.com", count: 1, count2: 2},
|
||||
{filter: "user", count: 4},
|
||||
{filter: "user ", count: 1},
|
||||
{filter: " user", count: 2},
|
||||
{filter: "http", count: 10},
|
||||
{filter: "https", count: 1},
|
||||
{filter: "secret", count: 0, count2: 2},
|
||||
{filter: "secret!", count: 0},
|
||||
];
|
||||
|
||||
let toggleCalls = 0;
|
||||
function toggleShowPasswords(func) {
|
||||
let toggleButton = doc.getElementById("togglePasswords");
|
||||
let showMode = (toggleCalls++ % 2) == 0;
|
||||
let toggleCalls = 0;
|
||||
function toggleShowPasswords(func) {
|
||||
let toggleButton = doc.getElementById("togglePasswords");
|
||||
let showMode = (toggleCalls++ % 2) == 0;
|
||||
|
||||
// only watch for a confirmation dialog every other time being called
|
||||
if (showMode) {
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowclosed")
|
||||
Services.ww.unregisterNotification(notification);
|
||||
else if (aTopic == "domwindowopened") {
|
||||
let targetWin = aSubject;
|
||||
SimpleTest.waitForFocus(function() {
|
||||
EventUtils.sendKey("RETURN", targetWin);
|
||||
}, targetWin);
|
||||
}
|
||||
});
|
||||
// only watch for a confirmation dialog every other time being called
|
||||
if (showMode) {
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
if (aTopic == "domwindowclosed")
|
||||
Services.ww.unregisterNotification(notification);
|
||||
else if (aTopic == "domwindowopened") {
|
||||
let targetWin = aSubject;
|
||||
SimpleTest.waitForFocus(function() {
|
||||
EventUtils.sendKey("RETURN", targetWin);
|
||||
}, targetWin);
|
||||
}
|
||||
|
||||
Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
|
||||
if (aTopic == "passwordmgr-password-toggle-complete") {
|
||||
Services.obs.removeObserver(observer, aTopic);
|
||||
func();
|
||||
}
|
||||
}, "passwordmgr-password-toggle-complete");
|
||||
|
||||
EventUtils.synthesizeMouse(toggleButton, 1, 1, {}, win);
|
||||
});
|
||||
}
|
||||
|
||||
function runTests(mode, endFunction) {
|
||||
let testCounter = 0;
|
||||
Services.obs.addObserver(function observer(aSubject, aTopic, aData) {
|
||||
if (aTopic == "passwordmgr-password-toggle-complete") {
|
||||
Services.obs.removeObserver(observer, aTopic);
|
||||
func();
|
||||
}
|
||||
}, "passwordmgr-password-toggle-complete");
|
||||
|
||||
function setFilter(string) {
|
||||
filter.value = string;
|
||||
filter.doCommand();
|
||||
}
|
||||
EventUtils.synthesizeMouse(toggleButton, 1, 1, {}, win);
|
||||
}
|
||||
|
||||
function runOneTest(testCase) {
|
||||
function tester() {
|
||||
is(view.rowCount, expected, expected + " logins should match '" + testCase.filter + "'");
|
||||
}
|
||||
function runTests(mode, endFunction) {
|
||||
let testCounter = 0;
|
||||
|
||||
let expected;
|
||||
switch (mode) {
|
||||
case 1: // without showing passwords
|
||||
expected = testCase.count;
|
||||
break;
|
||||
case 2: // showing passwords
|
||||
expected = ("count2" in testCase) ? testCase.count2 : testCase.count;
|
||||
break;
|
||||
case 3: // toggle
|
||||
expected = testCase.count;
|
||||
tester();
|
||||
toggleShowPasswords(function() {
|
||||
expected = ("count2" in testCase) ? testCase.count2 : testCase.count;
|
||||
tester();
|
||||
toggleShowPasswords(proceed);
|
||||
});
|
||||
return;
|
||||
}
|
||||
function setFilter(string) {
|
||||
filter.value = string;
|
||||
filter.doCommand();
|
||||
}
|
||||
|
||||
function runOneTest(testCase) {
|
||||
function tester() {
|
||||
is(view.rowCount, expected, expected + " logins should match '" + testCase.filter + "'");
|
||||
}
|
||||
|
||||
let expected;
|
||||
switch (mode) {
|
||||
case 1: // without showing passwords
|
||||
expected = testCase.count;
|
||||
break;
|
||||
case 2: // showing passwords
|
||||
expected = ("count2" in testCase) ? testCase.count2 : testCase.count;
|
||||
break;
|
||||
case 3: // toggle
|
||||
expected = testCase.count;
|
||||
tester();
|
||||
toggleShowPasswords(function() {
|
||||
expected = ("count2" in testCase) ? testCase.count2 : testCase.count;
|
||||
tester();
|
||||
proceed();
|
||||
}
|
||||
|
||||
function proceed() {
|
||||
// run the next test if necessary or proceed with the tests
|
||||
if (testCounter != tests.length)
|
||||
runNextTest();
|
||||
else
|
||||
endFunction();
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
let testCase = tests[testCounter++];
|
||||
setFilter(testCase.filter);
|
||||
setTimeout(runOneTest, 0, testCase);
|
||||
}
|
||||
toggleShowPasswords(proceed);
|
||||
});
|
||||
return;
|
||||
}
|
||||
tester();
|
||||
proceed();
|
||||
}
|
||||
|
||||
function proceed() {
|
||||
// run the next test if necessary or proceed with the tests
|
||||
if (testCounter != tests.length)
|
||||
runNextTest();
|
||||
else
|
||||
endFunction();
|
||||
}
|
||||
|
||||
function step1() {
|
||||
runTests(1, step2);
|
||||
function runNextTest() {
|
||||
let testCase = tests[testCounter++];
|
||||
setFilter(testCase.filter);
|
||||
setTimeout(runOneTest, 0, testCase);
|
||||
}
|
||||
|
||||
function step2() {
|
||||
toggleShowPasswords(function() {
|
||||
runTests(2, step3);
|
||||
});
|
||||
}
|
||||
runNextTest();
|
||||
}
|
||||
|
||||
function step3() {
|
||||
toggleShowPasswords(function() {
|
||||
runTests(3, lastStep);
|
||||
});
|
||||
}
|
||||
function step1() {
|
||||
runTests(1, step2);
|
||||
}
|
||||
|
||||
function lastStep() {
|
||||
// cleanup
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
// unregister ourself
|
||||
Services.ww.unregisterNotification(notification);
|
||||
function step2() {
|
||||
toggleShowPasswords(function() {
|
||||
runTests(2, step3);
|
||||
});
|
||||
}
|
||||
|
||||
Services.logins.removeAllLogins();
|
||||
finish();
|
||||
});
|
||||
pwmgrdlg.close();
|
||||
}
|
||||
function step3() {
|
||||
toggleShowPasswords(function() {
|
||||
runTests(3, lastStep);
|
||||
});
|
||||
}
|
||||
|
||||
step1();
|
||||
function lastStep() {
|
||||
// cleanup
|
||||
Services.ww.registerNotification(function notification(aSubject, aTopic, aData) {
|
||||
// unregister ourself
|
||||
Services.ww.unregisterNotification(notification);
|
||||
|
||||
Services.logins.removeAllLogins();
|
||||
finish();
|
||||
});
|
||||
pwmgrdlg.close();
|
||||
}
|
||||
|
||||
step1();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,16 +10,16 @@ function getSelectDialogDoc() {
|
|||
// var enumerator = Services.wm.getEnumerator("navigator:browser");
|
||||
for (let {docShell} of Services.wm.getEnumerator(null)) {
|
||||
var containedDocShells = docShell.getDocShellEnumerator(
|
||||
docShell.typeChrome,
|
||||
docShell.ENUMERATE_FORWARDS);
|
||||
docShell.typeChrome,
|
||||
docShell.ENUMERATE_FORWARDS);
|
||||
for (let childDocShell of containedDocShells) {
|
||||
// We don't want it if it's not done loading.
|
||||
if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
|
||||
continue;
|
||||
var childDoc = childDocShell.contentViewer.DOMDocument;
|
||||
// We don't want it if it's not done loading.
|
||||
if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
|
||||
continue;
|
||||
var childDoc = childDocShell.contentViewer.DOMDocument;
|
||||
|
||||
if (childDoc.location.href == "chrome://global/content/selectDialog.xul")
|
||||
return childDoc;
|
||||
if (childDoc.location.href == "chrome://global/content/selectDialog.xul")
|
||||
return childDoc;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
* Initialization: for each test, remove any prior notifications.
|
||||
*/
|
||||
function cleanUpPopupNotifications() {
|
||||
var container = getPopupNotifications(window.top);
|
||||
var notes = container._currentNotifications;
|
||||
info(true, "Removing " + notes.length + " popup notifications.");
|
||||
for (var i = notes.length - 1; i >= 0; i--) {
|
||||
notes[i].remove();
|
||||
}
|
||||
var container = getPopupNotifications(window.top);
|
||||
var notes = container._currentNotifications;
|
||||
info(true, "Removing " + notes.length + " popup notifications.");
|
||||
for (var i = notes.length - 1; i >= 0; i--) {
|
||||
notes[i].remove();
|
||||
}
|
||||
}
|
||||
cleanUpPopupNotifications();
|
||||
|
||||
|
@ -17,16 +17,16 @@ cleanUpPopupNotifications();
|
|||
* Fetches the popup notification for the specified window.
|
||||
*/
|
||||
function getPopupNotifications(aWindow) {
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var Cc = SpecialPowers.Cc;
|
||||
ok(Ci != null, "Access Ci");
|
||||
ok(Cc != null, "Access Cc");
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var Cc = SpecialPowers.Cc;
|
||||
ok(Ci != null, "Access Ci");
|
||||
ok(Cc != null, "Access Cc");
|
||||
|
||||
var chromeWin =
|
||||
var chromeWin =
|
||||
SpecialPowers.wrap(aWindow).docShell.chromeEventHandler.ownerGlobal;
|
||||
|
||||
var popupNotifications = chromeWin.PopupNotifications;
|
||||
return popupNotifications;
|
||||
var popupNotifications = chromeWin.PopupNotifications;
|
||||
return popupNotifications;
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,17 +38,17 @@ function getPopupNotifications(aWindow) {
|
|||
* @returns the found password popup notification.
|
||||
*/
|
||||
function getPopup(aPopupNote, aKind) {
|
||||
ok(true, "Looking for " + aKind + " popup notification");
|
||||
var notification = aPopupNote.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.");
|
||||
}
|
||||
ok(true, "Looking for " + aKind + " popup notification");
|
||||
var notification = aPopupNote.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;
|
||||
}
|
||||
return notification;
|
||||
}
|
||||
|
||||
|
||||
|
@ -58,21 +58,21 @@ function getPopup(aPopupNote, aKind) {
|
|||
* Clicks the specified popup notification button.
|
||||
*/
|
||||
function clickPopupButton(aPopup, aButtonIndex) {
|
||||
ok(true, "Looking for action at index " + aButtonIndex);
|
||||
ok(true, "Looking for action at index " + aButtonIndex);
|
||||
|
||||
var notifications = SpecialPowers.wrap(aPopup.owner).panel.childNodes;
|
||||
ok(notifications.length > 0, "at least one notification displayed");
|
||||
ok(true, notifications.length + " notifications");
|
||||
var notification = notifications[0];
|
||||
var notifications = SpecialPowers.wrap(aPopup.owner).panel.childNodes;
|
||||
ok(notifications.length > 0, "at least one notification displayed");
|
||||
ok(true, notifications.length + " notifications");
|
||||
var notification = notifications[0];
|
||||
|
||||
if (aButtonIndex == 0) {
|
||||
ok(true, "Triggering main action");
|
||||
notification.button.doCommand();
|
||||
} else if (aButtonIndex <= aPopup.secondaryActions.length) {
|
||||
var index = aButtonIndex;
|
||||
ok(true, "Triggering secondary action " + index);
|
||||
notification.childNodes[index].doCommand();
|
||||
}
|
||||
if (aButtonIndex == 0) {
|
||||
ok(true, "Triggering main action");
|
||||
notification.button.doCommand();
|
||||
} else if (aButtonIndex <= aPopup.secondaryActions.length) {
|
||||
var index = aButtonIndex;
|
||||
ok(true, "Triggering secondary action " + index);
|
||||
notification.childNodes[index].doCommand();
|
||||
}
|
||||
}
|
||||
|
||||
const kRememberButton = 0;
|
||||
|
@ -89,7 +89,7 @@ function dumpNotifications() {
|
|||
var notes = container._currentNotifications;
|
||||
ok(true, "Found " + notes.length + " popup notifications.");
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
ok(true, "#" + i + ": " + notes[i].id);
|
||||
ok(true, "#" + i + ": " + notes[i].id);
|
||||
}
|
||||
|
||||
// Notification bars
|
||||
|
@ -99,7 +99,7 @@ function dumpNotifications() {
|
|||
notes = nb.allNotifications;
|
||||
ok(true, "Found " + notes.length + " notification bars.");
|
||||
for (let i = 0; i < notes.length; i++) {
|
||||
ok(true, "#" + i + ": " + notes[i].getAttribute("value"));
|
||||
ok(true, "#" + i + ": " + notes[i].getAttribute("value"));
|
||||
}
|
||||
} catch (e) { todo(false, "WOAH! " + e); }
|
||||
}
|
||||
|
|
|
@ -30,17 +30,17 @@ ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|||
var testpath = "/chrome/toolkit/components/passwordmgr/test/chrome/";
|
||||
var prefix = "http://test2.example.com" + testpath;
|
||||
var subtests = [
|
||||
"subtst_privbrowsing_1.html", // 1
|
||||
"subtst_privbrowsing_1.html", // 2
|
||||
"subtst_privbrowsing_1.html", // 3
|
||||
"subtst_privbrowsing_2.html", // 4
|
||||
"subtst_privbrowsing_2.html", // 5
|
||||
"subtst_privbrowsing_2.html", // 6
|
||||
"subtst_privbrowsing_3.html", // 7
|
||||
"subtst_privbrowsing_3.html", // 8
|
||||
"subtst_privbrowsing_4.html", // 9
|
||||
"subtst_privbrowsing_3.html", // 10
|
||||
];
|
||||
"subtst_privbrowsing_1.html", // 1
|
||||
"subtst_privbrowsing_1.html", // 2
|
||||
"subtst_privbrowsing_1.html", // 3
|
||||
"subtst_privbrowsing_2.html", // 4
|
||||
"subtst_privbrowsing_2.html", // 5
|
||||
"subtst_privbrowsing_2.html", // 6
|
||||
"subtst_privbrowsing_3.html", // 7
|
||||
"subtst_privbrowsing_3.html", // 8
|
||||
"subtst_privbrowsing_4.html", // 9
|
||||
"subtst_privbrowsing_3.html", // 10
|
||||
];
|
||||
var observer;
|
||||
|
||||
var testNum = 0;
|
||||
|
@ -264,7 +264,7 @@ var url = "http://test2.example.com";
|
|||
is(Services.logins.countLogins(url, "", null), 0, "No logins should be stored for " + url);
|
||||
|
||||
var nsLoginInfo = new SpecialPowers.wrap(SpecialPowers.Components).Constructor("@mozilla.org/login-manager/loginInfo;1",
|
||||
Ci.nsILoginInfo, "init");
|
||||
Ci.nsILoginInfo, "init");
|
||||
var login = new nsLoginInfo(url, url, null, "notifyu1", "notifyp1", "user", "pass");
|
||||
|
||||
var normalWindow;
|
||||
|
|
|
@ -18,8 +18,8 @@ const CROSS_ORIGIN_SECURE_PATH = TESTS_DIR + "mochitest/form_cross_origin_secure
|
|||
const chromeScript = runChecksAfterCommonInit(false);
|
||||
|
||||
let nsLoginInfo = SpecialPowers.wrap(SpecialPowers.Components).Constructor("@mozilla.org/login-manager/loginInfo;1",
|
||||
SpecialPowers.Ci.nsILoginInfo,
|
||||
"init");
|
||||
SpecialPowers.Ci.nsILoginInfo,
|
||||
"init");
|
||||
</script>
|
||||
<p id="display"></p>
|
||||
|
||||
|
|
|
@ -137,29 +137,29 @@ runChecksAfterCommonInit(() => startTest());
|
|||
/** Test for Login Manager: simple form fill **/
|
||||
|
||||
function startTest() {
|
||||
var f = 1;
|
||||
var f = 1;
|
||||
|
||||
// 1-3
|
||||
checkForm(f++, "testpass");
|
||||
checkForm(f++, "testpass");
|
||||
checkForm(f++, "xxxxxxxx");
|
||||
// 1-3
|
||||
checkForm(f++, "testpass");
|
||||
checkForm(f++, "testpass");
|
||||
checkForm(f++, "xxxxxxxx");
|
||||
|
||||
// 4-8
|
||||
checkForm(f++, "testuser", "testpass");
|
||||
checkForm(f++, "testuser", "testpass");
|
||||
checkForm(f++, "xxxxxxxx", "");
|
||||
checkForm(f++, "", "testpass");
|
||||
checkForm(f++, "", "xxxxxxxx");
|
||||
// 4-8
|
||||
checkForm(f++, "testuser", "testpass");
|
||||
checkForm(f++, "testuser", "testpass");
|
||||
checkForm(f++, "xxxxxxxx", "");
|
||||
checkForm(f++, "", "testpass");
|
||||
checkForm(f++, "", "xxxxxxxx");
|
||||
|
||||
// 9-14
|
||||
checkForm(f++, "testpass", "");
|
||||
checkForm(f++, "", "testuser", "testpass");
|
||||
checkForm(f++, "testuser", "testpass", "");
|
||||
checkForm(f++, "testpass", "xxxxxxxx");
|
||||
checkForm(f++, "xxxxxxxx", "testuser", "testpass");
|
||||
checkForm(f++, "testuser", "testpass", "xxxxxxxx");
|
||||
// 9-14
|
||||
checkForm(f++, "testpass", "");
|
||||
checkForm(f++, "", "testuser", "testpass");
|
||||
checkForm(f++, "testuser", "testpass", "");
|
||||
checkForm(f++, "testpass", "xxxxxxxx");
|
||||
checkForm(f++, "xxxxxxxx", "testuser", "testpass");
|
||||
checkForm(f++, "testuser", "testpass", "xxxxxxxx");
|
||||
|
||||
SimpleTest.finish();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -87,20 +87,20 @@ runChecksAfterCommonInit(() => startTest());
|
|||
/** Test for Login Manager: simple form fill, part 2 **/
|
||||
|
||||
function startTest() {
|
||||
var f;
|
||||
var f;
|
||||
|
||||
// Test various combinations of disabled/readonly inputs
|
||||
checkForm(1, "testpass"); // control
|
||||
checkUnmodifiedForm(2);
|
||||
checkUnmodifiedForm(3);
|
||||
checkForm(4, "testuser", "testpass"); // control
|
||||
for (f = 5; f <= 8; f++) { checkUnmodifiedForm(f); }
|
||||
// Test case-insensitive comparison of username field
|
||||
checkForm(9, "testuser", "testpass");
|
||||
checkForm(10, "TESTUSER", "testpass");
|
||||
checkForm(11, "TESTUSER", "testpass");
|
||||
// Test various combinations of disabled/readonly inputs
|
||||
checkForm(1, "testpass"); // control
|
||||
checkUnmodifiedForm(2);
|
||||
checkUnmodifiedForm(3);
|
||||
checkForm(4, "testuser", "testpass"); // control
|
||||
for (f = 5; f <= 8; f++) { checkUnmodifiedForm(f); }
|
||||
// Test case-insensitive comparison of username field
|
||||
checkForm(9, "testuser", "testpass");
|
||||
checkForm(10, "TESTUSER", "testpass");
|
||||
checkForm(11, "TESTUSER", "testpass");
|
||||
|
||||
SimpleTest.finish();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -157,29 +157,29 @@ runChecksAfterCommonInit(() => startTest());
|
|||
/** Test for Login Manager: simple form fill **/
|
||||
|
||||
function startTest() {
|
||||
var f = 1;
|
||||
var f = 1;
|
||||
|
||||
// 1-6 no username
|
||||
checkForm(f++, "testpass", "");
|
||||
checkForm(f++, "testpass", "");
|
||||
checkForm(f++, "testpass", "", "");
|
||||
checkForm(f++, "testpass", "");
|
||||
checkForm(f++, "xxxxxxxx", "");
|
||||
checkForm(f++, "testpass", "xxxxxxxx");
|
||||
// 1-6 no username
|
||||
checkForm(f++, "testpass", "");
|
||||
checkForm(f++, "testpass", "");
|
||||
checkForm(f++, "testpass", "", "");
|
||||
checkForm(f++, "testpass", "");
|
||||
checkForm(f++, "xxxxxxxx", "");
|
||||
checkForm(f++, "testpass", "xxxxxxxx");
|
||||
|
||||
// 7-15 with username
|
||||
checkForm(f++, "testuser", "testpass", "");
|
||||
checkForm(f++, "testuser", "testpass", "");
|
||||
checkForm(f++, "testuser", "testpass", "");
|
||||
checkForm(f++, "xxxxxxxx", "", "");
|
||||
checkForm(f++, "testuser", "xxxxxxxx", "");
|
||||
checkForm(f++, "testuser", "testpass", "xxxxxxxx");
|
||||
checkForm(f++, "testuser", "testpass", "");
|
||||
checkForm(f++, "", "xxxxxxxx", "testpass");
|
||||
checkForm(f++, "testpass", "", "");
|
||||
checkForm(f++, "xxxxxxxx", "", "");
|
||||
// 7-15 with username
|
||||
checkForm(f++, "testuser", "testpass", "");
|
||||
checkForm(f++, "testuser", "testpass", "");
|
||||
checkForm(f++, "testuser", "testpass", "");
|
||||
checkForm(f++, "xxxxxxxx", "", "");
|
||||
checkForm(f++, "testuser", "xxxxxxxx", "");
|
||||
checkForm(f++, "testuser", "testpass", "xxxxxxxx");
|
||||
checkForm(f++, "testuser", "testpass", "");
|
||||
checkForm(f++, "", "xxxxxxxx", "testpass");
|
||||
checkForm(f++, "testpass", "", "");
|
||||
checkForm(f++, "xxxxxxxx", "", "");
|
||||
|
||||
SimpleTest.finish();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -183,25 +183,25 @@ password-only, the other is username+password)
|
|||
/** Test for Login Manager: password-only logins **/
|
||||
function startTest() {
|
||||
|
||||
checkForm(1, "1234");
|
||||
checkForm(2, "1234", "");
|
||||
checkForm(3, "1234", "", "");
|
||||
checkUnmodifiedForm(4);
|
||||
checkForm(1, "1234");
|
||||
checkForm(2, "1234", "");
|
||||
checkForm(3, "1234", "", "");
|
||||
checkUnmodifiedForm(4);
|
||||
|
||||
checkForm(5, "", "1234");
|
||||
checkForm(6, "someuser", "");
|
||||
checkForm(5, "", "1234");
|
||||
checkForm(6, "someuser", "");
|
||||
|
||||
checkForm(7, "testuser", "testpass");
|
||||
checkForm(8, "someuser", "");
|
||||
checkForm(7, "testuser", "testpass");
|
||||
checkForm(8, "someuser", "");
|
||||
|
||||
checkForm(9, "", "1234");
|
||||
checkForm(10, "", "1234");
|
||||
checkForm(11, "", "1234");
|
||||
checkForm(9, "", "1234");
|
||||
checkForm(10, "", "1234");
|
||||
checkForm(11, "", "1234");
|
||||
|
||||
checkUnmodifiedForm(12);
|
||||
checkUnmodifiedForm(13);
|
||||
checkUnmodifiedForm(12);
|
||||
checkUnmodifiedForm(13);
|
||||
|
||||
SimpleTest.finish();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
let login2 = parentCc["@mozilla.org/login-manager/loginInfo;1"].
|
||||
createInstance(parentCi.nsILoginInfo);
|
||||
login2.init("http://mochi.test:8888", null, "mochirealm", "user1name",
|
||||
"user1pass", "", "");
|
||||
"user1pass", "", "");
|
||||
Services.logins.addLogin(login2);
|
||||
|
||||
sendAsyncMessage("setupDone");
|
||||
|
|
|
@ -65,9 +65,9 @@ var pword = $_(1, "pword");
|
|||
|
||||
// Restore the form to the default state.
|
||||
function restoreForm() {
|
||||
uname.value = "";
|
||||
pword.value = "";
|
||||
uname.focus();
|
||||
uname.value = "";
|
||||
pword.value = "";
|
||||
uname.focus();
|
||||
}
|
||||
|
||||
// Check for expected username/password in form.
|
||||
|
|
|
@ -17,16 +17,16 @@ runInParent(function setup() {
|
|||
|
||||
let jslogin = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo);
|
||||
jslogin.init("http://mochi.test:8888", "javascript:", null,
|
||||
"jsuser", "jspass123", "uname", "pword");
|
||||
"jsuser", "jspass123", "uname", "pword");
|
||||
Services.logins.addLogin(jslogin);
|
||||
});
|
||||
|
||||
/** Test for Login Manager: JS action URL **/
|
||||
|
||||
function startTest() {
|
||||
checkForm(1, "jsuser", "jspass123");
|
||||
checkForm(1, "jsuser", "jspass123");
|
||||
|
||||
SimpleTest.finish();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
|
@ -766,7 +766,7 @@ add_task(async function test_form9_filtering() {
|
|||
|
||||
checkACForm("form9userAAB", "");
|
||||
checkArrayValues(results, ["This connection is not secure. Logins entered here could be compromised. Learn More", "form9userAAB"],
|
||||
"Check dropdown is updated after inserting 'A'");
|
||||
"Check dropdown is updated after inserting 'A'");
|
||||
synthesizeKey("KEY_ArrowDown"); // skip insecure warning
|
||||
synthesizeKey("KEY_ArrowDown");
|
||||
synthesizeKey("KEY_Enter");
|
||||
|
|
|
@ -133,7 +133,7 @@ async function reinitializeForm(index) {
|
|||
|
||||
function generateDateString(date) {
|
||||
let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
|
||||
{ dateStyle: "medium" });
|
||||
{ dateStyle: "medium" });
|
||||
return dateAndTimeFormatter.format(date);
|
||||
}
|
||||
|
||||
|
@ -164,9 +164,9 @@ add_task(async function test_form1_initial_empty() {
|
|||
|
||||
add_task(async function test_form2_password_readonly() {
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.insecure_field_warning.contextual.enabled", true],
|
||||
["signon.autofillForms.http", true],
|
||||
]});
|
||||
["security.insecure_field_warning.contextual.enabled", true],
|
||||
["signon.autofillForms.http", true],
|
||||
]});
|
||||
await reinitializeForm(2);
|
||||
|
||||
// Trigger autocomplete popup
|
||||
|
@ -177,9 +177,9 @@ add_task(async function test_form2_password_readonly() {
|
|||
|
||||
add_task(async function test_form3_password_disabled() {
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.insecure_field_warning.contextual.enabled", true],
|
||||
["signon.autofillForms.http", true],
|
||||
]});
|
||||
["security.insecure_field_warning.contextual.enabled", true],
|
||||
["signon.autofillForms.http", true],
|
||||
]});
|
||||
await reinitializeForm(3);
|
||||
|
||||
// Trigger autocomplete popup
|
||||
|
@ -190,9 +190,9 @@ add_task(async function test_form3_password_disabled() {
|
|||
|
||||
add_task(async function test_form1_enabledInsecureFieldWarning_enabledInsecureAutoFillForm() {
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.insecure_field_warning.contextual.enabled", true],
|
||||
["signon.autofillForms.http", true],
|
||||
]});
|
||||
["security.insecure_field_warning.contextual.enabled", true],
|
||||
["signon.autofillForms.http", true],
|
||||
]});
|
||||
await reinitializeForm(1);
|
||||
// Trigger autocomplete popup
|
||||
let shownPromise = promiseACShown();
|
||||
|
@ -219,9 +219,9 @@ add_task(async function test_form1_enabledInsecureFieldWarning_enabledInsecureAu
|
|||
|
||||
add_task(async function test_form1_disabledInsecureFieldWarning_enabledInsecureAutoFillForm() {
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.insecure_field_warning.contextual.enabled", false],
|
||||
["signon.autofillForms.http", true],
|
||||
]});
|
||||
["security.insecure_field_warning.contextual.enabled", false],
|
||||
["signon.autofillForms.http", true],
|
||||
]});
|
||||
await reinitializeForm(1);
|
||||
|
||||
// Trigger autocomplete popup
|
||||
|
@ -248,9 +248,9 @@ add_task(async function test_form1_disabledInsecureFieldWarning_enabledInsecureA
|
|||
|
||||
add_task(async function test_form1_enabledInsecureFieldWarning_disabledInsecureAutoFillForm() {
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.insecure_field_warning.contextual.enabled", true],
|
||||
["signon.autofillForms.http", false],
|
||||
]});
|
||||
["security.insecure_field_warning.contextual.enabled", true],
|
||||
["signon.autofillForms.http", false],
|
||||
]});
|
||||
await reinitializeForm(1);
|
||||
|
||||
// Trigger autocomplete popup
|
||||
|
@ -278,9 +278,9 @@ add_task(async function test_form1_enabledInsecureFieldWarning_disabledInsecureA
|
|||
|
||||
add_task(async function test_form1_disabledInsecureFieldWarning_disabledInsecureAutoFillForm() {
|
||||
await SpecialPowers.pushPrefEnv({"set": [
|
||||
["security.insecure_field_warning.contextual.enabled", false],
|
||||
["signon.autofillForms.http", false],
|
||||
]});
|
||||
["security.insecure_field_warning.contextual.enabled", false],
|
||||
["signon.autofillForms.http", false],
|
||||
]});
|
||||
await reinitializeForm(1);
|
||||
|
||||
// Trigger autocomplete popup
|
||||
|
|
|
@ -15,34 +15,34 @@ var didDialog;
|
|||
|
||||
var timer; // keep in outer scope so it's not GC'd before firing
|
||||
function startCallbackTimer() {
|
||||
didDialog = false;
|
||||
didDialog = false;
|
||||
|
||||
// Delay before the callback twiddles the prompt.
|
||||
const dialogDelay = 10;
|
||||
// Delay before the callback twiddles the prompt.
|
||||
const dialogDelay = 10;
|
||||
|
||||
// Use a timer to invoke a callback to twiddle the authentication dialog
|
||||
timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.init(observer, dialogDelay, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
// Use a timer to invoke a callback to twiddle the authentication dialog
|
||||
timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
timer.init(observer, dialogDelay, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}
|
||||
|
||||
|
||||
var observer = SpecialPowers.wrapCallbackObject({
|
||||
QueryInterface(iid) {
|
||||
const interfaces = [Ci.nsIObserver,
|
||||
Ci.nsISupports, Ci.nsISupportsWeakReference];
|
||||
QueryInterface(iid) {
|
||||
const interfaces = [Ci.nsIObserver,
|
||||
Ci.nsISupports, Ci.nsISupportsWeakReference];
|
||||
|
||||
if (!interfaces.some( function(v) { return iid.equals(v); } ))
|
||||
throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
if (!interfaces.some( function(v) { return iid.equals(v); } ))
|
||||
throw SpecialPowers.Components.results.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
|
||||
observe(subject, topic, data) {
|
||||
var doc = getDialogDoc();
|
||||
if (doc)
|
||||
handleDialog(doc, testNum);
|
||||
else
|
||||
startCallbackTimer(); // try again in a bit
|
||||
},
|
||||
observe(subject, topic, data) {
|
||||
var doc = getDialogDoc();
|
||||
if (doc)
|
||||
handleDialog(doc, testNum);
|
||||
else
|
||||
startCallbackTimer(); // try again in a bit
|
||||
},
|
||||
});
|
||||
|
||||
function getDialogDoc() {
|
||||
|
@ -51,17 +51,17 @@ function getDialogDoc() {
|
|||
// var enumerator = SpecialPowers.Services.wm.getEnumerator("navigator:browser");
|
||||
for (let {docShell} of SpecialPowers.Services.wm.getXULWindowEnumerator(null)) {
|
||||
var containedDocShells = docShell.getDocShellEnumerator(
|
||||
docShell.typeChrome,
|
||||
docShell.ENUMERATE_FORWARDS);
|
||||
docShell.typeChrome,
|
||||
docShell.ENUMERATE_FORWARDS);
|
||||
for (let childDocShell of containedDocShells) {
|
||||
// We don't want it if it's not done loading.
|
||||
if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
|
||||
continue;
|
||||
var childDoc = childDocShell.contentViewer.DOMDocument;
|
||||
// We don't want it if it's not done loading.
|
||||
if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE)
|
||||
continue;
|
||||
var childDoc = childDocShell.contentViewer.DOMDocument;
|
||||
|
||||
// ok(true, "Got window: " + childDoc.location.href);
|
||||
if (childDoc.location.href == "chrome://global/content/commonDialog.xul")
|
||||
return childDoc;
|
||||
// ok(true, "Got window: " + childDoc.location.href);
|
||||
if (childDoc.location.href == "chrome://global/content/commonDialog.xul")
|
||||
return childDoc;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -422,7 +422,7 @@ if (this.addMessageListener) {
|
|||
["signon.autofillForms.http", true],
|
||||
["security.insecure_field_warning.contextual.enabled", false],
|
||||
["network.auth.non-web-content-triggered-resources-http-auth-allow", true]],
|
||||
});
|
||||
});
|
||||
SimpleTest.registerCleanupFunction(() => {
|
||||
SpecialPowers.popPrefEnv();
|
||||
runInParent(function cleanupParent() {
|
||||
|
|
|
@ -57,11 +57,11 @@ var iframe2 = document.getElementById("iframe2");
|
|||
// and then posts a message back up to us telling us to continue.
|
||||
var continuation = null;
|
||||
addEventListener("message", () => {
|
||||
if (continuation) {
|
||||
var c = continuation;
|
||||
continuation = null;
|
||||
c();
|
||||
}
|
||||
if (continuation) {
|
||||
var c = continuation;
|
||||
continuation = null;
|
||||
c();
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
|
@ -80,50 +80,50 @@ function handleDialog(doc, testNumber) {
|
|||
var passfield = doc.getElementById("password1Textbox");
|
||||
var dialog = doc.getElementById("commonDialog");
|
||||
|
||||
switch (testNumber) {
|
||||
case 1:
|
||||
is(passfield.getAttribute("value"), "", "Checking empty prompt");
|
||||
passfield.setAttribute("value", masterPassword);
|
||||
is(passfield.getAttribute("value"), masterPassword, "Checking filled prompt");
|
||||
break;
|
||||
switch (testNumber) {
|
||||
case 1:
|
||||
is(passfield.getAttribute("value"), "", "Checking empty prompt");
|
||||
passfield.setAttribute("value", masterPassword);
|
||||
is(passfield.getAttribute("value"), masterPassword, "Checking filled prompt");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
clickOK = false;
|
||||
break;
|
||||
case 2:
|
||||
clickOK = false;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
is(passfield.getAttribute("value"), "", "Checking empty prompt");
|
||||
passfield.setAttribute("value", masterPassword);
|
||||
break;
|
||||
case 3:
|
||||
is(passfield.getAttribute("value"), "", "Checking empty prompt");
|
||||
passfield.setAttribute("value", masterPassword);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
doNothing = true;
|
||||
break;
|
||||
case 4:
|
||||
doNothing = true;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
is(passfield.getAttribute("value"), "", "Checking empty prompt");
|
||||
passfield.setAttribute("value", masterPassword);
|
||||
break;
|
||||
case 5:
|
||||
is(passfield.getAttribute("value"), "", "Checking empty prompt");
|
||||
passfield.setAttribute("value", masterPassword);
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "Uhh, unhandled switch for testNum #" + testNumber);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
ok(false, "Uhh, unhandled switch for testNum #" + testNumber);
|
||||
break;
|
||||
}
|
||||
|
||||
didDialog = true;
|
||||
didDialog = true;
|
||||
|
||||
if (!doNothing) {
|
||||
SpecialPowers.addObserver(outerWindowObserver, "outer-window-destroyed");
|
||||
if (clickOK)
|
||||
dialog.acceptDialog();
|
||||
else
|
||||
dialog.cancelDialog();
|
||||
}
|
||||
if (!doNothing) {
|
||||
SpecialPowers.addObserver(outerWindowObserver, "outer-window-destroyed");
|
||||
if (clickOK)
|
||||
dialog.acceptDialog();
|
||||
else
|
||||
dialog.cancelDialog();
|
||||
}
|
||||
|
||||
ok(true, "handleDialog done for test " + testNumber);
|
||||
ok(true, "handleDialog done for test " + testNumber);
|
||||
|
||||
if (testNumber == 4)
|
||||
checkTest4A();
|
||||
if (testNumber == 4)
|
||||
checkTest4A();
|
||||
}
|
||||
|
||||
var outerWindowObserver = {
|
||||
|
@ -131,172 +131,172 @@ var outerWindowObserver = {
|
|||
SpecialPowers.removeObserver(outerWindowObserver, "outer-window-destroyed");
|
||||
var func;
|
||||
if (testNum == 1)
|
||||
func = startTest2;
|
||||
func = startTest2;
|
||||
else if (testNum == 2)
|
||||
func = startTest3;
|
||||
func = startTest3;
|
||||
|
||||
// For tests 3 and 4C, we use the 'continuation' mechanism, described
|
||||
// above.
|
||||
if (func)
|
||||
setTimeout(func, 300);
|
||||
setTimeout(func, 300);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
function startTest1() {
|
||||
ok(pwcrypt.isLoggedIn, "should be initially logged in (no MP)");
|
||||
enableMasterPassword();
|
||||
ok(!pwcrypt.isLoggedIn, "should be logged out after setting MP");
|
||||
ok(pwcrypt.isLoggedIn, "should be initially logged in (no MP)");
|
||||
enableMasterPassword();
|
||||
ok(!pwcrypt.isLoggedIn, "should be logged out after setting MP");
|
||||
|
||||
// --- Test 1 ---
|
||||
// Trigger a MP prompt via the API
|
||||
startCallbackTimer();
|
||||
var logins = pwmgr.getAllLogins();
|
||||
ok(didDialog, "handleDialog was invoked");
|
||||
is(logins.length, 3, "expected number of logins");
|
||||
// --- Test 1 ---
|
||||
// Trigger a MP prompt via the API
|
||||
startCallbackTimer();
|
||||
var logins = pwmgr.getAllLogins();
|
||||
ok(didDialog, "handleDialog was invoked");
|
||||
is(logins.length, 3, "expected number of logins");
|
||||
|
||||
ok(pwcrypt.isLoggedIn, "should be logged in after MP prompt");
|
||||
logoutMasterPassword();
|
||||
ok(!pwcrypt.isLoggedIn, "should be logged out");
|
||||
ok(pwcrypt.isLoggedIn, "should be logged in after MP prompt");
|
||||
logoutMasterPassword();
|
||||
ok(!pwcrypt.isLoggedIn, "should be logged out");
|
||||
}
|
||||
|
||||
function startTest2() {
|
||||
// Try again but click cancel.
|
||||
testNum++;
|
||||
startCallbackTimer();
|
||||
var failedAsExpected = false;
|
||||
logins = null;
|
||||
try {
|
||||
logins = pwmgr.getAllLogins();
|
||||
} catch (e) { failedAsExpected = true; }
|
||||
ok(didDialog, "handleDialog was invoked");
|
||||
ok(failedAsExpected, "getAllLogins should have thrown");
|
||||
is(logins, null, "shouldn't have gotten logins");
|
||||
ok(!pwcrypt.isLoggedIn, "should still be logged out");
|
||||
// Try again but click cancel.
|
||||
testNum++;
|
||||
startCallbackTimer();
|
||||
var failedAsExpected = false;
|
||||
logins = null;
|
||||
try {
|
||||
logins = pwmgr.getAllLogins();
|
||||
} catch (e) { failedAsExpected = true; }
|
||||
ok(didDialog, "handleDialog was invoked");
|
||||
ok(failedAsExpected, "getAllLogins should have thrown");
|
||||
is(logins, null, "shouldn't have gotten logins");
|
||||
ok(!pwcrypt.isLoggedIn, "should still be logged out");
|
||||
}
|
||||
|
||||
function startTest3() {
|
||||
// Load a single iframe to trigger a MP
|
||||
testNum++;
|
||||
iframe1.src = exampleCom + "subtst_master_pass.html";
|
||||
continuation = checkTest3;
|
||||
startCallbackTimer();
|
||||
// Load a single iframe to trigger a MP
|
||||
testNum++;
|
||||
iframe1.src = exampleCom + "subtst_master_pass.html";
|
||||
continuation = checkTest3;
|
||||
startCallbackTimer();
|
||||
}
|
||||
|
||||
function checkTest3() {
|
||||
ok(true, "checkTest3 starting");
|
||||
ok(didDialog, "handleDialog was invoked");
|
||||
ok(true, "checkTest3 starting");
|
||||
ok(didDialog, "handleDialog was invoked");
|
||||
|
||||
// check contents of iframe1 fields
|
||||
var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield");
|
||||
var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield");
|
||||
is(u.value, "user1", "checking expected user to have been filled in");
|
||||
is(p.value, "pass1", "checking expected pass to have been filled in");
|
||||
// check contents of iframe1 fields
|
||||
var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield");
|
||||
var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield");
|
||||
is(u.value, "user1", "checking expected user to have been filled in");
|
||||
is(p.value, "pass1", "checking expected pass to have been filled in");
|
||||
|
||||
ok(pwcrypt.isLoggedIn, "should be logged in");
|
||||
logoutMasterPassword();
|
||||
ok(!pwcrypt.isLoggedIn, "should be logged out");
|
||||
ok(pwcrypt.isLoggedIn, "should be logged in");
|
||||
logoutMasterPassword();
|
||||
ok(!pwcrypt.isLoggedIn, "should be logged out");
|
||||
|
||||
|
||||
// --- Test 4 ---
|
||||
// first part of loading 2 MP-triggering iframes
|
||||
testNum++;
|
||||
iframe1.src = exampleOrg + "subtst_master_pass.html";
|
||||
// start the callback, but we'll not enter the MP, just call checkTest4A
|
||||
startCallbackTimer();
|
||||
// --- Test 4 ---
|
||||
// first part of loading 2 MP-triggering iframes
|
||||
testNum++;
|
||||
iframe1.src = exampleOrg + "subtst_master_pass.html";
|
||||
// start the callback, but we'll not enter the MP, just call checkTest4A
|
||||
startCallbackTimer();
|
||||
}
|
||||
|
||||
function checkTest4A() {
|
||||
ok(true, "checkTest4A starting");
|
||||
ok(didDialog, "handleDialog was invoked");
|
||||
ok(true, "checkTest4A starting");
|
||||
ok(didDialog, "handleDialog was invoked");
|
||||
|
||||
// check contents of iframe1 fields
|
||||
var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield");
|
||||
var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield");
|
||||
is(u.value, "", "checking expected empty user");
|
||||
is(p.value, "", "checking expected empty pass");
|
||||
// check contents of iframe1 fields
|
||||
var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield");
|
||||
var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield");
|
||||
is(u.value, "", "checking expected empty user");
|
||||
is(p.value, "", "checking expected empty pass");
|
||||
|
||||
|
||||
ok(!pwcrypt.isLoggedIn, "should be logged out");
|
||||
ok(!pwcrypt.isLoggedIn, "should be logged out");
|
||||
|
||||
// XXX check that there's 1 MP window open
|
||||
// XXX check that there's 1 MP window open
|
||||
|
||||
// Load another iframe with a login form
|
||||
// This should detect that there's already a pending MP prompt, and not
|
||||
// put up a second one. The load event will fire (note that when pwmgr is
|
||||
// driven from DOMContentLoaded, if that blocks due to prompting for a MP,
|
||||
// the load even will also be blocked until the prompt is dismissed).
|
||||
iframe2.onload = checkTest4B_delay;
|
||||
iframe2.src = exampleCom + "subtst_master_pass.html";
|
||||
// Load another iframe with a login form
|
||||
// This should detect that there's already a pending MP prompt, and not
|
||||
// put up a second one. The load event will fire (note that when pwmgr is
|
||||
// driven from DOMContentLoaded, if that blocks due to prompting for a MP,
|
||||
// the load even will also be blocked until the prompt is dismissed).
|
||||
iframe2.onload = checkTest4B_delay;
|
||||
iframe2.src = exampleCom + "subtst_master_pass.html";
|
||||
}
|
||||
|
||||
function checkTest4B_delay() {
|
||||
// Testing a negative, wait a little to give the login manager a chance to
|
||||
// (incorrectly) fill in the form. Note, we cannot use setTimeout()
|
||||
// here because the modal window suspends all window timers. Instead we
|
||||
// must use a chrome script to use nsITimer directly.
|
||||
let chromeURL = SimpleTest.getTestFileURL("chrome_timeout.js");
|
||||
let script = SpecialPowers.loadChromeScript(chromeURL);
|
||||
script.addMessageListener("ready", _ => {
|
||||
script.sendAsyncMessage("setTimeout", { delay: 500 });
|
||||
});
|
||||
script.addMessageListener("timeout", checkTest4B);
|
||||
// Testing a negative, wait a little to give the login manager a chance to
|
||||
// (incorrectly) fill in the form. Note, we cannot use setTimeout()
|
||||
// here because the modal window suspends all window timers. Instead we
|
||||
// must use a chrome script to use nsITimer directly.
|
||||
let chromeURL = SimpleTest.getTestFileURL("chrome_timeout.js");
|
||||
let script = SpecialPowers.loadChromeScript(chromeURL);
|
||||
script.addMessageListener("ready", _ => {
|
||||
script.sendAsyncMessage("setTimeout", { delay: 500 });
|
||||
});
|
||||
script.addMessageListener("timeout", checkTest4B);
|
||||
}
|
||||
|
||||
function checkTest4B() {
|
||||
ok(true, "checkTest4B starting");
|
||||
// iframe2 should load without having triggered a MP prompt (because one
|
||||
// is already waiting)
|
||||
ok(true, "checkTest4B starting");
|
||||
// iframe2 should load without having triggered a MP prompt (because one
|
||||
// is already waiting)
|
||||
|
||||
// check contents of iframe2 fields
|
||||
var u = SpecialPowers.wrap(iframe2).contentDocument.getElementById("userfield");
|
||||
var p = SpecialPowers.wrap(iframe2).contentDocument.getElementById("passfield");
|
||||
is(u.value, "", "checking expected empty user");
|
||||
is(p.value, "", "checking expected empty pass");
|
||||
// check contents of iframe2 fields
|
||||
var u = SpecialPowers.wrap(iframe2).contentDocument.getElementById("userfield");
|
||||
var p = SpecialPowers.wrap(iframe2).contentDocument.getElementById("passfield");
|
||||
is(u.value, "", "checking expected empty user");
|
||||
is(p.value, "", "checking expected empty pass");
|
||||
|
||||
// XXX check that there's 1 MP window open
|
||||
ok(!pwcrypt.isLoggedIn, "should be logged out");
|
||||
// XXX check that there's 1 MP window open
|
||||
ok(!pwcrypt.isLoggedIn, "should be logged out");
|
||||
|
||||
continuation = checkTest4C;
|
||||
continuation = checkTest4C;
|
||||
|
||||
// Ok, now enter the MP. The MP prompt is already up, but we'll just reuse startCallBackTimer.
|
||||
// --- Test 5 ---
|
||||
testNum++;
|
||||
startCallbackTimer();
|
||||
// Ok, now enter the MP. The MP prompt is already up, but we'll just reuse startCallBackTimer.
|
||||
// --- Test 5 ---
|
||||
testNum++;
|
||||
startCallbackTimer();
|
||||
}
|
||||
|
||||
function checkTest4C() {
|
||||
ok(true, "checkTest4C starting");
|
||||
ok(didDialog, "handleDialog was invoked");
|
||||
ok(true, "checkTest4C starting");
|
||||
ok(didDialog, "handleDialog was invoked");
|
||||
|
||||
// We shouldn't have to worry about iframe1's load event racing with
|
||||
// filling of iframe2's data. We notify observers synchronously, so
|
||||
// iframe2's observer will process iframe2 before iframe1 even finishes
|
||||
// processing the form (which is blocking its load event).
|
||||
ok(pwcrypt.isLoggedIn, "should be logged in");
|
||||
// We shouldn't have to worry about iframe1's load event racing with
|
||||
// filling of iframe2's data. We notify observers synchronously, so
|
||||
// iframe2's observer will process iframe2 before iframe1 even finishes
|
||||
// processing the form (which is blocking its load event).
|
||||
ok(pwcrypt.isLoggedIn, "should be logged in");
|
||||
|
||||
// check contents of iframe1 fields
|
||||
var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield");
|
||||
var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield");
|
||||
is(u.value, "user2", "checking expected user to have been filled in");
|
||||
is(p.value, "pass2", "checking expected pass to have been filled in");
|
||||
// check contents of iframe1 fields
|
||||
var u = SpecialPowers.wrap(iframe1).contentDocument.getElementById("userfield");
|
||||
var p = SpecialPowers.wrap(iframe1).contentDocument.getElementById("passfield");
|
||||
is(u.value, "user2", "checking expected user to have been filled in");
|
||||
is(p.value, "pass2", "checking expected pass to have been filled in");
|
||||
|
||||
// check contents of iframe2 fields
|
||||
u = SpecialPowers.wrap(iframe2).contentDocument.getElementById("userfield");
|
||||
p = SpecialPowers.wrap(iframe2).contentDocument.getElementById("passfield");
|
||||
is(u.value, "user1", "checking expected user to have been filled in");
|
||||
is(p.value, "pass1", "checking expected pass to have been filled in");
|
||||
// check contents of iframe2 fields
|
||||
u = SpecialPowers.wrap(iframe2).contentDocument.getElementById("userfield");
|
||||
p = SpecialPowers.wrap(iframe2).contentDocument.getElementById("passfield");
|
||||
is(u.value, "user1", "checking expected user to have been filled in");
|
||||
is(p.value, "pass1", "checking expected pass to have been filled in");
|
||||
|
||||
SimpleTest.finish();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
// XXX do a test5ABC with clicking cancel?
|
||||
|
||||
SimpleTest.registerCleanupFunction(function finishTest() {
|
||||
disableMasterPassword();
|
||||
disableMasterPassword();
|
||||
|
||||
pwmgr.removeLogin(login1);
|
||||
pwmgr.removeLogin(login2);
|
||||
pwmgr.removeLogin(login1);
|
||||
pwmgr.removeLogin(login2);
|
||||
});
|
||||
|
||||
window.addEventListener("runTests", startTest1);
|
||||
|
|
|
@ -19,11 +19,8 @@
|
|||
// Class monitoring number of open dialog windows
|
||||
// It checks there is always open just a single dialog per application
|
||||
function dialogMonitor() {
|
||||
// eslint-disable-next-line mozilla/use-services
|
||||
var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
observerService.addObserver(this, "domwindowopened");
|
||||
observerService.addObserver(this, "domwindowclosed");
|
||||
SpecialPowers.Services.obs.addObserver(this, "domwindowopened");
|
||||
SpecialPowers.Services.obs.addObserver(this, "domwindowclosed");
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -36,38 +33,35 @@
|
|||
* we need to do SpecialPowers.wrapCallbackObject directly on the prototype.
|
||||
*/
|
||||
dialogMonitor.prototype = SpecialPowers.wrapCallbackObject({
|
||||
windowsOpen: 0,
|
||||
windowsRegistered: 0,
|
||||
windowsOpen: 0,
|
||||
windowsRegistered: 0,
|
||||
|
||||
QueryInterface(iid) {
|
||||
const interfaces = [Ci.nsIObserver, Ci.nsISupports];
|
||||
QueryInterface(iid) {
|
||||
const interfaces = [Ci.nsIObserver, Ci.nsISupports];
|
||||
|
||||
if (!interfaces.some( function(v) { return iid.equals(v); } ))
|
||||
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
if (!interfaces.some( function(v) { return iid.equals(v); } ))
|
||||
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
|
||||
observe(subject, topic, data) {
|
||||
if (topic === "domwindowopened") {
|
||||
this.windowsOpen++;
|
||||
this.windowsRegistered++;
|
||||
} else if (topic === "domwindowclosed") {
|
||||
this.windowsOpen--;
|
||||
}
|
||||
},
|
||||
observe(subject, topic, data) {
|
||||
if (topic === "domwindowopened") {
|
||||
this.windowsOpen++;
|
||||
this.windowsRegistered++;
|
||||
} else if (topic === "domwindowclosed") {
|
||||
this.windowsOpen--;
|
||||
}
|
||||
},
|
||||
|
||||
shutdown() {
|
||||
// eslint-disable-next-line mozilla/use-services
|
||||
var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService);
|
||||
observerService.removeObserver(this, "domwindowopened");
|
||||
observerService.removeObserver(this, "domwindowclosed");
|
||||
},
|
||||
shutdown() {
|
||||
SpecialPowers.Services.obs.removeObserver(this, "domwindowopened");
|
||||
SpecialPowers.Services.obs.removeObserver(this, "domwindowclosed");
|
||||
},
|
||||
|
||||
reset() {
|
||||
this.windowsOpen = 0;
|
||||
this.windowsRegistered = 0;
|
||||
},
|
||||
reset() {
|
||||
this.windowsOpen = 0;
|
||||
this.windowsRegistered = 0;
|
||||
},
|
||||
});
|
||||
|
||||
var monitor = new dialogMonitor();
|
||||
|
@ -75,83 +69,82 @@
|
|||
var pwmgr, logins = [];
|
||||
|
||||
function initLogins(pi) {
|
||||
pwmgr = SpecialPowers.Services.logins;
|
||||
pwmgr = SpecialPowers.Services.logins;
|
||||
|
||||
function addLogin(host, realm, user, pass) {
|
||||
var login = SpecialPowers.Cc["@mozilla.org/login-manager/loginInfo;1"]
|
||||
.createInstance(Ci.nsILoginInfo);
|
||||
login.init(host, null, realm, user, pass, "", "");
|
||||
pwmgr.addLogin(login);
|
||||
logins.push(login);
|
||||
}
|
||||
function addLogin(host, realm, user, pass) {
|
||||
var login = SpecialPowers.Cc["@mozilla.org/login-manager/loginInfo;1"]
|
||||
.createInstance(Ci.nsILoginInfo);
|
||||
login.init(host, null, realm, user, pass, "", "");
|
||||
pwmgr.addLogin(login);
|
||||
logins.push(login);
|
||||
}
|
||||
|
||||
var mozproxy = "moz-proxy://" +
|
||||
SpecialPowers.wrap(pi).host + ":" +
|
||||
SpecialPowers.wrap(pi).port;
|
||||
var mozproxy = "moz-proxy://" + SpecialPowers.wrap(pi).host + ":" +
|
||||
SpecialPowers.wrap(pi).port;
|
||||
|
||||
addLogin(mozproxy, "proxy_realm",
|
||||
"proxy_user", "proxy_pass");
|
||||
addLogin(mozproxy, "proxy_realm2",
|
||||
"proxy_user2", "proxy_pass2");
|
||||
addLogin(mozproxy, "proxy_realm3",
|
||||
"proxy_user3", "proxy_pass3");
|
||||
addLogin(mozproxy, "proxy_realm4",
|
||||
"proxy_user4", "proxy_pass4");
|
||||
addLogin(mozproxy, "proxy_realm5",
|
||||
"proxy_user5", "proxy_pass5");
|
||||
addLogin("http://example.com", "mochirealm",
|
||||
"user1name", "user1pass");
|
||||
addLogin("http://example.org", "mochirealm2",
|
||||
"user2name", "user2pass");
|
||||
addLogin("http://example.com", "mochirealm3",
|
||||
"user3name", "user3pass");
|
||||
addLogin("http://example.com", "mochirealm4",
|
||||
"user4name", "user4pass");
|
||||
addLogin("http://example.com", "mochirealm5",
|
||||
"user5name", "user5pass");
|
||||
addLogin("http://example.com", "mochirealm6",
|
||||
"user6name", "user6pass");
|
||||
addLogin(mozproxy, "proxy_realm",
|
||||
"proxy_user", "proxy_pass");
|
||||
addLogin(mozproxy, "proxy_realm2",
|
||||
"proxy_user2", "proxy_pass2");
|
||||
addLogin(mozproxy, "proxy_realm3",
|
||||
"proxy_user3", "proxy_pass3");
|
||||
addLogin(mozproxy, "proxy_realm4",
|
||||
"proxy_user4", "proxy_pass4");
|
||||
addLogin(mozproxy, "proxy_realm5",
|
||||
"proxy_user5", "proxy_pass5");
|
||||
addLogin("http://example.com", "mochirealm",
|
||||
"user1name", "user1pass");
|
||||
addLogin("http://example.org", "mochirealm2",
|
||||
"user2name", "user2pass");
|
||||
addLogin("http://example.com", "mochirealm3",
|
||||
"user3name", "user3pass");
|
||||
addLogin("http://example.com", "mochirealm4",
|
||||
"user4name", "user4pass");
|
||||
addLogin("http://example.com", "mochirealm5",
|
||||
"user5name", "user5pass");
|
||||
addLogin("http://example.com", "mochirealm6",
|
||||
"user6name", "user6pass");
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
ok(true, "finishTest removing testing logins...");
|
||||
for (i in logins)
|
||||
pwmgr.removeLogin(logins[i]);
|
||||
ok(true, "finishTest removing testing logins...");
|
||||
for (i in logins)
|
||||
pwmgr.removeLogin(logins[i]);
|
||||
|
||||
var authMgr = SpecialPowers.Cc["@mozilla.org/network/http-auth-manager;1"]
|
||||
.getService(Ci.nsIHttpAuthManager);
|
||||
authMgr.clearAll();
|
||||
var authMgr = SpecialPowers.Cc["@mozilla.org/network/http-auth-manager;1"]
|
||||
.getService(Ci.nsIHttpAuthManager);
|
||||
authMgr.clearAll();
|
||||
|
||||
monitor.shutdown();
|
||||
SimpleTest.finish();
|
||||
monitor.shutdown();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
var resolveCallback = SpecialPowers.wrapCallbackObject({
|
||||
QueryInterface(iid) {
|
||||
const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports];
|
||||
QueryInterface(iid) {
|
||||
const interfaces = [Ci.nsIProtocolProxyCallback, Ci.nsISupports];
|
||||
|
||||
if (!interfaces.some( function(v) { return iid.equals(v); } ))
|
||||
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
if (!interfaces.some( function(v) { return iid.equals(v); } ))
|
||||
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
|
||||
return this;
|
||||
},
|
||||
|
||||
onProxyAvailable(req, uri, pi, status) {
|
||||
initLogins(pi);
|
||||
doTest(testNum);
|
||||
},
|
||||
onProxyAvailable(req, uri, pi, status) {
|
||||
initLogins(pi);
|
||||
doTest(testNum);
|
||||
},
|
||||
});
|
||||
|
||||
function startup() {
|
||||
// Need to allow for arbitrary network servers defined in PAC instead of a hardcoded moz-proxy.
|
||||
var channel = NetUtil.newChannel({
|
||||
uri: "http://example.com",
|
||||
loadUsingSystemPrincipal: true,
|
||||
});
|
||||
// Need to allow for arbitrary network servers defined in PAC instead of a hardcoded moz-proxy.
|
||||
var channel = NetUtil.newChannel({
|
||||
uri: "http://example.com",
|
||||
loadUsingSystemPrincipal: true,
|
||||
});
|
||||
|
||||
var pps = SpecialPowers.Cc["@mozilla.org/network/protocol-proxy-service;1"]
|
||||
.getService();
|
||||
var pps = SpecialPowers.Cc["@mozilla.org/network/protocol-proxy-service;1"]
|
||||
.getService();
|
||||
|
||||
pps.asyncResolve(channel, 0, resolveCallback);
|
||||
pps.asyncResolve(channel, 0, resolveCallback);
|
||||
}
|
||||
|
||||
// --------------- Test loop spin ----------------
|
||||
|
@ -160,371 +153,371 @@
|
|||
var iframe2a;
|
||||
var iframe2b;
|
||||
window.onload = function() {
|
||||
iframe1 = document.getElementById("iframe1");
|
||||
iframe2a = document.getElementById("iframe2a");
|
||||
iframe2b = document.getElementById("iframe2b");
|
||||
iframe1.onload = onFrameLoad;
|
||||
iframe2a.onload = onFrameLoad;
|
||||
iframe2b.onload = onFrameLoad;
|
||||
iframe1 = document.getElementById("iframe1");
|
||||
iframe2a = document.getElementById("iframe2a");
|
||||
iframe2b = document.getElementById("iframe2b");
|
||||
iframe1.onload = onFrameLoad;
|
||||
iframe2a.onload = onFrameLoad;
|
||||
iframe2b.onload = onFrameLoad;
|
||||
|
||||
startup();
|
||||
startup();
|
||||
};
|
||||
|
||||
var expectedLoads;
|
||||
var expectedDialogs;
|
||||
function onFrameLoad()
|
||||
{
|
||||
if (--expectedLoads == 0) {
|
||||
// All pages expected to load has loaded, continue with the next test
|
||||
ok(true, "Expected frames loaded");
|
||||
if (--expectedLoads == 0) {
|
||||
// All pages expected to load has loaded, continue with the next test
|
||||
ok(true, "Expected frames loaded");
|
||||
|
||||
doCheck(testNum);
|
||||
monitor.reset();
|
||||
doCheck(testNum);
|
||||
monitor.reset();
|
||||
|
||||
testNum++;
|
||||
doTest(testNum);
|
||||
}
|
||||
testNum++;
|
||||
doTest(testNum);
|
||||
}
|
||||
}
|
||||
|
||||
function doTest(testNumber)
|
||||
{
|
||||
/*
|
||||
/*
|
||||
* These contentDocument variables are located here,
|
||||
* rather than in the global scope, because SpecialPowers threw
|
||||
* errors (complaining that the objects were deleted)
|
||||
* when these were in the global scope.
|
||||
*/
|
||||
var iframe1Doc = SpecialPowers.wrap(iframe1).contentDocument;
|
||||
var iframe2aDoc = SpecialPowers.wrap(iframe2a).contentDocument;
|
||||
var iframe2bDoc = SpecialPowers.wrap(iframe2b).contentDocument;
|
||||
var exampleCom = "http://example.com/tests/toolkit/components/passwordmgr/test/";
|
||||
var exampleOrg = "http://example.org/tests/toolkit/components/passwordmgr/test/";
|
||||
var iframe1Doc = SpecialPowers.wrap(iframe1).contentDocument;
|
||||
var iframe2aDoc = SpecialPowers.wrap(iframe2a).contentDocument;
|
||||
var iframe2bDoc = SpecialPowers.wrap(iframe2b).contentDocument;
|
||||
var exampleCom = "http://example.com/tests/toolkit/components/passwordmgr/test/";
|
||||
var exampleOrg = "http://example.org/tests/toolkit/components/passwordmgr/test/";
|
||||
|
||||
switch (testNumber)
|
||||
{
|
||||
switch (testNumber)
|
||||
{
|
||||
case 1:
|
||||
// Load through a single proxy with authentication required 3 different
|
||||
// pages, first with one login, other two with their own different login.
|
||||
// We expect to show just a single dialog for proxy authentication and
|
||||
// then two dialogs to authenticate to login 1 and then login 2.
|
||||
ok(true, "doTest testNum 1");
|
||||
expectedLoads = 3;
|
||||
expectedDialogs = 3;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"r=1&" +
|
||||
"user=user1name&" +
|
||||
"pass=user1pass&" +
|
||||
"realm=mochirealm&" +
|
||||
"proxy_user=proxy_user&" +
|
||||
"proxy_pass=proxy_pass&" +
|
||||
"proxy_realm=proxy_realm";
|
||||
iframe2a.src = exampleOrg + "authenticate.sjs?" +
|
||||
"r=2&" +
|
||||
"user=user2name&" +
|
||||
"pass=user2pass&" +
|
||||
"realm=mochirealm2&" +
|
||||
"proxy_user=proxy_user&" +
|
||||
"proxy_pass=proxy_pass&" +
|
||||
"proxy_realm=proxy_realm";
|
||||
iframe2b.src = exampleOrg + "authenticate.sjs?" +
|
||||
"r=3&" +
|
||||
"user=user2name&" +
|
||||
"pass=user2pass&" +
|
||||
"realm=mochirealm2&" +
|
||||
"proxy_user=proxy_user&" +
|
||||
"proxy_pass=proxy_pass&" +
|
||||
"proxy_realm=proxy_realm";
|
||||
break;
|
||||
// Load through a single proxy with authentication required 3 different
|
||||
// pages, first with one login, other two with their own different login.
|
||||
// We expect to show just a single dialog for proxy authentication and
|
||||
// then two dialogs to authenticate to login 1 and then login 2.
|
||||
ok(true, "doTest testNum 1");
|
||||
expectedLoads = 3;
|
||||
expectedDialogs = 3;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"r=1&" +
|
||||
"user=user1name&" +
|
||||
"pass=user1pass&" +
|
||||
"realm=mochirealm&" +
|
||||
"proxy_user=proxy_user&" +
|
||||
"proxy_pass=proxy_pass&" +
|
||||
"proxy_realm=proxy_realm";
|
||||
iframe2a.src = exampleOrg + "authenticate.sjs?" +
|
||||
"r=2&" +
|
||||
"user=user2name&" +
|
||||
"pass=user2pass&" +
|
||||
"realm=mochirealm2&" +
|
||||
"proxy_user=proxy_user&" +
|
||||
"proxy_pass=proxy_pass&" +
|
||||
"proxy_realm=proxy_realm";
|
||||
iframe2b.src = exampleOrg + "authenticate.sjs?" +
|
||||
"r=3&" +
|
||||
"user=user2name&" +
|
||||
"pass=user2pass&" +
|
||||
"realm=mochirealm2&" +
|
||||
"proxy_user=proxy_user&" +
|
||||
"proxy_pass=proxy_pass&" +
|
||||
"proxy_realm=proxy_realm";
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Load an iframe with 3 subpages all requiring the same login through
|
||||
// anuthenticated proxy. We expect 2 dialogs, proxy authentication
|
||||
// and web authentication.
|
||||
ok(true, "doTest testNum 2");
|
||||
expectedLoads = 3;
|
||||
expectedDialogs = 2;
|
||||
iframe1.src = exampleCom + "subtst_prompt_async.html";
|
||||
iframe2a.src = "about:blank";
|
||||
iframe2b.src = "about:blank";
|
||||
break;
|
||||
// Load an iframe with 3 subpages all requiring the same login through
|
||||
// anuthenticated proxy. We expect 2 dialogs, proxy authentication
|
||||
// and web authentication.
|
||||
ok(true, "doTest testNum 2");
|
||||
expectedLoads = 3;
|
||||
expectedDialogs = 2;
|
||||
iframe1.src = exampleCom + "subtst_prompt_async.html";
|
||||
iframe2a.src = "about:blank";
|
||||
iframe2b.src = "about:blank";
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// Load in the iframe page through unauthenticated proxy
|
||||
// and discard the proxy authentication. We expect to see
|
||||
// unauthenticated page content and just a single dialog.
|
||||
ok(true, "doTest testNum 3");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 1;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"user=user4name&" +
|
||||
"pass=user4pass&" +
|
||||
"realm=mochirealm4&" +
|
||||
"proxy_user=proxy_user3&" +
|
||||
"proxy_pass=proxy_pass3&" +
|
||||
"proxy_realm=proxy_realm3";
|
||||
break;
|
||||
// Load in the iframe page through unauthenticated proxy
|
||||
// and discard the proxy authentication. We expect to see
|
||||
// unauthenticated page content and just a single dialog.
|
||||
ok(true, "doTest testNum 3");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 1;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"user=user4name&" +
|
||||
"pass=user4pass&" +
|
||||
"realm=mochirealm4&" +
|
||||
"proxy_user=proxy_user3&" +
|
||||
"proxy_pass=proxy_pass3&" +
|
||||
"proxy_realm=proxy_realm3";
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// Reload the frame from previous step and pass the proxy authentication
|
||||
// but cancel the WWW authentication. We should get the proxy=ok and WWW=fail
|
||||
// content as a result.
|
||||
ok(true, "doTest testNum 4");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 2;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"user=user4name&" +
|
||||
"pass=user4pass&" +
|
||||
"realm=mochirealm4&" +
|
||||
"proxy_user=proxy_user3&" +
|
||||
"proxy_pass=proxy_pass3&" +
|
||||
"proxy_realm=proxy_realm3";
|
||||
// Reload the frame from previous step and pass the proxy authentication
|
||||
// but cancel the WWW authentication. We should get the proxy=ok and WWW=fail
|
||||
// content as a result.
|
||||
ok(true, "doTest testNum 4");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 2;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"user=user4name&" +
|
||||
"pass=user4pass&" +
|
||||
"realm=mochirealm4&" +
|
||||
"proxy_user=proxy_user3&" +
|
||||
"proxy_pass=proxy_pass3&" +
|
||||
"proxy_realm=proxy_realm3";
|
||||
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// Same as the previous two steps but let the server generate
|
||||
// huge content load to check http channel is capable to handle
|
||||
// case when auth dialog is canceled or accepted before unauthenticated
|
||||
// content data is load from the server. (This would be better to
|
||||
// implement using delay of server response).
|
||||
ok(true, "doTest testNum 5");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 1;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"user=user5name&" +
|
||||
"pass=user5pass&" +
|
||||
"realm=mochirealm5&" +
|
||||
"proxy_user=proxy_user4&" +
|
||||
"proxy_pass=proxy_pass4&" +
|
||||
"proxy_realm=proxy_realm4&" +
|
||||
"huge=1";
|
||||
break;
|
||||
// Same as the previous two steps but let the server generate
|
||||
// huge content load to check http channel is capable to handle
|
||||
// case when auth dialog is canceled or accepted before unauthenticated
|
||||
// content data is load from the server. (This would be better to
|
||||
// implement using delay of server response).
|
||||
ok(true, "doTest testNum 5");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 1;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"user=user5name&" +
|
||||
"pass=user5pass&" +
|
||||
"realm=mochirealm5&" +
|
||||
"proxy_user=proxy_user4&" +
|
||||
"proxy_pass=proxy_pass4&" +
|
||||
"proxy_realm=proxy_realm4&" +
|
||||
"huge=1";
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// Reload the frame from the previous step and let the proxy
|
||||
// authentication pass but WWW fail. We expect two dialogs
|
||||
// and an unathenticated page content load.
|
||||
ok(true, "doTest testNum 6");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 2;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"user=user5name&" +
|
||||
"pass=user5pass&" +
|
||||
"realm=mochirealm5&" +
|
||||
"proxy_user=proxy_user4&" +
|
||||
"proxy_pass=proxy_pass4&" +
|
||||
"proxy_realm=proxy_realm4&" +
|
||||
"huge=1";
|
||||
break;
|
||||
// Reload the frame from the previous step and let the proxy
|
||||
// authentication pass but WWW fail. We expect two dialogs
|
||||
// and an unathenticated page content load.
|
||||
ok(true, "doTest testNum 6");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 2;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"user=user5name&" +
|
||||
"pass=user5pass&" +
|
||||
"realm=mochirealm5&" +
|
||||
"proxy_user=proxy_user4&" +
|
||||
"proxy_pass=proxy_pass4&" +
|
||||
"proxy_realm=proxy_realm4&" +
|
||||
"huge=1";
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// Reload again and let pass all authentication dialogs.
|
||||
// Check we get the authenticated content not broken by
|
||||
// the unauthenticated content.
|
||||
ok(true, "doTest testNum 7");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 1;
|
||||
iframe1Doc.location.reload();
|
||||
break;
|
||||
// Reload again and let pass all authentication dialogs.
|
||||
// Check we get the authenticated content not broken by
|
||||
// the unauthenticated content.
|
||||
ok(true, "doTest testNum 7");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 1;
|
||||
iframe1Doc.location.reload();
|
||||
break;
|
||||
|
||||
case 8:
|
||||
// Check we proccess all challenges sent by server when
|
||||
// user cancels prompts
|
||||
ok(true, "doTest testNum 8");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 5;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"user=user6name&" +
|
||||
"pass=user6pass&" +
|
||||
"realm=mochirealm6&" +
|
||||
"proxy_user=proxy_user5&" +
|
||||
"proxy_pass=proxy_pass5&" +
|
||||
"proxy_realm=proxy_realm5&" +
|
||||
"huge=1&" +
|
||||
"multiple=3";
|
||||
break;
|
||||
// Check we proccess all challenges sent by server when
|
||||
// user cancels prompts
|
||||
ok(true, "doTest testNum 8");
|
||||
expectedLoads = 1;
|
||||
expectedDialogs = 5;
|
||||
iframe1.src = exampleCom + "authenticate.sjs?" +
|
||||
"user=user6name&" +
|
||||
"pass=user6pass&" +
|
||||
"realm=mochirealm6&" +
|
||||
"proxy_user=proxy_user5&" +
|
||||
"proxy_pass=proxy_pass5&" +
|
||||
"proxy_realm=proxy_realm5&" +
|
||||
"huge=1&" +
|
||||
"multiple=3";
|
||||
break;
|
||||
|
||||
case 9:
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
finishTest();
|
||||
return;
|
||||
}
|
||||
|
||||
startCallbackTimer();
|
||||
startCallbackTimer();
|
||||
}
|
||||
|
||||
function handleDialog(doc, testNumber)
|
||||
{
|
||||
var dialog = doc.getElementById("commonDialog");
|
||||
var dialog = doc.getElementById("commonDialog");
|
||||
|
||||
switch (testNumber)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
dialog.acceptDialog();
|
||||
break;
|
||||
switch (testNumber)
|
||||
{
|
||||
case 1:
|
||||
case 2:
|
||||
dialog.acceptDialog();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
dialog.cancelDialog();
|
||||
setTimeout(onFrameLoad, 10); // there are no successful frames for test 3
|
||||
break;
|
||||
case 3:
|
||||
dialog.cancelDialog();
|
||||
setTimeout(onFrameLoad, 10); // there are no successful frames for test 3
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (expectedDialogs == 2)
|
||||
dialog.acceptDialog();
|
||||
else
|
||||
dialog.cancelDialog();
|
||||
break;
|
||||
case 4:
|
||||
if (expectedDialogs == 2)
|
||||
dialog.acceptDialog();
|
||||
else
|
||||
dialog.cancelDialog();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
dialog.cancelDialog();
|
||||
setTimeout(onFrameLoad, 10); // there are no successful frames for test 5
|
||||
break;
|
||||
case 5:
|
||||
dialog.cancelDialog();
|
||||
setTimeout(onFrameLoad, 10); // there are no successful frames for test 5
|
||||
break;
|
||||
|
||||
case 6:
|
||||
if (expectedDialogs == 2)
|
||||
dialog.acceptDialog();
|
||||
else
|
||||
dialog.cancelDialog();
|
||||
break;
|
||||
case 6:
|
||||
if (expectedDialogs == 2)
|
||||
dialog.acceptDialog();
|
||||
else
|
||||
dialog.cancelDialog();
|
||||
break;
|
||||
|
||||
case 7:
|
||||
dialog.acceptDialog();
|
||||
break;
|
||||
case 7:
|
||||
dialog.acceptDialog();
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if (expectedDialogs == 3 || expectedDialogs == 1)
|
||||
dialog.acceptDialog();
|
||||
else
|
||||
dialog.cancelDialog();
|
||||
break;
|
||||
case 8:
|
||||
if (expectedDialogs == 3 || expectedDialogs == 1)
|
||||
dialog.acceptDialog();
|
||||
else
|
||||
dialog.cancelDialog();
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "Unhandled testNum " + testNumber + " in handleDialog");
|
||||
}
|
||||
default:
|
||||
ok(false, "Unhandled testNum " + testNumber + " in handleDialog");
|
||||
}
|
||||
|
||||
if (--expectedDialogs > 0)
|
||||
startCallbackTimer();
|
||||
if (--expectedDialogs > 0)
|
||||
startCallbackTimer();
|
||||
}
|
||||
|
||||
function doCheck(testNumber)
|
||||
{
|
||||
var iframe1Doc = SpecialPowers.wrap(iframe1).contentDocument;
|
||||
var iframe2aDoc = SpecialPowers.wrap(iframe2a).contentDocument;
|
||||
var iframe2bDoc = SpecialPowers.wrap(iframe2b).contentDocument;
|
||||
var authok1;
|
||||
var proxyok1;
|
||||
var footnote;
|
||||
switch (testNumber)
|
||||
{
|
||||
case 1:
|
||||
ok(true, "doCheck testNum 1");
|
||||
is(monitor.windowsRegistered, 3, "Registered 3 open dialogs");
|
||||
var iframe1Doc = SpecialPowers.wrap(iframe1).contentDocument;
|
||||
var iframe2aDoc = SpecialPowers.wrap(iframe2a).contentDocument;
|
||||
var iframe2bDoc = SpecialPowers.wrap(iframe2b).contentDocument;
|
||||
var authok1;
|
||||
var proxyok1;
|
||||
var footnote;
|
||||
switch (testNumber)
|
||||
{
|
||||
case 1:
|
||||
ok(true, "doCheck testNum 1");
|
||||
is(monitor.windowsRegistered, 3, "Registered 3 open dialogs");
|
||||
|
||||
authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
|
||||
var authok2a = iframe2aDoc.getElementById("ok").textContent;
|
||||
var proxyok2a = iframe2aDoc.getElementById("proxy").textContent;
|
||||
var authok2a = iframe2aDoc.getElementById("ok").textContent;
|
||||
var proxyok2a = iframe2aDoc.getElementById("proxy").textContent;
|
||||
|
||||
var authok2b = iframe2bDoc.getElementById("ok").textContent;
|
||||
var proxyok2b = iframe2bDoc.getElementById("proxy").textContent;
|
||||
var authok2b = iframe2bDoc.getElementById("ok").textContent;
|
||||
var proxyok2b = iframe2bDoc.getElementById("proxy").textContent;
|
||||
|
||||
is(authok1, "PASS", "WWW Authorization OK, frame1");
|
||||
is(authok2a, "PASS", "WWW Authorization OK, frame2a");
|
||||
is(authok2b, "PASS", "WWW Authorization OK, frame2b");
|
||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
||||
is(proxyok2a, "PASS", "Proxy Authorization OK, frame2a");
|
||||
is(proxyok2b, "PASS", "Proxy Authorization OK, frame2b");
|
||||
break;
|
||||
is(authok1, "PASS", "WWW Authorization OK, frame1");
|
||||
is(authok2a, "PASS", "WWW Authorization OK, frame2a");
|
||||
is(authok2b, "PASS", "WWW Authorization OK, frame2b");
|
||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
||||
is(proxyok2a, "PASS", "Proxy Authorization OK, frame2a");
|
||||
is(proxyok2b, "PASS", "Proxy Authorization OK, frame2b");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
is(monitor.windowsRegistered, 2, "Registered 2 open dialogs");
|
||||
ok(true, "doCheck testNum 2");
|
||||
case 2:
|
||||
is(monitor.windowsRegistered, 2, "Registered 2 open dialogs");
|
||||
ok(true, "doCheck testNum 2");
|
||||
|
||||
function checkIframe(frame) {
|
||||
var doc = SpecialPowers.wrap(frame).contentDocument;
|
||||
function checkIframe(frame) {
|
||||
var doc = SpecialPowers.wrap(frame).contentDocument;
|
||||
|
||||
var authok = doc.getElementById("ok").textContent;
|
||||
var proxyok = doc.getElementById("proxy").textContent;
|
||||
var authok = doc.getElementById("ok").textContent;
|
||||
var proxyok = doc.getElementById("proxy").textContent;
|
||||
|
||||
is(authok, "PASS", "WWW Authorization OK, " + frame.id);
|
||||
is(proxyok, "PASS", "Proxy Authorization OK, " + frame.id);
|
||||
}
|
||||
is(authok, "PASS", "WWW Authorization OK, " + frame.id);
|
||||
is(proxyok, "PASS", "Proxy Authorization OK, " + frame.id);
|
||||
}
|
||||
|
||||
checkIframe(iframe1Doc.getElementById("iframe1"));
|
||||
checkIframe(iframe1Doc.getElementById("iframe2"));
|
||||
checkIframe(iframe1Doc.getElementById("iframe3"));
|
||||
break;
|
||||
checkIframe(iframe1Doc.getElementById("iframe1"));
|
||||
checkIframe(iframe1Doc.getElementById("iframe2"));
|
||||
checkIframe(iframe1Doc.getElementById("iframe3"));
|
||||
break;
|
||||
|
||||
case 3:
|
||||
ok(true, "doCheck testNum 3");
|
||||
is(monitor.windowsRegistered, 1, "Registered 1 open dialog");
|
||||
case 3:
|
||||
ok(true, "doCheck testNum 3");
|
||||
is(monitor.windowsRegistered, 1, "Registered 1 open dialog");
|
||||
|
||||
// ensure that the page content is not displayed on failed proxy auth
|
||||
is(iframe1Doc.getElementById("ok"), null, "frame did not load");
|
||||
break;
|
||||
// ensure that the page content is not displayed on failed proxy auth
|
||||
is(iframe1Doc.getElementById("ok"), null, "frame did not load");
|
||||
break;
|
||||
|
||||
case 4:
|
||||
ok(true, "doCheck testNum 4");
|
||||
is(monitor.windowsRegistered, 2, "Registered 2 open dialogs");
|
||||
authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
case 4:
|
||||
ok(true, "doCheck testNum 4");
|
||||
is(monitor.windowsRegistered, 2, "Registered 2 open dialogs");
|
||||
authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
|
||||
is(authok1, "FAIL", "WWW Authorization FAILED, frame1");
|
||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
||||
break;
|
||||
is(authok1, "FAIL", "WWW Authorization FAILED, frame1");
|
||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
||||
break;
|
||||
|
||||
case 5:
|
||||
ok(true, "doCheck testNum 5");
|
||||
is(monitor.windowsRegistered, 1, "Registered 1 open dialog");
|
||||
case 5:
|
||||
ok(true, "doCheck testNum 5");
|
||||
is(monitor.windowsRegistered, 1, "Registered 1 open dialog");
|
||||
|
||||
// ensure that the page content is not displayed on failed proxy auth
|
||||
is(iframe1Doc.getElementById("footnote"), null, "frame did not load");
|
||||
break;
|
||||
// ensure that the page content is not displayed on failed proxy auth
|
||||
is(iframe1Doc.getElementById("footnote"), null, "frame did not load");
|
||||
break;
|
||||
|
||||
case 6:
|
||||
ok(true, "doCheck testNum 6");
|
||||
is(monitor.windowsRegistered, 2, "Registered 2 open dialogs");
|
||||
authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
footnote = iframe1Doc.getElementById("footnote").textContent;
|
||||
case 6:
|
||||
ok(true, "doCheck testNum 6");
|
||||
is(monitor.windowsRegistered, 2, "Registered 2 open dialogs");
|
||||
authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
footnote = iframe1Doc.getElementById("footnote").textContent;
|
||||
|
||||
is(authok1, "FAIL", "WWW Authorization FAILED, frame1");
|
||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
||||
is(footnote, "This is a footnote after the huge content fill",
|
||||
"Footnote present and loaded completely");
|
||||
break;
|
||||
is(authok1, "FAIL", "WWW Authorization FAILED, frame1");
|
||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
||||
is(footnote, "This is a footnote after the huge content fill",
|
||||
"Footnote present and loaded completely");
|
||||
break;
|
||||
|
||||
case 7:
|
||||
ok(true, "doCheck testNum 7");
|
||||
is(monitor.windowsRegistered, 1, "Registered 1 open dialogs");
|
||||
authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
footnote = iframe1Doc.getElementById("footnote").textContent;
|
||||
case 7:
|
||||
ok(true, "doCheck testNum 7");
|
||||
is(monitor.windowsRegistered, 1, "Registered 1 open dialogs");
|
||||
authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
footnote = iframe1Doc.getElementById("footnote").textContent;
|
||||
|
||||
is(authok1, "PASS", "WWW Authorization OK, frame1");
|
||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
||||
is(footnote, "This is a footnote after the huge content fill",
|
||||
"Footnote present and loaded completely");
|
||||
break;
|
||||
is(authok1, "PASS", "WWW Authorization OK, frame1");
|
||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
||||
is(footnote, "This is a footnote after the huge content fill",
|
||||
"Footnote present and loaded completely");
|
||||
break;
|
||||
|
||||
case 8:
|
||||
ok(true, "doCheck testNum 8");
|
||||
is(monitor.windowsRegistered, 5, "Registered 5 open dialogs");
|
||||
authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
footnote = iframe1Doc.getElementById("footnote").textContent;
|
||||
case 8:
|
||||
ok(true, "doCheck testNum 8");
|
||||
is(monitor.windowsRegistered, 5, "Registered 5 open dialogs");
|
||||
authok1 = iframe1Doc.getElementById("ok").textContent;
|
||||
proxyok1 = iframe1Doc.getElementById("proxy").textContent;
|
||||
footnote = iframe1Doc.getElementById("footnote").textContent;
|
||||
|
||||
is(authok1, "PASS", "WWW Authorization OK, frame1");
|
||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
||||
is(footnote, "This is a footnote after the huge content fill",
|
||||
"Footnote present and loaded completely");
|
||||
break;
|
||||
is(authok1, "PASS", "WWW Authorization OK, frame1");
|
||||
is(proxyok1, "PASS", "Proxy Authorization OK, frame1");
|
||||
is(footnote, "This is a footnote after the huge content fill",
|
||||
"Footnote present and loaded completely");
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "Unhandled testNum " + testNumber + " in doCheck");
|
||||
}
|
||||
default:
|
||||
ok(false, "Unhandled testNum " + testNumber + " in doCheck");
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
@ -29,9 +29,9 @@ function initLogins() {
|
|||
createInstance(Ci.nsILoginInfo);
|
||||
|
||||
login1.init("http://mochi.test:8888", null, "xhr",
|
||||
"xhruser1", "xhrpass1", "", "");
|
||||
"xhruser1", "xhrpass1", "", "");
|
||||
login2.init("http://mochi.test:8888", null, "xhr2",
|
||||
"xhruser2", "xhrpass2", "", "");
|
||||
"xhruser2", "xhrpass2", "", "");
|
||||
|
||||
SpecialPowers.Services.logins.addLogin(login1);
|
||||
SpecialPowers.Services.logins.addLogin(login2);
|
||||
|
@ -57,53 +57,53 @@ function handleDialog(doc, testNum) {
|
|||
|
||||
switch (testNum) {
|
||||
case 1:
|
||||
is(username, "xhruser1", "Checking provided username");
|
||||
is(password, "xhrpass1", "Checking provided password");
|
||||
break;
|
||||
is(username, "xhruser1", "Checking provided username");
|
||||
is(password, "xhrpass1", "Checking provided password");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
is(username, "xhruser2", "Checking provided username");
|
||||
is(password, "xhrpass2", "Checking provided password");
|
||||
is(username, "xhruser2", "Checking provided username");
|
||||
is(password, "xhrpass2", "Checking provided password");
|
||||
|
||||
// Check that the dialog is modal, chrome and dependent;
|
||||
// We can't just check window.opener because that'll be
|
||||
// a content window, which therefore isn't exposed (it'll lie and
|
||||
// be null).
|
||||
var win = doc.defaultView;
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var treeOwner = win.docShell.treeOwner;
|
||||
treeOwner.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
var flags = treeOwner.getInterface(Ci.nsIXULWindow).chromeFlags;
|
||||
var wbc = treeOwner.getInterface(Ci.nsIWebBrowserChrome);
|
||||
info("Flags: " + flags);
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_CHROME) != 0,
|
||||
"Dialog should be opened as chrome");
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_DIALOG) != 0,
|
||||
"Dialog should be opened as a dialog");
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_DEPENDENT) != 0,
|
||||
"Dialog should be opened as dependent.");
|
||||
ok(wbc.isWindowModal(), "Dialog should be modal");
|
||||
// Check that the dialog is modal, chrome and dependent;
|
||||
// We can't just check window.opener because that'll be
|
||||
// a content window, which therefore isn't exposed (it'll lie and
|
||||
// be null).
|
||||
var win = doc.defaultView;
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var treeOwner = win.docShell.treeOwner;
|
||||
treeOwner.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
var flags = treeOwner.getInterface(Ci.nsIXULWindow).chromeFlags;
|
||||
var wbc = treeOwner.getInterface(Ci.nsIWebBrowserChrome);
|
||||
info("Flags: " + flags);
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_CHROME) != 0,
|
||||
"Dialog should be opened as chrome");
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_DIALOG) != 0,
|
||||
"Dialog should be opened as a dialog");
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_DEPENDENT) != 0,
|
||||
"Dialog should be opened as dependent.");
|
||||
ok(wbc.isWindowModal(), "Dialog should be modal");
|
||||
|
||||
// Check that the right tab is focused:
|
||||
var browserWin = SpecialPowers.Services.wm.getMostRecentWindow("navigator:browser");
|
||||
var spec = browserWin.gBrowser.selectedBrowser.currentURI.spec;
|
||||
ok(spec.startsWith("http://mochi.test:8888"),
|
||||
"Tab with remote URI (rather than about:blank) should be focused (" + spec + ")");
|
||||
// Check that the right tab is focused:
|
||||
var browserWin = SpecialPowers.Services.wm.getMostRecentWindow("navigator:browser");
|
||||
var spec = browserWin.gBrowser.selectedBrowser.currentURI.spec;
|
||||
ok(spec.startsWith("http://mochi.test:8888"),
|
||||
"Tab with remote URI (rather than about:blank) should be focused (" + spec + ")");
|
||||
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "Uhh, unhandled switch for testNum #" + testNum);
|
||||
break;
|
||||
ok(false, "Uhh, unhandled switch for testNum #" + testNum);
|
||||
break;
|
||||
}
|
||||
|
||||
// Explicitly cancel the dialog and report a fail in this failure
|
||||
// case, rather than letting the dialog get stuck due to an auth
|
||||
// failure and having the test timeout.
|
||||
if (!username && !password) {
|
||||
ok(false, "No values prefilled");
|
||||
clickOK = false;
|
||||
ok(false, "No values prefilled");
|
||||
clickOK = false;
|
||||
}
|
||||
|
||||
if (clickOK)
|
||||
|
@ -127,20 +127,20 @@ function xhrLoad(xmlDoc) {
|
|||
|
||||
switch (testNum) {
|
||||
case 1:
|
||||
is(username, "xhruser1", "Checking provided username");
|
||||
is(password, "xhrpass1", "Checking provided password");
|
||||
break;
|
||||
is(username, "xhruser1", "Checking provided username");
|
||||
is(password, "xhrpass1", "Checking provided password");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
is(username, "xhruser2", "Checking provided username");
|
||||
is(password, "xhrpass2", "Checking provided password");
|
||||
is(username, "xhruser2", "Checking provided username");
|
||||
is(password, "xhrpass2", "Checking provided password");
|
||||
|
||||
newWin.close();
|
||||
break;
|
||||
newWin.close();
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "Uhh, unhandled switch for testNum #" + testNum);
|
||||
break;
|
||||
ok(false, "Uhh, unhandled switch for testNum #" + testNum);
|
||||
break;
|
||||
}
|
||||
|
||||
doTest();
|
||||
|
@ -149,21 +149,21 @@ function xhrLoad(xmlDoc) {
|
|||
function doTest() {
|
||||
switch (++testNum) {
|
||||
case 1:
|
||||
startCallbackTimer();
|
||||
makeRequest("authenticate.sjs?user=xhruser1&pass=xhrpass1&realm=xhr");
|
||||
break;
|
||||
startCallbackTimer();
|
||||
makeRequest("authenticate.sjs?user=xhruser1&pass=xhrpass1&realm=xhr");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Test correct parenting, by opening another tab in the foreground,
|
||||
// and making sure the prompt re-focuses the original tab when shown:
|
||||
newWin = window.open();
|
||||
newWin.focus();
|
||||
startCallbackTimer();
|
||||
makeRequest("authenticate.sjs?user=xhruser2&pass=xhrpass2&realm=xhr2");
|
||||
break;
|
||||
// Test correct parenting, by opening another tab in the foreground,
|
||||
// and making sure the prompt re-focuses the original tab when shown:
|
||||
newWin = window.open();
|
||||
newWin.focus();
|
||||
startCallbackTimer();
|
||||
makeRequest("authenticate.sjs?user=xhruser2&pass=xhrpass2&realm=xhr2");
|
||||
break;
|
||||
|
||||
default:
|
||||
finishTest();
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,9 +29,9 @@ function initLogins() {
|
|||
.createInstance(Ci.nsILoginInfo);
|
||||
|
||||
login1.init("http://mochi.test:8888", null, "xml",
|
||||
"xmluser1", "xmlpass1", "", "");
|
||||
"xmluser1", "xmlpass1", "", "");
|
||||
login2.init("http://mochi.test:8888", null, "xml2",
|
||||
"xmluser2", "xmlpass2", "", "");
|
||||
"xmluser2", "xmlpass2", "", "");
|
||||
|
||||
SpecialPowers.Services.logins.addLogin(login1);
|
||||
SpecialPowers.Services.logins.addLogin(login2);
|
||||
|
@ -49,52 +49,52 @@ function handleDialog(doc, testNum) {
|
|||
|
||||
switch (testNum) {
|
||||
case 1:
|
||||
is(username, "xmluser1", "Checking provided username");
|
||||
is(password, "xmlpass1", "Checking provided password");
|
||||
break;
|
||||
is(username, "xmluser1", "Checking provided username");
|
||||
is(password, "xmlpass1", "Checking provided password");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
is(username, "xmluser2", "Checking provided username");
|
||||
is(password, "xmlpass2", "Checking provided password");
|
||||
is(username, "xmluser2", "Checking provided username");
|
||||
is(password, "xmlpass2", "Checking provided password");
|
||||
|
||||
// Check that the dialog is modal, chrome and dependent;
|
||||
// We can't just check window.opener because that'll be
|
||||
// a content window, which therefore isn't exposed (it'll lie and
|
||||
// be null).
|
||||
var win = doc.defaultView;
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var treeOwner = win.docShell.treeOwner;
|
||||
treeOwner.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
var flags = treeOwner.getInterface(Ci.nsIXULWindow).chromeFlags;
|
||||
var wbc = treeOwner.getInterface(Ci.nsIWebBrowserChrome);
|
||||
info("Flags: " + flags);
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_CHROME) != 0,
|
||||
"Dialog should be opened as chrome");
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_DIALOG) != 0,
|
||||
"Dialog should be opened as a dialog");
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_DEPENDENT) != 0,
|
||||
"Dialog should be opened as dependent.");
|
||||
ok(wbc.isWindowModal(), "Dialog should be modal");
|
||||
// Check that the dialog is modal, chrome and dependent;
|
||||
// We can't just check window.opener because that'll be
|
||||
// a content window, which therefore isn't exposed (it'll lie and
|
||||
// be null).
|
||||
var win = doc.defaultView;
|
||||
var Ci = SpecialPowers.Ci;
|
||||
var treeOwner = win.docShell.treeOwner;
|
||||
treeOwner.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
var flags = treeOwner.getInterface(Ci.nsIXULWindow).chromeFlags;
|
||||
var wbc = treeOwner.getInterface(Ci.nsIWebBrowserChrome);
|
||||
info("Flags: " + flags);
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_CHROME) != 0,
|
||||
"Dialog should be opened as chrome");
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_OPENAS_DIALOG) != 0,
|
||||
"Dialog should be opened as a dialog");
|
||||
ok((flags & Ci.nsIWebBrowserChrome.CHROME_DEPENDENT) != 0,
|
||||
"Dialog should be opened as dependent.");
|
||||
ok(wbc.isWindowModal(), "Dialog should be modal");
|
||||
|
||||
// Check that the right tab is focused:
|
||||
var browserWin = SpecialPowers.Services.wm.getMostRecentWindow("navigator:browser");
|
||||
var spec = browserWin.gBrowser.selectedBrowser.currentURI.spec;
|
||||
ok(spec.startsWith("http://mochi.test:8888"),
|
||||
"Tab with remote URI (rather than about:blank) should be focused (" + spec + ")");
|
||||
// Check that the right tab is focused:
|
||||
var browserWin = SpecialPowers.Services.wm.getMostRecentWindow("navigator:browser");
|
||||
var spec = browserWin.gBrowser.selectedBrowser.currentURI.spec;
|
||||
ok(spec.startsWith("http://mochi.test:8888"),
|
||||
"Tab with remote URI (rather than about:blank) should be focused (" + spec + ")");
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "Uhh, unhandled switch for testNum #" + testNum);
|
||||
break;
|
||||
ok(false, "Uhh, unhandled switch for testNum #" + testNum);
|
||||
break;
|
||||
}
|
||||
|
||||
// Explicitly cancel the dialog and report a fail in this failure
|
||||
// case, rather than letting the dialog get stuck due to an auth
|
||||
// failure and having the test timeout.
|
||||
if (!username && !password) {
|
||||
ok(false, "No values prefilled");
|
||||
clickOK = false;
|
||||
ok(false, "No values prefilled");
|
||||
clickOK = false;
|
||||
}
|
||||
|
||||
if (clickOK)
|
||||
|
@ -117,20 +117,20 @@ function xmlLoad(responseDoc) {
|
|||
|
||||
switch (testNum) {
|
||||
case 1:
|
||||
is(username, "xmluser1", "Checking provided username");
|
||||
is(password, "xmlpass1", "Checking provided password");
|
||||
break;
|
||||
is(username, "xmluser1", "Checking provided username");
|
||||
is(password, "xmlpass1", "Checking provided password");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
is(username, "xmluser2", "Checking provided username");
|
||||
is(password, "xmlpass2", "Checking provided password");
|
||||
is(username, "xmluser2", "Checking provided username");
|
||||
is(password, "xmlpass2", "Checking provided password");
|
||||
|
||||
newWin.close();
|
||||
break;
|
||||
newWin.close();
|
||||
break;
|
||||
|
||||
default:
|
||||
ok(false, "Uhh, unhandled switch for testNum #" + testNum);
|
||||
break;
|
||||
ok(false, "Uhh, unhandled switch for testNum #" + testNum);
|
||||
break;
|
||||
}
|
||||
|
||||
doTest();
|
||||
|
@ -139,21 +139,21 @@ function xmlLoad(responseDoc) {
|
|||
function doTest() {
|
||||
switch (++testNum) {
|
||||
case 1:
|
||||
startCallbackTimer();
|
||||
makeRequest("authenticate.sjs?user=xmluser1&pass=xmlpass1&realm=xml");
|
||||
break;
|
||||
startCallbackTimer();
|
||||
makeRequest("authenticate.sjs?user=xmluser1&pass=xmlpass1&realm=xml");
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// Test correct parenting, by opening another tab in the foreground,
|
||||
// and making sure the prompt re-focuses the original tab when shown:
|
||||
newWin = window.open();
|
||||
newWin.focus();
|
||||
startCallbackTimer();
|
||||
makeRequest("authenticate.sjs?user=xmluser2&pass=xmlpass2&realm=xml2");
|
||||
break;
|
||||
// Test correct parenting, by opening another tab in the foreground,
|
||||
// and making sure the prompt re-focuses the original tab when shown:
|
||||
newWin = window.open();
|
||||
newWin.focus();
|
||||
startCallbackTimer();
|
||||
makeRequest("authenticate.sjs?user=xmluser2&pass=xmlpass2&realm=xml2");
|
||||
break;
|
||||
|
||||
default:
|
||||
SimpleTest.finish();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ function makeRequest(uri) {
|
|||
var xmlDoc = document.implementation.createDocument("", "test", null);
|
||||
|
||||
function documentLoaded(e) {
|
||||
xmlLoad(xmlDoc);
|
||||
xmlLoad(xmlDoc);
|
||||
}
|
||||
xmlDoc.addEventListener("load", documentLoaded);
|
||||
xmlDoc.load(uri);
|
||||
|
|
|
@ -16,23 +16,23 @@ var crypto = new OSCrypto();
|
|||
add_task(function test_getIELoginHash()
|
||||
{
|
||||
Assert.equal(crypto.getIELoginHash("https://bugzilla.mozilla.org/page.cgi"),
|
||||
"4A66FE96607885790F8E67B56EEE52AB539BAFB47D");
|
||||
"4A66FE96607885790F8E67B56EEE52AB539BAFB47D");
|
||||
|
||||
Assert.equal(crypto.getIELoginHash("https://github.com/login"),
|
||||
"0112F7DCE67B8579EA01367678AA44AB9868B5A143");
|
||||
"0112F7DCE67B8579EA01367678AA44AB9868B5A143");
|
||||
|
||||
Assert.equal(crypto.getIELoginHash("https://login.live.com/login.srf"),
|
||||
"FBF92E5D804C82717A57856533B779676D92903688");
|
||||
"FBF92E5D804C82717A57856533B779676D92903688");
|
||||
|
||||
Assert.equal(crypto.getIELoginHash("https://preview.c9.io/riadh/w1/pass.1.html"),
|
||||
"6935CF27628830605927F86AB53831016FC8973D1A");
|
||||
"6935CF27628830605927F86AB53831016FC8973D1A");
|
||||
|
||||
|
||||
Assert.equal(crypto.getIELoginHash("https://reviewboard.mozilla.org/account/login/"),
|
||||
"09141FD287E2E59A8B1D3BB5671537FD3D6B61337A");
|
||||
"09141FD287E2E59A8B1D3BB5671537FD3D6B61337A");
|
||||
|
||||
Assert.equal(crypto.getIELoginHash("https://www.facebook.com/"),
|
||||
"EF44D3E034009CB0FD1B1D81A1FF3F3335213BD796");
|
||||
"EF44D3E034009CB0FD1B1D81A1FF3F3335213BD796");
|
||||
|
||||
});
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ function checkLoginItems(logins, items) {
|
|||
let duplicates = findDuplicates(logins);
|
||||
|
||||
let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
|
||||
{ dateStyle: "medium" });
|
||||
{ dateStyle: "medium" });
|
||||
for (let login of logins) {
|
||||
if (login.username && !duplicates.has(login.username)) {
|
||||
// If login is not duplicate and we can't find an item for it, fail.
|
||||
|
@ -138,29 +138,29 @@ function getExpectedLogins(hostname) {
|
|||
|
||||
function loginList() {
|
||||
return [
|
||||
new LoginInfo("http://www.example.com", "http://www.example.com", null,
|
||||
"username1", "password",
|
||||
"form_field_username", "form_field_password"),
|
||||
new LoginInfo("http://www.example.com", "http://www.example.com", null,
|
||||
"username1", "password",
|
||||
"form_field_username", "form_field_password"),
|
||||
|
||||
new LoginInfo("http://www.example.com", "http://www.example.com", null,
|
||||
"username2", "password",
|
||||
"form_field_username", "form_field_password"),
|
||||
new LoginInfo("http://www.example.com", "http://www.example.com", null,
|
||||
"username2", "password",
|
||||
"form_field_username", "form_field_password"),
|
||||
|
||||
new LoginInfo("http://www2.example.com", "http://www.example.com", null,
|
||||
"username", "password",
|
||||
"form_field_username", "form_field_password"),
|
||||
new LoginInfo("http://www2.example.com", "http://www2.example.com", null,
|
||||
"username", "password2",
|
||||
"form_field_username", "form_field_password"),
|
||||
new LoginInfo("http://www2.example.com", "http://www2.example.com", null,
|
||||
"username2", "password2",
|
||||
"form_field_username", "form_field_password"),
|
||||
new LoginInfo("http://www2.example.com", "http://www.example.com", null,
|
||||
"username", "password",
|
||||
"form_field_username", "form_field_password"),
|
||||
new LoginInfo("http://www2.example.com", "http://www2.example.com", null,
|
||||
"username", "password2",
|
||||
"form_field_username", "form_field_password"),
|
||||
new LoginInfo("http://www2.example.com", "http://www2.example.com", null,
|
||||
"username2", "password2",
|
||||
"form_field_username", "form_field_password"),
|
||||
|
||||
new LoginInfo("http://www3.example.com", "http://www.example.com", null,
|
||||
"", "password",
|
||||
"form_field_username", "form_field_password"),
|
||||
new LoginInfo("http://www3.example.com", "http://www3.example.com", null,
|
||||
"", "password2",
|
||||
"form_field_username", "form_field_password"),
|
||||
new LoginInfo("http://www3.example.com", "http://www.example.com", null,
|
||||
"", "password",
|
||||
"form_field_username", "form_field_password"),
|
||||
new LoginInfo("http://www3.example.com", "http://www3.example.com", null,
|
||||
"", "password2",
|
||||
"form_field_username", "form_field_password"),
|
||||
];
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ for (let tc of TESTCASES) {
|
|||
add_task(async function() {
|
||||
info("Starting testcase: " + testcase.description);
|
||||
let document = MockDocument.createTestDocument("http://localhost:8080/test/",
|
||||
testcase.document);
|
||||
testcase.document);
|
||||
|
||||
let input = document.querySelector("input");
|
||||
MockDocument.mockOwnerDocumentProperty(input, document, "http://localhost:8080/test/");
|
||||
|
|
|
@ -84,7 +84,7 @@ for (let tc of TESTCASES) {
|
|||
add_task(async function() {
|
||||
info("Starting testcase: " + testcase.description);
|
||||
let document = MockDocument.createTestDocument("http://localhost:8080/test/",
|
||||
testcase.document);
|
||||
testcase.document);
|
||||
|
||||
let input = document.querySelector("input");
|
||||
MockDocument.mockOwnerDocumentProperty(input, document, "http://localhost:8080/test/");
|
||||
|
|
|
@ -84,8 +84,8 @@ add_task(function test_search_all_wildcard()
|
|||
Assert.equal(Services.logins.searchLogins({}, matchData).length, 1);
|
||||
|
||||
Assert.equal(Services.logins.findLogins({}, "http://any.example.com",
|
||||
"http://www.example.com",
|
||||
null).length, 1);
|
||||
"http://www.example.com",
|
||||
null).length, 1);
|
||||
|
||||
Assert.equal(Services.logins.countLogins("http://any.example.com",
|
||||
"http://www.example.com",
|
||||
|
@ -99,7 +99,7 @@ add_task(function test_search_all_wildcard()
|
|||
add_task(function test_searchLogins_wildcard()
|
||||
{
|
||||
let logins = Services.logins.searchLogins({},
|
||||
newPropertyBag({ formSubmitURL: "" }));
|
||||
newPropertyBag({ formSubmitURL: "" }));
|
||||
|
||||
let loginInfo = TestData.formLogin({ hostname: "http://any.example.com",
|
||||
formSubmitURL: "" });
|
||||
|
|
|
@ -243,8 +243,8 @@ add_task(function test_modifyLogin_nsILoginInfo()
|
|||
|
||||
// Modifying a login to match an existing one should not be possible.
|
||||
Assert.throws(
|
||||
() => Services.logins.modifyLogin(loginInfo, differentLoginInfo),
|
||||
/already exists/);
|
||||
() => Services.logins.modifyLogin(loginInfo, differentLoginInfo),
|
||||
/already exists/);
|
||||
LoginTestUtils.checkLogins([loginInfo, differentLoginInfo]);
|
||||
|
||||
LoginTestUtils.clearData();
|
||||
|
@ -310,8 +310,8 @@ add_task(function test_modifyLogin_nsIProperyBag()
|
|||
|
||||
// Modifying a login to match an existing one should not be possible.
|
||||
Assert.throws(
|
||||
() => Services.logins.modifyLogin(loginInfo, differentLoginProperties),
|
||||
/already exists/);
|
||||
() => Services.logins.modifyLogin(loginInfo, differentLoginProperties),
|
||||
/already exists/);
|
||||
LoginTestUtils.checkLogins([loginInfo, differentLoginInfo]);
|
||||
|
||||
LoginTestUtils.clearData();
|
||||
|
|
|
@ -43,9 +43,9 @@ add_task(function test_logins_decrypt_failure()
|
|||
Assert.equal(Services.logins.findLogins({}, "", "", "").length, 0);
|
||||
Assert.equal(Services.logins.searchLogins({}, newPropertyBag()).length, 0);
|
||||
Assert.throws(() => Services.logins.modifyLogin(logins[0], newPropertyBag()),
|
||||
/No matching logins/);
|
||||
/No matching logins/);
|
||||
Assert.throws(() => Services.logins.removeLogin(logins[0]),
|
||||
/No matching logins/);
|
||||
/No matching logins/);
|
||||
|
||||
// The function that counts logins sees the non-decryptable entries also.
|
||||
Assert.equal(Services.logins.countLogins("", "", ""), logins.length);
|
||||
|
@ -91,8 +91,8 @@ add_task(function test_add_logins_with_decrypt_failure()
|
|||
|
||||
// A different login but with the same GUID.
|
||||
let loginDupeGuid = new LoginInfo("http://www.example3.com", "http://www.example3.com", null,
|
||||
"the username", "the password",
|
||||
"form_field_username", "form_field_password");
|
||||
"the username", "the password",
|
||||
"form_field_username", "form_field_password");
|
||||
loginDupeGuid.QueryInterface(Ci.nsILoginMetaInfo);
|
||||
loginDupeGuid.guid = login.guid;
|
||||
|
||||
|
|
|
@ -180,7 +180,7 @@ add_task(function test_searchLogins()
|
|||
add_task(function test_searchLogins_invalid()
|
||||
{
|
||||
Assert.throws(() => Services.logins.searchLogins({},
|
||||
newPropertyBag({ username: "value" })),
|
||||
newPropertyBag({ username: "value" })),
|
||||
/Unexpected field/);
|
||||
});
|
||||
|
||||
|
|
|
@ -13,34 +13,34 @@ var TestObserver = {
|
|||
Assert.equal(data, expectedNotification);
|
||||
|
||||
switch (data) {
|
||||
case "addLogin":
|
||||
Assert.ok(subject instanceof Ci.nsILoginInfo);
|
||||
Assert.ok(subject instanceof Ci.nsILoginMetaInfo);
|
||||
Assert.ok(expectedData.equals(subject)); // nsILoginInfo.equals()
|
||||
break;
|
||||
case "modifyLogin":
|
||||
Assert.ok(subject instanceof Ci.nsIArray);
|
||||
Assert.equal(subject.length, 2);
|
||||
var oldLogin = subject.queryElementAt(0, Ci.nsILoginInfo);
|
||||
var newLogin = subject.queryElementAt(1, Ci.nsILoginInfo);
|
||||
Assert.ok(expectedData[0].equals(oldLogin)); // nsILoginInfo.equals()
|
||||
Assert.ok(expectedData[1].equals(newLogin));
|
||||
break;
|
||||
case "removeLogin":
|
||||
Assert.ok(subject instanceof Ci.nsILoginInfo);
|
||||
Assert.ok(subject instanceof Ci.nsILoginMetaInfo);
|
||||
Assert.ok(expectedData.equals(subject)); // nsILoginInfo.equals()
|
||||
break;
|
||||
case "removeAllLogins":
|
||||
Assert.equal(subject, null);
|
||||
break;
|
||||
case "hostSavingEnabled":
|
||||
case "hostSavingDisabled":
|
||||
Assert.ok(subject instanceof Ci.nsISupportsString);
|
||||
Assert.equal(subject.data, expectedData);
|
||||
break;
|
||||
default:
|
||||
do_throw("Unhandled notification: " + data + " / " + topic);
|
||||
case "addLogin":
|
||||
Assert.ok(subject instanceof Ci.nsILoginInfo);
|
||||
Assert.ok(subject instanceof Ci.nsILoginMetaInfo);
|
||||
Assert.ok(expectedData.equals(subject)); // nsILoginInfo.equals()
|
||||
break;
|
||||
case "modifyLogin":
|
||||
Assert.ok(subject instanceof Ci.nsIArray);
|
||||
Assert.equal(subject.length, 2);
|
||||
var oldLogin = subject.queryElementAt(0, Ci.nsILoginInfo);
|
||||
var newLogin = subject.queryElementAt(1, Ci.nsILoginInfo);
|
||||
Assert.ok(expectedData[0].equals(oldLogin)); // nsILoginInfo.equals()
|
||||
Assert.ok(expectedData[1].equals(newLogin));
|
||||
break;
|
||||
case "removeLogin":
|
||||
Assert.ok(subject instanceof Ci.nsILoginInfo);
|
||||
Assert.ok(subject instanceof Ci.nsILoginMetaInfo);
|
||||
Assert.ok(expectedData.equals(subject)); // nsILoginInfo.equals()
|
||||
break;
|
||||
case "removeAllLogins":
|
||||
Assert.equal(subject, null);
|
||||
break;
|
||||
case "hostSavingEnabled":
|
||||
case "hostSavingDisabled":
|
||||
Assert.ok(subject instanceof Ci.nsISupportsString);
|
||||
Assert.equal(subject.data, expectedData);
|
||||
break;
|
||||
default:
|
||||
do_throw("Unhandled notification: " + data + " / " + topic);
|
||||
}
|
||||
|
||||
expectedNotification = null; // ensure a duplicate is flagged as unexpected.
|
||||
|
@ -51,122 +51,122 @@ var TestObserver = {
|
|||
add_task(function test_notifications()
|
||||
{
|
||||
|
||||
try {
|
||||
try {
|
||||
|
||||
var testnum = 0;
|
||||
var testdesc = "Setup of nsLoginInfo test-users";
|
||||
var testnum = 0;
|
||||
var testdesc = "Setup of nsLoginInfo test-users";
|
||||
|
||||
var testuser1 = new LoginInfo("http://testhost1", "", null,
|
||||
"dummydude", "itsasecret", "put_user_here", "put_pw_here");
|
||||
var testuser1 = new LoginInfo("http://testhost1", "", null,
|
||||
"dummydude", "itsasecret", "put_user_here", "put_pw_here");
|
||||
|
||||
var testuser2 = new LoginInfo("http://testhost2", "", null,
|
||||
"dummydude2", "itsasecret2", "put_user2_here", "put_pw2_here");
|
||||
var testuser2 = new LoginInfo("http://testhost2", "", null,
|
||||
"dummydude2", "itsasecret2", "put_user2_here", "put_pw2_here");
|
||||
|
||||
Services.obs.addObserver(TestObserver, "passwordmgr-storage-changed");
|
||||
Services.obs.addObserver(TestObserver, "passwordmgr-storage-changed");
|
||||
|
||||
|
||||
/* ========== 1 ========== */
|
||||
testnum = 1;
|
||||
testdesc = "Initial connection to storage module";
|
||||
/* ========== 1 ========== */
|
||||
testnum = 1;
|
||||
testdesc = "Initial connection to storage module";
|
||||
|
||||
/* ========== 2 ========== */
|
||||
testnum++;
|
||||
testdesc = "addLogin";
|
||||
/* ========== 2 ========== */
|
||||
testnum++;
|
||||
testdesc = "addLogin";
|
||||
|
||||
expectedNotification = "addLogin";
|
||||
expectedData = testuser1;
|
||||
Services.logins.addLogin(testuser1);
|
||||
LoginTestUtils.checkLogins([testuser1]);
|
||||
Assert.equal(expectedNotification, null); // check that observer got a notification
|
||||
expectedNotification = "addLogin";
|
||||
expectedData = testuser1;
|
||||
Services.logins.addLogin(testuser1);
|
||||
LoginTestUtils.checkLogins([testuser1]);
|
||||
Assert.equal(expectedNotification, null); // check that observer got a notification
|
||||
|
||||
/* ========== 3 ========== */
|
||||
testnum++;
|
||||
testdesc = "modifyLogin";
|
||||
/* ========== 3 ========== */
|
||||
testnum++;
|
||||
testdesc = "modifyLogin";
|
||||
|
||||
expectedNotification = "modifyLogin";
|
||||
expectedData = [testuser1, testuser2];
|
||||
Services.logins.modifyLogin(testuser1, testuser2);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([testuser2]);
|
||||
expectedNotification = "modifyLogin";
|
||||
expectedData = [testuser1, testuser2];
|
||||
Services.logins.modifyLogin(testuser1, testuser2);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([testuser2]);
|
||||
|
||||
/* ========== 4 ========== */
|
||||
testnum++;
|
||||
testdesc = "removeLogin";
|
||||
/* ========== 4 ========== */
|
||||
testnum++;
|
||||
testdesc = "removeLogin";
|
||||
|
||||
expectedNotification = "removeLogin";
|
||||
expectedData = testuser2;
|
||||
Services.logins.removeLogin(testuser2);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([]);
|
||||
expectedNotification = "removeLogin";
|
||||
expectedData = testuser2;
|
||||
Services.logins.removeLogin(testuser2);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([]);
|
||||
|
||||
/* ========== 5 ========== */
|
||||
testnum++;
|
||||
testdesc = "removeAllLogins";
|
||||
/* ========== 5 ========== */
|
||||
testnum++;
|
||||
testdesc = "removeAllLogins";
|
||||
|
||||
expectedNotification = "removeAllLogins";
|
||||
expectedData = null;
|
||||
Services.logins.removeAllLogins();
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([]);
|
||||
expectedNotification = "removeAllLogins";
|
||||
expectedData = null;
|
||||
Services.logins.removeAllLogins();
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([]);
|
||||
|
||||
/* ========== 6 ========== */
|
||||
testnum++;
|
||||
testdesc = "removeAllLogins (again)";
|
||||
/* ========== 6 ========== */
|
||||
testnum++;
|
||||
testdesc = "removeAllLogins (again)";
|
||||
|
||||
expectedNotification = "removeAllLogins";
|
||||
expectedData = null;
|
||||
Services.logins.removeAllLogins();
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([]);
|
||||
expectedNotification = "removeAllLogins";
|
||||
expectedData = null;
|
||||
Services.logins.removeAllLogins();
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([]);
|
||||
|
||||
/* ========== 7 ========== */
|
||||
testnum++;
|
||||
testdesc = "setLoginSavingEnabled / false";
|
||||
/* ========== 7 ========== */
|
||||
testnum++;
|
||||
testdesc = "setLoginSavingEnabled / false";
|
||||
|
||||
expectedNotification = "hostSavingDisabled";
|
||||
expectedData = "http://site.com";
|
||||
Services.logins.setLoginSavingEnabled("http://site.com", false);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(),
|
||||
["http://site.com"]);
|
||||
expectedNotification = "hostSavingDisabled";
|
||||
expectedData = "http://site.com";
|
||||
Services.logins.setLoginSavingEnabled("http://site.com", false);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(),
|
||||
["http://site.com"]);
|
||||
|
||||
/* ========== 8 ========== */
|
||||
testnum++;
|
||||
testdesc = "setLoginSavingEnabled / false (again)";
|
||||
/* ========== 8 ========== */
|
||||
testnum++;
|
||||
testdesc = "setLoginSavingEnabled / false (again)";
|
||||
|
||||
expectedNotification = "hostSavingDisabled";
|
||||
expectedData = "http://site.com";
|
||||
Services.logins.setLoginSavingEnabled("http://site.com", false);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(),
|
||||
["http://site.com"]);
|
||||
expectedNotification = "hostSavingDisabled";
|
||||
expectedData = "http://site.com";
|
||||
Services.logins.setLoginSavingEnabled("http://site.com", false);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(),
|
||||
["http://site.com"]);
|
||||
|
||||
/* ========== 9 ========== */
|
||||
testnum++;
|
||||
testdesc = "setLoginSavingEnabled / true";
|
||||
/* ========== 9 ========== */
|
||||
testnum++;
|
||||
testdesc = "setLoginSavingEnabled / true";
|
||||
|
||||
expectedNotification = "hostSavingEnabled";
|
||||
expectedData = "http://site.com";
|
||||
Services.logins.setLoginSavingEnabled("http://site.com", true);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([]);
|
||||
expectedNotification = "hostSavingEnabled";
|
||||
expectedData = "http://site.com";
|
||||
Services.logins.setLoginSavingEnabled("http://site.com", true);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([]);
|
||||
|
||||
/* ========== 10 ========== */
|
||||
testnum++;
|
||||
testdesc = "setLoginSavingEnabled / true (again)";
|
||||
/* ========== 10 ========== */
|
||||
testnum++;
|
||||
testdesc = "setLoginSavingEnabled / true (again)";
|
||||
|
||||
expectedNotification = "hostSavingEnabled";
|
||||
expectedData = "http://site.com";
|
||||
Services.logins.setLoginSavingEnabled("http://site.com", true);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([]);
|
||||
expectedNotification = "hostSavingEnabled";
|
||||
expectedData = "http://site.com";
|
||||
Services.logins.setLoginSavingEnabled("http://site.com", true);
|
||||
Assert.equal(expectedNotification, null);
|
||||
LoginTestUtils.checkLogins([]);
|
||||
|
||||
Services.obs.removeObserver(TestObserver, "passwordmgr-storage-changed");
|
||||
Services.obs.removeObserver(TestObserver, "passwordmgr-storage-changed");
|
||||
|
||||
LoginTestUtils.clearData();
|
||||
LoginTestUtils.clearData();
|
||||
|
||||
} catch (e) {
|
||||
} catch (e) {
|
||||
throw new Error("FAILED in test #" + testnum + " -- " + testdesc + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -44,10 +44,9 @@ function reloadStorage(aInputPathName, aInputFileName)
|
|||
{
|
||||
var inputFile = null;
|
||||
if (aInputFileName) {
|
||||
inputFile = Cc["@mozilla.org/file/local;1"].
|
||||
createInstance(Ci.nsIFile);
|
||||
inputFile.initWithPath(aInputPathName);
|
||||
inputFile.append(aInputFileName);
|
||||
inputFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
inputFile.initWithPath(aInputPathName);
|
||||
inputFile.append(aInputFileName);
|
||||
}
|
||||
|
||||
let storage = Cc["@mozilla.org/login-manager/storage/mozStorage;1"]
|
||||
|
@ -90,415 +89,415 @@ function setLoginSavingEnabled(origin, enabled) {
|
|||
add_task(async function test_execute()
|
||||
{
|
||||
|
||||
const OUTDIR = OS.Constants.Path.profileDir;
|
||||
const OUTDIR = OS.Constants.Path.profileDir;
|
||||
|
||||
try {
|
||||
try {
|
||||
|
||||
var isGUID = /^\{[0-9a-f\d]{8}-[0-9a-f\d]{4}-[0-9a-f\d]{4}-[0-9a-f\d]{4}-[0-9a-f\d]{12}\}$/;
|
||||
function getGUIDforID(conn, id) {
|
||||
var stmt = conn.createStatement("SELECT guid from moz_logins WHERE id = " + id);
|
||||
stmt.executeStep();
|
||||
var guid = stmt.getString(0);
|
||||
stmt.finalize();
|
||||
return guid;
|
||||
}
|
||||
|
||||
function getEncTypeForID(conn, id) {
|
||||
var stmt = conn.createStatement("SELECT encType from moz_logins WHERE id = " + id);
|
||||
stmt.executeStep();
|
||||
var encType = stmt.row.encType;
|
||||
stmt.finalize();
|
||||
return encType;
|
||||
}
|
||||
|
||||
function getAllDisabledHostsFromMozStorage(conn) {
|
||||
let disabledHosts = [];
|
||||
let stmt = conn.createStatement("SELECT hostname from moz_disabledHosts");
|
||||
|
||||
while (stmt.executeStep()) {
|
||||
disabledHosts.push(stmt.row.hostname);
|
||||
var isGUID = /^\{[0-9a-f\d]{8}-[0-9a-f\d]{4}-[0-9a-f\d]{4}-[0-9a-f\d]{4}-[0-9a-f\d]{12}\}$/;
|
||||
function getGUIDforID(conn, id) {
|
||||
var stmt = conn.createStatement("SELECT guid from moz_logins WHERE id = " + id);
|
||||
stmt.executeStep();
|
||||
var guid = stmt.getString(0);
|
||||
stmt.finalize();
|
||||
return guid;
|
||||
}
|
||||
|
||||
return disabledHosts;
|
||||
}
|
||||
|
||||
var storage;
|
||||
var dbConnection;
|
||||
var testnum = 0;
|
||||
var testdesc = "Setup of nsLoginInfo test-users";
|
||||
var nsLoginInfo = new Components.Constructor(
|
||||
"@mozilla.org/login-manager/loginInfo;1",
|
||||
Ci.nsILoginInfo);
|
||||
Assert.ok(nsLoginInfo != null);
|
||||
|
||||
var testuser1 = new nsLoginInfo;
|
||||
testuser1.init("http://test.com", "http://test.com", null,
|
||||
"testuser1", "testpass1", "u1", "p1");
|
||||
var testuser1B = new nsLoginInfo;
|
||||
testuser1B.init("http://test.com", "http://test.com", null,
|
||||
"testuser1B", "testpass1B", "u1", "p1");
|
||||
var testuser2 = new nsLoginInfo;
|
||||
testuser2.init("http://test.org", "http://test.org", null,
|
||||
"testuser2", "testpass2", "u2", "p2");
|
||||
var testuser3 = new nsLoginInfo;
|
||||
testuser3.init("http://test.gov", "http://test.gov", null,
|
||||
"testuser3", "testpass3", "u3", "p3");
|
||||
var testuser4 = new nsLoginInfo;
|
||||
testuser4.init("http://test.gov", "http://test.gov", null,
|
||||
"testuser1", "testpass2", "u4", "p4");
|
||||
var testuser5 = new nsLoginInfo;
|
||||
testuser5.init("http://test.gov", "http://test.gov", null,
|
||||
"testuser2", "testpass1", "u5", "p5");
|
||||
|
||||
|
||||
/* ========== 1 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test downgrade from v999 storage";
|
||||
|
||||
await copyFile("signons-v999.sqlite");
|
||||
// Verify the schema version in the test file.
|
||||
dbConnection = openDB("signons-v999.sqlite");
|
||||
Assert.equal(999, dbConnection.schemaVersion);
|
||||
dbConnection.close();
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v999.sqlite");
|
||||
setLoginSavingEnabled("https://disabled.net", false);
|
||||
checkStorageData(storage, ["https://disabled.net"], [testuser1]);
|
||||
|
||||
// Check to make sure we downgraded the schema version.
|
||||
dbConnection = openDB("signons-v999.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
dbConnection.close();
|
||||
|
||||
deleteFile(OUTDIR, "signons-v999.sqlite");
|
||||
|
||||
/* ========== 2 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test downgrade from incompat v999 storage";
|
||||
// This file has a testuser999/testpass999, but is missing an expected column
|
||||
|
||||
var origFile = OS.Path.join(OUTDIR, "signons-v999-2.sqlite");
|
||||
var failFile = OS.Path.join(OUTDIR, "signons-v999-2.sqlite.corrupt");
|
||||
|
||||
// Make sure we always start clean in a clean state.
|
||||
await copyFile("signons-v999-2.sqlite");
|
||||
await OS.File.remove(failFile);
|
||||
|
||||
Assert.throws(() => reloadStorage(OUTDIR, "signons-v999-2.sqlite"),
|
||||
/Initialization failed/);
|
||||
|
||||
// Check to ensure the DB file was renamed to .corrupt.
|
||||
Assert.equal(false, await OS.File.exists(origFile));
|
||||
Assert.ok(await OS.File.exists(failFile));
|
||||
|
||||
await OS.File.remove(failFile);
|
||||
|
||||
/* ========== 3 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v1->v2 storage";
|
||||
|
||||
await copyFile("signons-v1.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v1.sqlite");
|
||||
Assert.equal(1, dbConnection.schemaVersion);
|
||||
dbConnection.close();
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v1.sqlite");
|
||||
checkStorageData(storage, ["https://disabled.net"], [testuser1, testuser2]);
|
||||
|
||||
// Check to see that we added a GUIDs to the logins.
|
||||
dbConnection = openDB("signons-v1.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
var guid = getGUIDforID(dbConnection, 1);
|
||||
Assert.ok(isGUID.test(guid));
|
||||
guid = getGUIDforID(dbConnection, 2);
|
||||
Assert.ok(isGUID.test(guid));
|
||||
dbConnection.close();
|
||||
|
||||
deleteFile(OUTDIR, "signons-v1.sqlite");
|
||||
|
||||
/* ========== 4 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade v2->v1 storage";
|
||||
// This is the case where a v2 DB has been accessed with v1 code, and now we
|
||||
// are upgrading it again. Any logins added by the v1 code must be properly
|
||||
// upgraded.
|
||||
|
||||
await copyFile("signons-v1v2.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v1v2.sqlite");
|
||||
Assert.equal(1, dbConnection.schemaVersion);
|
||||
dbConnection.close();
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v1v2.sqlite");
|
||||
checkStorageData(storage, ["https://disabled.net"], [testuser1, testuser2, testuser3]);
|
||||
|
||||
// While we're here, try modifying a login, to ensure that doing so doesn't
|
||||
// change the existing GUID.
|
||||
storage.modifyLogin(testuser1, testuser1B);
|
||||
checkStorageData(storage, ["https://disabled.net"], [testuser1B, testuser2, testuser3]);
|
||||
|
||||
// Check the GUIDs. Logins 1 and 2 should retain their original GUID, login 3
|
||||
// should have one created (because it didn't have one previously).
|
||||
dbConnection = openDB("signons-v1v2.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
guid = getGUIDforID(dbConnection, 1);
|
||||
Assert.equal("{655c7358-f1d6-6446-adab-53f98ac5d80f}", guid);
|
||||
guid = getGUIDforID(dbConnection, 2);
|
||||
Assert.equal("{13d9bfdc-572a-4d4e-9436-68e9803e84c1}", guid);
|
||||
guid = getGUIDforID(dbConnection, 3);
|
||||
Assert.ok(isGUID.test(guid));
|
||||
dbConnection.close();
|
||||
|
||||
deleteFile(OUTDIR, "signons-v1v2.sqlite");
|
||||
|
||||
/* ========== 5 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v2->v3 storage";
|
||||
|
||||
await copyFile("signons-v2.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v2.sqlite");
|
||||
Assert.equal(2, dbConnection.schemaVersion);
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v2.sqlite");
|
||||
|
||||
// Check to see that we added the correct encType to the logins.
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
var encTypes = [ENCTYPE_BASE64, ENCTYPE_SDR, ENCTYPE_BASE64, ENCTYPE_BASE64];
|
||||
for (let i = 0; i < encTypes.length; i++)
|
||||
Assert.equal(encTypes[i], getEncTypeForID(dbConnection, i + 1));
|
||||
dbConnection.close();
|
||||
|
||||
// There are 4 logins, but 3 will be invalid because we can no longer decrypt
|
||||
// base64-encoded items. (testuser1/4/5)
|
||||
checkStorageData(storage, ["https://disabled.net"],
|
||||
[testuser2]);
|
||||
|
||||
deleteFile(OUTDIR, "signons-v2.sqlite");
|
||||
|
||||
/* ========== 6 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade v3->v2 storage";
|
||||
// This is the case where a v3 DB has been accessed with v2 code, and now we
|
||||
// are upgrading it again. Any logins added by the v2 code must be properly
|
||||
// upgraded.
|
||||
|
||||
await copyFile("signons-v2v3.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v2v3.sqlite");
|
||||
Assert.equal(2, dbConnection.schemaVersion);
|
||||
encTypes = [ENCTYPE_BASE64, ENCTYPE_SDR, ENCTYPE_BASE64, ENCTYPE_BASE64, null];
|
||||
for (let i = 0; i < encTypes.length; i++)
|
||||
Assert.equal(encTypes[i], getEncTypeForID(dbConnection, i + 1));
|
||||
|
||||
// Reload storage, check that the new login now has encType=1, others untouched
|
||||
storage = reloadStorage(OUTDIR, "signons-v2v3.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
|
||||
encTypes = [ENCTYPE_BASE64, ENCTYPE_SDR, ENCTYPE_BASE64, ENCTYPE_BASE64, ENCTYPE_SDR];
|
||||
for (let i = 0; i < encTypes.length; i++)
|
||||
Assert.equal(encTypes[i], getEncTypeForID(dbConnection, i + 1));
|
||||
|
||||
// Sanity check that the data gets migrated
|
||||
// There are 5 logins, but 3 will be invalid because we can no longer decrypt
|
||||
// base64-encoded items. (testuser1/4/5). We no longer reencrypt with SDR.
|
||||
checkStorageData(storage, ["https://disabled.net"], [testuser2, testuser3]);
|
||||
encTypes = [ENCTYPE_BASE64, ENCTYPE_SDR, ENCTYPE_BASE64, ENCTYPE_BASE64, ENCTYPE_SDR];
|
||||
for (let i = 0; i < encTypes.length; i++)
|
||||
Assert.equal(encTypes[i], getEncTypeForID(dbConnection, i + 1));
|
||||
dbConnection.close();
|
||||
|
||||
deleteFile(OUTDIR, "signons-v2v3.sqlite");
|
||||
|
||||
|
||||
/* ========== 7 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v3->v4 storage";
|
||||
|
||||
await copyFile("signons-v3.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v3.sqlite");
|
||||
Assert.equal(3, dbConnection.schemaVersion);
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v3.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
|
||||
// Remove old entry from permission manager.
|
||||
setLoginSavingEnabled("https://disabled.net", true);
|
||||
|
||||
// Check that timestamps and counts were initialized correctly
|
||||
checkStorageData(storage, [], [testuser1, testuser2]);
|
||||
|
||||
var logins = storage.getAllLogins();
|
||||
for (var i = 0; i < 2; i++) {
|
||||
Assert.ok(logins[i] instanceof Ci.nsILoginMetaInfo);
|
||||
Assert.equal(1, logins[i].timesUsed);
|
||||
LoginTestUtils.assertTimeIsAboutNow(logins[i].timeCreated);
|
||||
LoginTestUtils.assertTimeIsAboutNow(logins[i].timeLastUsed);
|
||||
LoginTestUtils.assertTimeIsAboutNow(logins[i].timePasswordChanged);
|
||||
}
|
||||
|
||||
/* ========== 8 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v3->v4->v3 storage";
|
||||
|
||||
await copyFile("signons-v3v4.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v3v4.sqlite");
|
||||
Assert.equal(3, dbConnection.schemaVersion);
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v3v4.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
|
||||
// testuser1 already has timestamps, testuser2 does not.
|
||||
checkStorageData(storage, [], [testuser1, testuser2]);
|
||||
|
||||
logins = storage.getAllLogins();
|
||||
|
||||
var t1, t2;
|
||||
if (logins[0].username == "testuser1") {
|
||||
t1 = logins[0];
|
||||
t2 = logins[1];
|
||||
} else {
|
||||
t1 = logins[1];
|
||||
t2 = logins[0];
|
||||
}
|
||||
|
||||
Assert.ok(t1 instanceof Ci.nsILoginMetaInfo);
|
||||
Assert.ok(t2 instanceof Ci.nsILoginMetaInfo);
|
||||
|
||||
Assert.equal(9, t1.timesUsed);
|
||||
Assert.equal(1262049951275, t1.timeCreated);
|
||||
Assert.equal(1262049951275, t1.timeLastUsed);
|
||||
Assert.equal(1262049951275, t1.timePasswordChanged);
|
||||
|
||||
Assert.equal(1, t2.timesUsed);
|
||||
LoginTestUtils.assertTimeIsAboutNow(t2.timeCreated);
|
||||
LoginTestUtils.assertTimeIsAboutNow(t2.timeLastUsed);
|
||||
LoginTestUtils.assertTimeIsAboutNow(t2.timePasswordChanged);
|
||||
|
||||
|
||||
/* ========== 9 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v4 storage";
|
||||
function getEncTypeForID(conn, id) {
|
||||
var stmt = conn.createStatement("SELECT encType from moz_logins WHERE id = " + id);
|
||||
stmt.executeStep();
|
||||
var encType = stmt.row.encType;
|
||||
stmt.finalize();
|
||||
return encType;
|
||||
}
|
||||
|
||||
function getAllDisabledHostsFromMozStorage(conn) {
|
||||
let disabledHosts = [];
|
||||
let stmt = conn.createStatement("SELECT hostname from moz_disabledHosts");
|
||||
|
||||
while (stmt.executeStep()) {
|
||||
disabledHosts.push(stmt.row.hostname);
|
||||
}
|
||||
|
||||
return disabledHosts;
|
||||
}
|
||||
|
||||
var storage;
|
||||
var dbConnection;
|
||||
var testnum = 0;
|
||||
var testdesc = "Setup of nsLoginInfo test-users";
|
||||
var nsLoginInfo = new Components.Constructor(
|
||||
"@mozilla.org/login-manager/loginInfo;1",
|
||||
Ci.nsILoginInfo);
|
||||
Assert.ok(nsLoginInfo != null);
|
||||
|
||||
var testuser1 = new nsLoginInfo;
|
||||
testuser1.init("http://test.com", "http://test.com", null,
|
||||
"testuser1", "testpass1", "u1", "p1");
|
||||
var testuser1B = new nsLoginInfo;
|
||||
testuser1B.init("http://test.com", "http://test.com", null,
|
||||
"testuser1B", "testpass1B", "u1", "p1");
|
||||
var testuser2 = new nsLoginInfo;
|
||||
testuser2.init("http://test.org", "http://test.org", null,
|
||||
"testuser2", "testpass2", "u2", "p2");
|
||||
var testuser3 = new nsLoginInfo;
|
||||
testuser3.init("http://test.gov", "http://test.gov", null,
|
||||
"testuser3", "testpass3", "u3", "p3");
|
||||
var testuser4 = new nsLoginInfo;
|
||||
testuser4.init("http://test.gov", "http://test.gov", null,
|
||||
"testuser1", "testpass2", "u4", "p4");
|
||||
var testuser5 = new nsLoginInfo;
|
||||
testuser5.init("http://test.gov", "http://test.gov", null,
|
||||
"testuser2", "testpass1", "u5", "p5");
|
||||
|
||||
|
||||
/* ========== 1 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test downgrade from v999 storage";
|
||||
|
||||
await copyFile("signons-v999.sqlite");
|
||||
// Verify the schema version in the test file.
|
||||
dbConnection = openDB("signons-v999.sqlite");
|
||||
Assert.equal(999, dbConnection.schemaVersion);
|
||||
dbConnection.close();
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v999.sqlite");
|
||||
setLoginSavingEnabled("https://disabled.net", false);
|
||||
checkStorageData(storage, ["https://disabled.net"], [testuser1]);
|
||||
|
||||
// Check to make sure we downgraded the schema version.
|
||||
dbConnection = openDB("signons-v999.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
dbConnection.close();
|
||||
|
||||
deleteFile(OUTDIR, "signons-v999.sqlite");
|
||||
|
||||
/* ========== 2 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test downgrade from incompat v999 storage";
|
||||
// This file has a testuser999/testpass999, but is missing an expected column
|
||||
|
||||
var origFile = OS.Path.join(OUTDIR, "signons-v999-2.sqlite");
|
||||
var failFile = OS.Path.join(OUTDIR, "signons-v999-2.sqlite.corrupt");
|
||||
|
||||
// Make sure we always start clean in a clean state.
|
||||
await copyFile("signons-v999-2.sqlite");
|
||||
await OS.File.remove(failFile);
|
||||
|
||||
Assert.throws(() => reloadStorage(OUTDIR, "signons-v999-2.sqlite"),
|
||||
/Initialization failed/);
|
||||
|
||||
// Check to ensure the DB file was renamed to .corrupt.
|
||||
Assert.equal(false, await OS.File.exists(origFile));
|
||||
Assert.ok(await OS.File.exists(failFile));
|
||||
|
||||
await OS.File.remove(failFile);
|
||||
|
||||
/* ========== 3 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v1->v2 storage";
|
||||
|
||||
await copyFile("signons-v1.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v1.sqlite");
|
||||
Assert.equal(1, dbConnection.schemaVersion);
|
||||
dbConnection.close();
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v1.sqlite");
|
||||
checkStorageData(storage, ["https://disabled.net"], [testuser1, testuser2]);
|
||||
|
||||
// Check to see that we added a GUIDs to the logins.
|
||||
dbConnection = openDB("signons-v1.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
var guid = getGUIDforID(dbConnection, 1);
|
||||
Assert.ok(isGUID.test(guid));
|
||||
guid = getGUIDforID(dbConnection, 2);
|
||||
Assert.ok(isGUID.test(guid));
|
||||
dbConnection.close();
|
||||
|
||||
deleteFile(OUTDIR, "signons-v1.sqlite");
|
||||
|
||||
/* ========== 4 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade v2->v1 storage";
|
||||
// This is the case where a v2 DB has been accessed with v1 code, and now we
|
||||
// are upgrading it again. Any logins added by the v1 code must be properly
|
||||
// upgraded.
|
||||
|
||||
await copyFile("signons-v1v2.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v1v2.sqlite");
|
||||
Assert.equal(1, dbConnection.schemaVersion);
|
||||
dbConnection.close();
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v1v2.sqlite");
|
||||
checkStorageData(storage, ["https://disabled.net"], [testuser1, testuser2, testuser3]);
|
||||
|
||||
// While we're here, try modifying a login, to ensure that doing so doesn't
|
||||
// change the existing GUID.
|
||||
storage.modifyLogin(testuser1, testuser1B);
|
||||
checkStorageData(storage, ["https://disabled.net"], [testuser1B, testuser2, testuser3]);
|
||||
|
||||
// Check the GUIDs. Logins 1 and 2 should retain their original GUID, login 3
|
||||
// should have one created (because it didn't have one previously).
|
||||
dbConnection = openDB("signons-v1v2.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
guid = getGUIDforID(dbConnection, 1);
|
||||
Assert.equal("{655c7358-f1d6-6446-adab-53f98ac5d80f}", guid);
|
||||
guid = getGUIDforID(dbConnection, 2);
|
||||
Assert.equal("{13d9bfdc-572a-4d4e-9436-68e9803e84c1}", guid);
|
||||
guid = getGUIDforID(dbConnection, 3);
|
||||
Assert.ok(isGUID.test(guid));
|
||||
dbConnection.close();
|
||||
|
||||
deleteFile(OUTDIR, "signons-v1v2.sqlite");
|
||||
|
||||
/* ========== 5 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v2->v3 storage";
|
||||
|
||||
await copyFile("signons-v2.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v2.sqlite");
|
||||
Assert.equal(2, dbConnection.schemaVersion);
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v2.sqlite");
|
||||
|
||||
// Check to see that we added the correct encType to the logins.
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
var encTypes = [ENCTYPE_BASE64, ENCTYPE_SDR, ENCTYPE_BASE64, ENCTYPE_BASE64];
|
||||
for (let i = 0; i < encTypes.length; i++)
|
||||
Assert.equal(encTypes[i], getEncTypeForID(dbConnection, i + 1));
|
||||
dbConnection.close();
|
||||
|
||||
// There are 4 logins, but 3 will be invalid because we can no longer decrypt
|
||||
// base64-encoded items. (testuser1/4/5)
|
||||
checkStorageData(storage, ["https://disabled.net"],
|
||||
[testuser2]);
|
||||
|
||||
deleteFile(OUTDIR, "signons-v2.sqlite");
|
||||
|
||||
/* ========== 6 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade v3->v2 storage";
|
||||
// This is the case where a v3 DB has been accessed with v2 code, and now we
|
||||
// are upgrading it again. Any logins added by the v2 code must be properly
|
||||
// upgraded.
|
||||
|
||||
await copyFile("signons-v2v3.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v2v3.sqlite");
|
||||
Assert.equal(2, dbConnection.schemaVersion);
|
||||
encTypes = [ENCTYPE_BASE64, ENCTYPE_SDR, ENCTYPE_BASE64, ENCTYPE_BASE64, null];
|
||||
for (let i = 0; i < encTypes.length; i++)
|
||||
Assert.equal(encTypes[i], getEncTypeForID(dbConnection, i + 1));
|
||||
|
||||
// Reload storage, check that the new login now has encType=1, others untouched
|
||||
storage = reloadStorage(OUTDIR, "signons-v2v3.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
|
||||
encTypes = [ENCTYPE_BASE64, ENCTYPE_SDR, ENCTYPE_BASE64, ENCTYPE_BASE64, ENCTYPE_SDR];
|
||||
for (let i = 0; i < encTypes.length; i++)
|
||||
Assert.equal(encTypes[i], getEncTypeForID(dbConnection, i + 1));
|
||||
|
||||
// Sanity check that the data gets migrated
|
||||
// There are 5 logins, but 3 will be invalid because we can no longer decrypt
|
||||
// base64-encoded items. (testuser1/4/5). We no longer reencrypt with SDR.
|
||||
checkStorageData(storage, ["https://disabled.net"], [testuser2, testuser3]);
|
||||
encTypes = [ENCTYPE_BASE64, ENCTYPE_SDR, ENCTYPE_BASE64, ENCTYPE_BASE64, ENCTYPE_SDR];
|
||||
for (let i = 0; i < encTypes.length; i++)
|
||||
Assert.equal(encTypes[i], getEncTypeForID(dbConnection, i + 1));
|
||||
dbConnection.close();
|
||||
|
||||
deleteFile(OUTDIR, "signons-v2v3.sqlite");
|
||||
|
||||
|
||||
/* ========== 7 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v3->v4 storage";
|
||||
|
||||
await copyFile("signons-v3.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v3.sqlite");
|
||||
Assert.equal(3, dbConnection.schemaVersion);
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v3.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
|
||||
// Remove old entry from permission manager.
|
||||
setLoginSavingEnabled("https://disabled.net", true);
|
||||
|
||||
// Check that timestamps and counts were initialized correctly
|
||||
checkStorageData(storage, [], [testuser1, testuser2]);
|
||||
|
||||
var logins = storage.getAllLogins();
|
||||
for (var i = 0; i < 2; i++) {
|
||||
Assert.ok(logins[i] instanceof Ci.nsILoginMetaInfo);
|
||||
Assert.equal(1, logins[i].timesUsed);
|
||||
LoginTestUtils.assertTimeIsAboutNow(logins[i].timeCreated);
|
||||
LoginTestUtils.assertTimeIsAboutNow(logins[i].timeLastUsed);
|
||||
LoginTestUtils.assertTimeIsAboutNow(logins[i].timePasswordChanged);
|
||||
}
|
||||
|
||||
/* ========== 8 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v3->v4->v3 storage";
|
||||
|
||||
await copyFile("signons-v3v4.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v3v4.sqlite");
|
||||
Assert.equal(3, dbConnection.schemaVersion);
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v3v4.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
|
||||
// testuser1 already has timestamps, testuser2 does not.
|
||||
checkStorageData(storage, [], [testuser1, testuser2]);
|
||||
|
||||
logins = storage.getAllLogins();
|
||||
|
||||
var t1, t2;
|
||||
if (logins[0].username == "testuser1") {
|
||||
t1 = logins[0];
|
||||
t2 = logins[1];
|
||||
} else {
|
||||
t1 = logins[1];
|
||||
t2 = logins[0];
|
||||
}
|
||||
|
||||
Assert.ok(t1 instanceof Ci.nsILoginMetaInfo);
|
||||
Assert.ok(t2 instanceof Ci.nsILoginMetaInfo);
|
||||
|
||||
Assert.equal(9, t1.timesUsed);
|
||||
Assert.equal(1262049951275, t1.timeCreated);
|
||||
Assert.equal(1262049951275, t1.timeLastUsed);
|
||||
Assert.equal(1262049951275, t1.timePasswordChanged);
|
||||
|
||||
Assert.equal(1, t2.timesUsed);
|
||||
LoginTestUtils.assertTimeIsAboutNow(t2.timeCreated);
|
||||
LoginTestUtils.assertTimeIsAboutNow(t2.timeLastUsed);
|
||||
LoginTestUtils.assertTimeIsAboutNow(t2.timePasswordChanged);
|
||||
|
||||
|
||||
/* ========== 9 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v4 storage";
|
||||
|
||||
await copyFile("signons-v4.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v4.sqlite");
|
||||
Assert.equal(4, dbConnection.schemaVersion);
|
||||
Assert.ok(!dbConnection.tableExists("moz_deleted_logins"));
|
||||
await copyFile("signons-v4.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v4.sqlite");
|
||||
Assert.equal(4, dbConnection.schemaVersion);
|
||||
Assert.ok(!dbConnection.tableExists("moz_deleted_logins"));
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v4.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
Assert.ok(dbConnection.tableExists("moz_deleted_logins"));
|
||||
storage = reloadStorage(OUTDIR, "signons-v4.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
Assert.ok(dbConnection.tableExists("moz_deleted_logins"));
|
||||
|
||||
|
||||
/* ========== 10 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v4->v5->v4 storage";
|
||||
/* ========== 10 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v4->v5->v4 storage";
|
||||
|
||||
await copyFile("signons-v4v5.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v4v5.sqlite");
|
||||
Assert.equal(4, dbConnection.schemaVersion);
|
||||
Assert.ok(dbConnection.tableExists("moz_deleted_logins"));
|
||||
await copyFile("signons-v4v5.sqlite");
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v4v5.sqlite");
|
||||
Assert.equal(4, dbConnection.schemaVersion);
|
||||
Assert.ok(dbConnection.tableExists("moz_deleted_logins"));
|
||||
|
||||
storage = reloadStorage(OUTDIR, "signons-v4v5.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
Assert.ok(dbConnection.tableExists("moz_deleted_logins"));
|
||||
storage = reloadStorage(OUTDIR, "signons-v4v5.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
Assert.ok(dbConnection.tableExists("moz_deleted_logins"));
|
||||
|
||||
/* ========== 11 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v5->v6 storage";
|
||||
/* ========== 11 ========== */
|
||||
testnum++;
|
||||
testdesc = "Test upgrade from v5->v6 storage";
|
||||
|
||||
await copyFile("signons-v5v6.sqlite");
|
||||
await copyFile("signons-v5v6.sqlite");
|
||||
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v5v6.sqlite");
|
||||
Assert.equal(5, dbConnection.schemaVersion);
|
||||
Assert.ok(dbConnection.tableExists("moz_disabledHosts"));
|
||||
// Sanity check the test file.
|
||||
dbConnection = openDB("signons-v5v6.sqlite");
|
||||
Assert.equal(5, dbConnection.schemaVersion);
|
||||
Assert.ok(dbConnection.tableExists("moz_disabledHosts"));
|
||||
|
||||
// Initial disabled hosts inside signons-v5v6.sqlite
|
||||
var disabledHosts = [
|
||||
"http://disabled1.example.com",
|
||||
"http://大.net",
|
||||
"http://xn--19g.com",
|
||||
];
|
||||
// Initial disabled hosts inside signons-v5v6.sqlite
|
||||
var disabledHosts = [
|
||||
"http://disabled1.example.com",
|
||||
"http://大.net",
|
||||
"http://xn--19g.com",
|
||||
];
|
||||
|
||||
LoginTestUtils.assertDisabledHostsEqual(disabledHosts, getAllDisabledHostsFromMozStorage(dbConnection));
|
||||
LoginTestUtils.assertDisabledHostsEqual(disabledHosts, getAllDisabledHostsFromMozStorage(dbConnection));
|
||||
|
||||
// Reload storage
|
||||
storage = reloadStorage(OUTDIR, "signons-v5v6.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
// Reload storage
|
||||
storage = reloadStorage(OUTDIR, "signons-v5v6.sqlite");
|
||||
Assert.equal(CURRENT_SCHEMA, dbConnection.schemaVersion);
|
||||
|
||||
// moz_disabledHosts should now be empty after migration.
|
||||
LoginTestUtils.assertDisabledHostsEqual([], getAllDisabledHostsFromMozStorage(dbConnection));
|
||||
// moz_disabledHosts should now be empty after migration.
|
||||
LoginTestUtils.assertDisabledHostsEqual([], getAllDisabledHostsFromMozStorage(dbConnection));
|
||||
|
||||
// Get all the other hosts currently saved in the permission manager.
|
||||
let hostsInPermissionManager = getAllDisabledHostsFromPermissionManager();
|
||||
// Get all the other hosts currently saved in the permission manager.
|
||||
let hostsInPermissionManager = getAllDisabledHostsFromPermissionManager();
|
||||
|
||||
// All disabledHosts should have migrated to the permission manager
|
||||
LoginTestUtils.assertDisabledHostsEqual(disabledHosts, hostsInPermissionManager);
|
||||
// All disabledHosts should have migrated to the permission manager
|
||||
LoginTestUtils.assertDisabledHostsEqual(disabledHosts, hostsInPermissionManager);
|
||||
|
||||
// Remove all disabled hosts from the permission manager before test ends
|
||||
for (let host of disabledHosts) {
|
||||
setLoginSavingEnabled(host, true);
|
||||
}
|
||||
// Remove all disabled hosts from the permission manager before test ends
|
||||
for (let host of disabledHosts) {
|
||||
setLoginSavingEnabled(host, true);
|
||||
}
|
||||
|
||||
/* ========== 12 ========== */
|
||||
testnum++;
|
||||
testdesc = "Create nsILoginInfo instances for testing with";
|
||||
/* ========== 12 ========== */
|
||||
testnum++;
|
||||
testdesc = "Create nsILoginInfo instances for testing with";
|
||||
|
||||
testuser1 = new nsLoginInfo;
|
||||
testuser1.init("http://dummyhost.mozilla.org", "", null,
|
||||
"dummydude", "itsasecret", "put_user_here", "put_pw_here");
|
||||
testuser1 = new nsLoginInfo;
|
||||
testuser1.init("http://dummyhost.mozilla.org", "", null,
|
||||
"dummydude", "itsasecret", "put_user_here", "put_pw_here");
|
||||
|
||||
|
||||
/*
|
||||
* ---------------------- DB Corruption ----------------------
|
||||
* Try to initialize with a corrupt database file. This should create a backup
|
||||
* file, then upon next use create a new database file.
|
||||
*/
|
||||
/*
|
||||
* ---------------------- DB Corruption ----------------------
|
||||
* Try to initialize with a corrupt database file. This should create a backup
|
||||
* file, then upon next use create a new database file.
|
||||
*/
|
||||
|
||||
/* ========== 13 ========== */
|
||||
testnum++;
|
||||
testdesc = "Corrupt database and backup";
|
||||
/* ========== 13 ========== */
|
||||
testnum++;
|
||||
testdesc = "Corrupt database and backup";
|
||||
|
||||
const filename = "signons-c.sqlite";
|
||||
const filepath = OS.Path.join(OS.Constants.Path.profileDir, filename);
|
||||
const filename = "signons-c.sqlite";
|
||||
const filepath = OS.Path.join(OS.Constants.Path.profileDir, filename);
|
||||
|
||||
await OS.File.copy(do_get_file("data/corruptDB.sqlite").path, filepath);
|
||||
await OS.File.copy(do_get_file("data/corruptDB.sqlite").path, filepath);
|
||||
|
||||
// will init mozStorage module with corrupt database, init should fail
|
||||
Assert.throws(
|
||||
() => reloadStorage(OS.Constants.Path.profileDir, filename),
|
||||
/Initialization failed/);
|
||||
// will init mozStorage module with corrupt database, init should fail
|
||||
Assert.throws(
|
||||
() => reloadStorage(OS.Constants.Path.profileDir, filename),
|
||||
/Initialization failed/);
|
||||
|
||||
// check that the backup file exists
|
||||
Assert.ok(await OS.File.exists(filepath + ".corrupt"));
|
||||
// check that the backup file exists
|
||||
Assert.ok(await OS.File.exists(filepath + ".corrupt"));
|
||||
|
||||
// check that the original corrupt file has been deleted
|
||||
Assert.equal(false, await OS.File.exists(filepath));
|
||||
// check that the original corrupt file has been deleted
|
||||
Assert.equal(false, await OS.File.exists(filepath));
|
||||
|
||||
// initialize the storage module again
|
||||
storage = reloadStorage(OS.Constants.Path.profileDir, filename);
|
||||
// initialize the storage module again
|
||||
storage = reloadStorage(OS.Constants.Path.profileDir, filename);
|
||||
|
||||
// use the storage module again, should work now
|
||||
storage.addLogin(testuser1);
|
||||
checkStorageData(storage, [], [testuser1]);
|
||||
// use the storage module again, should work now
|
||||
storage.addLogin(testuser1);
|
||||
checkStorageData(storage, [], [testuser1]);
|
||||
|
||||
// check the file exists
|
||||
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
file.initWithPath(OS.Constants.Path.profileDir);
|
||||
file.append(filename);
|
||||
Assert.ok(file.exists());
|
||||
// check the file exists
|
||||
var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
|
||||
file.initWithPath(OS.Constants.Path.profileDir);
|
||||
file.append(filename);
|
||||
Assert.ok(file.exists());
|
||||
|
||||
deleteFile(OS.Constants.Path.profileDir, filename + ".corrupt");
|
||||
deleteFile(OS.Constants.Path.profileDir, filename);
|
||||
deleteFile(OS.Constants.Path.profileDir, filename + ".corrupt");
|
||||
deleteFile(OS.Constants.Path.profileDir, filename);
|
||||
|
||||
} catch (e) {
|
||||
} catch (e) {
|
||||
throw new Error("FAILED in test #" + testnum + " -- " + testdesc + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -25,7 +25,7 @@ matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomple
|
|||
|
||||
let meta = matchingLogins[0].QueryInterface(Ci.nsILoginMetaInfo);
|
||||
let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined,
|
||||
{ dateStyle: "medium" });
|
||||
{ dateStyle: "medium" });
|
||||
let time = dateAndTimeFormatter.format(new Date(meta.timePasswordChanged));
|
||||
const LABEL_NO_USERNAME = "No username (" + time + ")";
|
||||
|
||||
|
@ -476,13 +476,13 @@ add_task(async function test_all_patterns() {
|
|||
|
||||
if (pattern.items.length != 0) {
|
||||
Assert.throws(() => actual.getValueAt(pattern.items.length),
|
||||
/Index out of range\./);
|
||||
/Index out of range\./);
|
||||
|
||||
Assert.throws(() => actual.getLabelAt(pattern.items.length),
|
||||
/Index out of range\./);
|
||||
/Index out of range\./);
|
||||
|
||||
Assert.throws(() => actual.removeValueAt(pattern.items.length, true),
|
||||
/Index out of range\./);
|
||||
/Index out of range\./);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче