diff options
Diffstat (limited to 'toolkit/components/passwordmgr/test')
164 files changed, 0 insertions, 21185 deletions
diff --git a/toolkit/components/passwordmgr/test/.eslintrc.js b/toolkit/components/passwordmgr/test/.eslintrc.js deleted file mode 100644 index ca626f31c..000000000 --- a/toolkit/components/passwordmgr/test/.eslintrc.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; - -module.exports = { // eslint-disable-line no-undef - "extends": [ - "../../../../testing/mochitest/mochitest.eslintrc.js", - "../../../../testing/mochitest/chrome.eslintrc.js" - ], - "rules": { - "brace-style": "off", - "no-undef": "off", - "no-unused-vars": "off", - }, -}; diff --git a/toolkit/components/passwordmgr/test/LoginTestUtils.jsm b/toolkit/components/passwordmgr/test/LoginTestUtils.jsm deleted file mode 100644 index 2fd8a31a3..000000000 --- a/toolkit/components/passwordmgr/test/LoginTestUtils.jsm +++ /dev/null @@ -1,295 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/* - * Shared functions generally available for testing login components. - */ - -"use strict"; - -this.EXPORTED_SYMBOLS = [ - "LoginTestUtils", -]; - -const { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/Promise.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/Task.jsm"); -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); - -Cu.import("resource://testing-common/TestUtils.jsm"); - -const LoginInfo = - Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - "nsILoginInfo", "init"); - -// For now, we need consumers to provide a reference to Assert.jsm. -var Assert = null; - -this.LoginTestUtils = { - set Assert(assert) { - Assert = assert; // eslint-disable-line no-native-reassign - }, - - /** - * Forces the storage module to save all data, and the Login Manager service - * to replace the storage module with a newly initialized instance. - */ - * reloadData() { - Services.obs.notifyObservers(null, "passwordmgr-storage-replace", null); - yield TestUtils.topicObserved("passwordmgr-storage-replace-complete"); - }, - - /** - * Erases all the data stored by the Login Manager service. - */ - clearData() { - Services.logins.removeAllLogins(); - for (let hostname of Services.logins.getAllDisabledHosts()) { - Services.logins.setLoginSavingEnabled(hostname, true); - } - }, - - /** - * Checks that the currently stored list of nsILoginInfo matches the provided - * array. The comparison uses the "equals" method of nsILoginInfo, that does - * not include nsILoginMetaInfo properties in the test. - */ - checkLogins(expectedLogins) { - this.assertLoginListsEqual(Services.logins.getAllLogins(), expectedLogins); - }, - - /** - * Checks that the two provided arrays of nsILoginInfo have the same length, - * and every login in "expected" is also found in "actual". The comparison - * uses the "equals" method of nsILoginInfo, that does not include - * nsILoginMetaInfo properties in the test. - */ - assertLoginListsEqual(actual, expected) { - Assert.equal(expected.length, actual.length); - Assert.ok(expected.every(e => actual.some(a => a.equals(e)))); - }, - - /** - * Checks that the two provided arrays of strings contain the same values, - * maybe in a different order, case-sensitively. - */ - assertDisabledHostsEqual(actual, expected) { - Assert.deepEqual(actual.sort(), expected.sort()); - }, - - /** - * Checks whether the given time, expressed as the number of milliseconds - * since January 1, 1970, 00:00:00 UTC, falls within 30 seconds of now. - */ - assertTimeIsAboutNow(timeMs) { - Assert.ok(Math.abs(timeMs - Date.now()) < 30000); - }, -}; - -/** - * This object contains functions that return new instances of nsILoginInfo for - * every call. The returned instances can be compared using their "equals" or - * "matches" methods, or modified for the needs of the specific test being run. - * - * Any modification to the test data requires updating the tests accordingly, in - * particular the search tests. - */ -this.LoginTestUtils.testData = { - /** - * Returns a new nsILoginInfo for use with form submits. - * - * @param modifications - * Each property of this object replaces the property of the same name - * in the returned nsILoginInfo or nsILoginMetaInfo. - */ - formLogin(modifications) { - let loginInfo = new LoginInfo("http://www3.example.com", - "http://www.example.com", null, - "the username", "the password", - "form_field_username", "form_field_password"); - loginInfo.QueryInterface(Ci.nsILoginMetaInfo); - if (modifications) { - for (let [name, value] of Object.entries(modifications)) { - loginInfo[name] = value; - } - } - return loginInfo; - }, - - /** - * Returns a new nsILoginInfo for use with HTTP authentication. - * - * @param modifications - * Each property of this object replaces the property of the same name - * in the returned nsILoginInfo or nsILoginMetaInfo. - */ - authLogin(modifications) { - let loginInfo = new LoginInfo("http://www.example.org", null, - "The HTTP Realm", "the username", - "the password", "", ""); - loginInfo.QueryInterface(Ci.nsILoginMetaInfo); - if (modifications) { - for (let [name, value] of Object.entries(modifications)) { - loginInfo[name] = value; - } - } - return loginInfo; - }, - - /** - * Returns an array of typical nsILoginInfo that could be stored in the - * database. - */ - loginList() { - return [ - // --- Examples of form logins (subdomains of example.com) --- - - // Simple form login with named fields for username and password. - new LoginInfo("http://www.example.com", "http://www.example.com", null, - "the username", "the password for www.example.com", - "form_field_username", "form_field_password"), - - // Different schemes are treated as completely different sites. - new LoginInfo("https://www.example.com", "https://www.example.com", null, - "the username", "the password for https", - "form_field_username", "form_field_password"), - - // Subdomains are treated as completely different sites. - new LoginInfo("https://example.com", "https://example.com", null, - "the username", "the password for example.com", - "form_field_username", "form_field_password"), - - // Forms found on the same host, but with different hostnames in the - // "action" attribute, are handled independently. - new LoginInfo("http://www3.example.com", "http://www.example.com", null, - "the username", "the password", - "form_field_username", "form_field_password"), - new LoginInfo("http://www3.example.com", "https://www.example.com", null, - "the username", "the password", - "form_field_username", "form_field_password"), - new LoginInfo("http://www3.example.com", "http://example.com", null, - "the username", "the password", - "form_field_username", "form_field_password"), - - // It is not possible to store multiple passwords for the same username, - // however multiple passwords can be stored when the usernames differ. - // An empty username is a valid case and different from the others. - new LoginInfo("http://www4.example.com", "http://www4.example.com", null, - "username one", "password one", - "form_field_username", "form_field_password"), - new LoginInfo("http://www4.example.com", "http://www4.example.com", null, - "username two", "password two", - "form_field_username", "form_field_password"), - new LoginInfo("http://www4.example.com", "http://www4.example.com", null, - "", "password three", - "form_field_username", "form_field_password"), - - // Username and passwords fields in forms may have no "name" attribute. - new LoginInfo("http://www5.example.com", "http://www5.example.com", null, - "multi username", "multi password", "", ""), - - // Forms with PIN-type authentication will typically have no username. - new LoginInfo("http://www6.example.com", "http://www6.example.com", null, - "", "12345", "", "form_field_password"), - - // --- Examples of authentication logins (subdomains of example.org) --- - - // Simple HTTP authentication login. - new LoginInfo("http://www.example.org", null, "The HTTP Realm", - "the username", "the password", "", ""), - - // Simple FTP authentication login. - new LoginInfo("ftp://ftp.example.org", null, "ftp://ftp.example.org", - "the username", "the password", "", ""), - - // Multiple HTTP authentication logins can be stored for different realms. - new LoginInfo("http://www2.example.org", null, "The HTTP Realm", - "the username", "the password", "", ""), - new LoginInfo("http://www2.example.org", null, "The HTTP Realm Other", - "the username other", "the password other", "", ""), - - // --- Both form and authentication logins (example.net) --- - - new LoginInfo("http://example.net", "http://example.net", null, - "the username", "the password", - "form_field_username", "form_field_password"), - new LoginInfo("http://example.net", "http://www.example.net", null, - "the username", "the password", - "form_field_username", "form_field_password"), - new LoginInfo("http://example.net", "http://www.example.net", null, - "username two", "the password", - "form_field_username", "form_field_password"), - new LoginInfo("http://example.net", null, "The HTTP Realm", - "the username", "the password", "", ""), - new LoginInfo("http://example.net", null, "The HTTP Realm Other", - "username two", "the password", "", ""), - new LoginInfo("ftp://example.net", null, "ftp://example.net", - "the username", "the password", "", ""), - - // --- Examples of logins added by extensions (chrome scheme) --- - - new LoginInfo("chrome://example_extension", null, "Example Login One", - "the username", "the password one", "", ""), - new LoginInfo("chrome://example_extension", null, "Example Login Two", - "the username", "the password two", "", ""), - ]; - }, -}; - -this.LoginTestUtils.recipes = { - getRecipeParent() { - let { LoginManagerParent } = Cu.import("resource://gre/modules/LoginManagerParent.jsm", {}); - if (!LoginManagerParent.recipeParentPromise) { - return null; - } - return LoginManagerParent.recipeParentPromise.then((recipeParent) => { - return recipeParent; - }); - }, -}; - -this.LoginTestUtils.masterPassword = { - masterPassword: "omgsecret!", - - _set(enable) { - let oldPW, newPW; - if (enable) { - oldPW = ""; - newPW = this.masterPassword; - } else { - oldPW = this.masterPassword; - newPW = ""; - } - - let secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"] - .getService(Ci.nsIPKCS11ModuleDB); - let slot = secmodDB.findSlotByName(""); - if (!slot) { - throw new Error("Can't find slot"); - } - - // Set master password. Note that this does not log you in, so the next - // invocation of pwmgr can trigger a MP prompt. - let pk11db = Cc["@mozilla.org/security/pk11tokendb;1"] - .getService(Ci.nsIPK11TokenDB); - let token = pk11db.findTokenByName(""); - if (slot.status == Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED) { - dump("MP initialized to " + newPW + "\n"); - token.initPassword(newPW); - } else { - token.checkPassword(oldPW); - dump("MP change from " + oldPW + " to " + newPW + "\n"); - token.changePassword(oldPW, newPW); - } - }, - - enable() { - this._set(true); - }, - - disable() { - this._set(false); - }, -}; diff --git a/toolkit/components/passwordmgr/test/authenticate.sjs b/toolkit/components/passwordmgr/test/authenticate.sjs deleted file mode 100644 index 42edc3220..000000000 --- a/toolkit/components/passwordmgr/test/authenticate.sjs +++ /dev/null @@ -1,228 +0,0 @@ -function handleRequest(request, response) -{ - try { - reallyHandleRequest(request, response); - } catch (e) { - response.setStatusLine("1.0", 200, "AlmostOK"); - response.write("Error handling request: " + e); - } -} - - -function reallyHandleRequest(request, response) { - var match; - var requestAuth = true, requestProxyAuth = true; - - // Allow the caller to drive how authentication is processed via the query. - // Eg, http://localhost:8888/authenticate.sjs?user=foo&realm=bar - // The extra ? allows the user/pass/realm checks to succeed if the name is - // at the beginning of the query string. - var query = "?" + request.queryString; - - var expected_user = "", expected_pass = "", realm = "mochitest"; - var proxy_expected_user = "", proxy_expected_pass = "", proxy_realm = "mochi-proxy"; - var huge = false, plugin = false, anonymous = false, formauth = false; - var authHeaderCount = 1; - // user=xxx - match = /[^_]user=([^&]*)/.exec(query); - if (match) - expected_user = match[1]; - - // pass=xxx - match = /[^_]pass=([^&]*)/.exec(query); - if (match) - expected_pass = match[1]; - - // realm=xxx - match = /[^_]realm=([^&]*)/.exec(query); - if (match) - realm = match[1]; - - // proxy_user=xxx - match = /proxy_user=([^&]*)/.exec(query); - if (match) - proxy_expected_user = match[1]; - - // proxy_pass=xxx - match = /proxy_pass=([^&]*)/.exec(query); - if (match) - proxy_expected_pass = match[1]; - - // proxy_realm=xxx - match = /proxy_realm=([^&]*)/.exec(query); - if (match) - proxy_realm = match[1]; - - // huge=1 - match = /huge=1/.exec(query); - if (match) - huge = true; - - // plugin=1 - match = /plugin=1/.exec(query); - if (match) - plugin = true; - - // multiple=1 - match = /multiple=([^&]*)/.exec(query); - if (match) - authHeaderCount = match[1]+0; - - // anonymous=1 - match = /anonymous=1/.exec(query); - if (match) - anonymous = true; - - // formauth=1 - match = /formauth=1/.exec(query); - if (match) - formauth = true; - - // Look for an authentication header, if any, in the request. - // - // EG: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== - // - // This test only supports Basic auth. The value sent by the client is - // "username:password", obscured with base64 encoding. - - var actual_user = "", actual_pass = "", authHeader, authPresent = false; - if (request.hasHeader("Authorization")) { - authPresent = true; - authHeader = request.getHeader("Authorization"); - match = /Basic (.+)/.exec(authHeader); - if (match.length != 2) - throw new Error("Couldn't parse auth header: " + authHeader); - - var userpass = base64ToString(match[1]); // no atob() :-( - match = /(.*):(.*)/.exec(userpass); - if (match.length != 3) - throw new Error("Couldn't decode auth header: " + userpass); - actual_user = match[1]; - actual_pass = match[2]; - } - - var proxy_actual_user = "", proxy_actual_pass = ""; - if (request.hasHeader("Proxy-Authorization")) { - authHeader = request.getHeader("Proxy-Authorization"); - match = /Basic (.+)/.exec(authHeader); - if (match.length != 2) - throw new Error("Couldn't parse auth header: " + authHeader); - - var userpass = base64ToString(match[1]); // no atob() :-( - match = /(.*):(.*)/.exec(userpass); - if (match.length != 3) - throw new Error("Couldn't decode auth header: " + userpass); - proxy_actual_user = match[1]; - proxy_actual_pass = match[2]; - } - - // Don't request authentication if the credentials we got were what we - // expected. - if (expected_user == actual_user && - expected_pass == actual_pass) { - requestAuth = false; - } - if (proxy_expected_user == proxy_actual_user && - proxy_expected_pass == proxy_actual_pass) { - requestProxyAuth = false; - } - - if (anonymous) { - if (authPresent) { - response.setStatusLine("1.0", 400, "Unexpected authorization header found"); - } else { - response.setStatusLine("1.0", 200, "Authorization header not found"); - } - } else { - if (requestProxyAuth) { - response.setStatusLine("1.0", 407, "Proxy authentication required"); - for (i = 0; i < authHeaderCount; ++i) - response.setHeader("Proxy-Authenticate", "basic realm=\"" + proxy_realm + "\"", true); - } else if (requestAuth) { - if (formauth && authPresent) - response.setStatusLine("1.0", 403, "Form authentication required"); - else - response.setStatusLine("1.0", 401, "Authentication required"); - for (i = 0; i < authHeaderCount; ++i) - response.setHeader("WWW-Authenticate", "basic realm=\"" + realm + "\"", true); - } else { - response.setStatusLine("1.0", 200, "OK"); - } - } - - response.setHeader("Content-Type", "application/xhtml+xml", false); - response.write("<html xmlns='http://www.w3.org/1999/xhtml'>"); - response.write("<p>Login: <span id='ok'>" + (requestAuth ? "FAIL" : "PASS") + "</span></p>\n"); - response.write("<p>Proxy: <span id='proxy'>" + (requestProxyAuth ? "FAIL" : "PASS") + "</span></p>\n"); - response.write("<p>Auth: <span id='auth'>" + authHeader + "</span></p>\n"); - response.write("<p>User: <span id='user'>" + actual_user + "</span></p>\n"); - response.write("<p>Pass: <span id='pass'>" + actual_pass + "</span></p>\n"); - - if (huge) { - response.write("<div style='display: none'>"); - for (i = 0; i < 100000; i++) { - response.write("123456789\n"); - } - response.write("</div>"); - response.write("<span id='footnote'>This is a footnote after the huge content fill</span>"); - } - - if (plugin) { - response.write("<embed id='embedtest' style='width: 400px; height: 100px;' " + - "type='application/x-test'></embed>\n"); - } - - response.write("</html>"); -} - - -// base64 decoder -// -// Yoinked from extensions/xml-rpc/src/nsXmlRpcClient.js because btoa() -// doesn't seem to exist. :-( -/* Convert Base64 data to a string */ -const toBinaryTable = [ - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -]; -const base64Pad = '='; - -function base64ToString(data) { - - var result = ''; - var leftbits = 0; // number of bits decoded, but yet to be appended - var leftdata = 0; // bits decoded, but yet to be appended - - // Convert one by one. - for (var i = 0; i < data.length; i++) { - var c = toBinaryTable[data.charCodeAt(i) & 0x7f]; - var padding = (data[i] == base64Pad); - // Skip illegal characters and whitespace - if (c == -1) continue; - - // Collect data into leftdata, update bitcount - leftdata = (leftdata << 6) | c; - leftbits += 6; - - // If we have 8 or more bits, append 8 bits to the result - if (leftbits >= 8) { - leftbits -= 8; - // Append if not padding. - if (!padding) - result += String.fromCharCode((leftdata >> leftbits) & 0xff); - leftdata &= (1 << leftbits) - 1; - } - } - - // If there are any bits left, the base64 string was corrupted - if (leftbits) - throw Components.Exception('Corrupted base64 string'); - - return result; -} diff --git a/toolkit/components/passwordmgr/test/blank.html b/toolkit/components/passwordmgr/test/blank.html deleted file mode 100644 index 81ddc2235..000000000 --- a/toolkit/components/passwordmgr/test/blank.html +++ /dev/null @@ -1,8 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - </head> - <body> - </body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/.eslintrc.js b/toolkit/components/passwordmgr/test/browser/.eslintrc.js deleted file mode 100644 index 7c8021192..000000000 --- a/toolkit/components/passwordmgr/test/browser/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; - -module.exports = { - "extends": [ - "../../../../../testing/mochitest/browser.eslintrc.js" - ] -}; diff --git a/toolkit/components/passwordmgr/test/browser/authenticate.sjs b/toolkit/components/passwordmgr/test/browser/authenticate.sjs deleted file mode 100644 index fe2d2423c..000000000 --- a/toolkit/components/passwordmgr/test/browser/authenticate.sjs +++ /dev/null @@ -1,110 +0,0 @@ -function handleRequest(request, response) -{ - var match; - var requestAuth = true; - - // Allow the caller to drive how authentication is processed via the query. - // Eg, http://localhost:8888/authenticate.sjs?user=foo&realm=bar - // The extra ? allows the user/pass/realm checks to succeed if the name is - // at the beginning of the query string. - var query = "?" + request.queryString; - - var expected_user = "test", expected_pass = "testpass", realm = "mochitest"; - - // Look for an authentication header, if any, in the request. - // - // EG: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== - // - // This test only supports Basic auth. The value sent by the client is - // "username:password", obscured with base64 encoding. - - var actual_user = "", actual_pass = "", authHeader, authPresent = false; - if (request.hasHeader("Authorization")) { - authPresent = true; - authHeader = request.getHeader("Authorization"); - match = /Basic (.+)/.exec(authHeader); - if (match.length != 2) - throw new Error("Couldn't parse auth header: " + authHeader); - - var userpass = base64ToString(match[1]); // no atob() :-( - match = /(.*):(.*)/.exec(userpass); - if (match.length != 3) - throw new Error("Couldn't decode auth header: " + userpass); - actual_user = match[1]; - actual_pass = match[2]; - } - - // Don't request authentication if the credentials we got were what we - // expected. - if (expected_user == actual_user && - expected_pass == actual_pass) { - requestAuth = false; - } - - if (requestAuth) { - response.setStatusLine("1.0", 401, "Authentication required"); - response.setHeader("WWW-Authenticate", "basic realm=\"" + realm + "\"", true); - } else { - response.setStatusLine("1.0", 200, "OK"); - } - - response.setHeader("Content-Type", "application/xhtml+xml", false); - response.write("<html xmlns='http://www.w3.org/1999/xhtml'>"); - response.write("<p>Login: <span id='ok'>" + (requestAuth ? "FAIL" : "PASS") + "</span></p>\n"); - response.write("<p>Auth: <span id='auth'>" + authHeader + "</span></p>\n"); - response.write("<p>User: <span id='user'>" + actual_user + "</span></p>\n"); - response.write("<p>Pass: <span id='pass'>" + actual_pass + "</span></p>\n"); - response.write("</html>"); -} - - -// base64 decoder -// -// Yoinked from extensions/xml-rpc/src/nsXmlRpcClient.js because btoa() -// doesn't seem to exist. :-( -/* Convert Base64 data to a string */ -const toBinaryTable = [ - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -]; -const base64Pad = '='; - -function base64ToString(data) { - - var result = ''; - var leftbits = 0; // number of bits decoded, but yet to be appended - var leftdata = 0; // bits decoded, but yet to be appended - - // Convert one by one. - for (var i = 0; i < data.length; i++) { - var c = toBinaryTable[data.charCodeAt(i) & 0x7f]; - var padding = (data[i] == base64Pad); - // Skip illegal characters and whitespace - if (c == -1) continue; - - // Collect data into leftdata, update bitcount - leftdata = (leftdata << 6) | c; - leftbits += 6; - - // If we have 8 or more bits, append 8 bits to the result - if (leftbits >= 8) { - leftbits -= 8; - // Append if not padding. - if (!padding) - result += String.fromCharCode((leftdata >> leftbits) & 0xff); - leftdata &= (1 << leftbits) - 1; - } - } - - // If there are any bits left, the base64 string was corrupted - if (leftbits) - throw Components.Exception('Corrupted base64 string'); - - return result; -} diff --git a/toolkit/components/passwordmgr/test/browser/browser.ini b/toolkit/components/passwordmgr/test/browser/browser.ini deleted file mode 100644 index b17591436..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser.ini +++ /dev/null @@ -1,72 +0,0 @@ -[DEFAULT] -support-files = - ../formsubmit.sjs - authenticate.sjs - form_basic.html - form_basic_iframe.html - formless_basic.html - form_same_origin_action.html - form_cross_origin_secure_action.html - head.js - insecure_test.html - insecure_test_subframe.html - multiple_forms.html - streamConverter_content.sjs - -[browser_autocomplete_insecure_warning.js] -support-files = - form_cross_origin_insecure_action.html -[browser_capture_doorhanger.js] -support-files = - subtst_notifications_1.html - subtst_notifications_2.html - subtst_notifications_2pw_0un.html - subtst_notifications_2pw_1un_1text.html - subtst_notifications_3.html - subtst_notifications_4.html - subtst_notifications_5.html - subtst_notifications_6.html - subtst_notifications_8.html - subtst_notifications_9.html - subtst_notifications_10.html - subtst_notifications_change_p.html -[browser_capture_doorhanger_httpsUpgrade.js] -support-files = - subtst_notifications_1.html - subtst_notifications_8.html -[browser_capture_doorhanger_window_open.js] -support-files = - subtst_notifications_11.html - subtst_notifications_11_popup.html -skip-if = os == "linux" # Bug 1312981, bug 1313136 -[browser_context_menu_autocomplete_interaction.js] -[browser_username_select_dialog.js] -support-files = - subtst_notifications_change_p.html -[browser_DOMFormHasPassword.js] -[browser_DOMInputPasswordAdded.js] -[browser_exceptions_dialog.js] -[browser_formless_submit_chrome.js] -[browser_hasInsecureLoginForms.js] -[browser_hasInsecureLoginForms_streamConverter.js] -[browser_http_autofill.js] -[browser_insecurePasswordConsoleWarning.js] -support-files = - form_cross_origin_insecure_action.html -[browser_master_password_autocomplete.js] -[browser_notifications.js] -[browser_notifications_username.js] -[browser_notifications_password.js] -[browser_notifications_2.js] -skip-if = os == "linux" # Bug 1272849 Main action button disabled state intermittent -[browser_passwordmgr_editing.js] -skip-if = os == "linux" -[browser_context_menu.js] -[browser_context_menu_iframe.js] -[browser_passwordmgr_contextmenu.js] -subsuite = clipboard -[browser_passwordmgr_fields.js] -[browser_passwordmgr_observers.js] -[browser_passwordmgr_sort.js] -[browser_passwordmgr_switchtab.js] -[browser_passwordmgrdlg.js] diff --git a/toolkit/components/passwordmgr/test/browser/browser_DOMFormHasPassword.js b/toolkit/components/passwordmgr/test/browser/browser_DOMFormHasPassword.js deleted file mode 100644 index 80a0dd903..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_DOMFormHasPassword.js +++ /dev/null @@ -1,94 +0,0 @@ -const ids = { - INPUT_ID: "input1", - FORM1_ID: "form1", - FORM2_ID: "form2", - CHANGE_INPUT_ID: "input2", -}; - -function task(contentIds) { - let resolve; - let promise = new Promise(r => { resolve = r; }); - - function unexpectedContentEvent(evt) { - ok(false, "Received a " + evt.type + " event on content"); - } - - var gDoc = null; - - addEventListener("load", tabLoad, true); - - function tabLoad() { - if (content.location.href == "about:blank") - return; - removeEventListener("load", tabLoad, true); - - gDoc = content.document; - gDoc.addEventListener("DOMFormHasPassword", unexpectedContentEvent, false); - gDoc.defaultView.setTimeout(test_inputAdd, 0); - } - - function test_inputAdd() { - addEventListener("DOMFormHasPassword", test_inputAddHandler, false); - let input = gDoc.createElementNS("http://www.w3.org/1999/xhtml", "input"); - input.setAttribute("type", "password"); - input.setAttribute("id", contentIds.INPUT_ID); - input.setAttribute("data-test", "unique-attribute"); - gDoc.getElementById(contentIds.FORM1_ID).appendChild(input); - } - - function test_inputAddHandler(evt) { - removeEventListener(evt.type, test_inputAddHandler, false); - is(evt.target.id, contentIds.FORM1_ID, - evt.type + " event targets correct form element (added password element)"); - gDoc.defaultView.setTimeout(test_inputChangeForm, 0); - } - - function test_inputChangeForm() { - addEventListener("DOMFormHasPassword", test_inputChangeFormHandler, false); - let input = gDoc.getElementById(contentIds.INPUT_ID); - input.setAttribute("form", contentIds.FORM2_ID); - } - - function test_inputChangeFormHandler(evt) { - removeEventListener(evt.type, test_inputChangeFormHandler, false); - is(evt.target.id, contentIds.FORM2_ID, - evt.type + " event targets correct form element (changed form)"); - gDoc.defaultView.setTimeout(test_inputChangesType, 0); - } - - function test_inputChangesType() { - addEventListener("DOMFormHasPassword", test_inputChangesTypeHandler, false); - let input = gDoc.getElementById(contentIds.CHANGE_INPUT_ID); - input.setAttribute("type", "password"); - } - - function test_inputChangesTypeHandler(evt) { - removeEventListener(evt.type, test_inputChangesTypeHandler, false); - is(evt.target.id, contentIds.FORM1_ID, - evt.type + " event targets correct form element (changed type)"); - gDoc.defaultView.setTimeout(finish, 0); - } - - function finish() { - gDoc.removeEventListener("DOMFormHasPassword", unexpectedContentEvent, false); - resolve(); - } - - return promise; -} - -add_task(function* () { - let tab = gBrowser.selectedTab = gBrowser.addTab(); - - let promise = ContentTask.spawn(tab.linkedBrowser, ids, task); - tab.linkedBrowser.loadURI("data:text/html;charset=utf-8," + - "<html><body>" + - "<form id='" + ids.FORM1_ID + "'>" + - "<input id='" + ids.CHANGE_INPUT_ID + "'></form>" + - "<form id='" + ids.FORM2_ID + "'></form>" + - "</body></html>"); - yield promise; - - ok(true, "Test completed"); - gBrowser.removeCurrentTab(); -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_DOMInputPasswordAdded.js b/toolkit/components/passwordmgr/test/browser/browser_DOMInputPasswordAdded.js deleted file mode 100644 index f54892e19..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_DOMInputPasswordAdded.js +++ /dev/null @@ -1,99 +0,0 @@ -const consts = { - HTML_NS: "http://www.w3.org/1999/xhtml", - - INPUT_ID: "input1", - FORM1_ID: "form1", - FORM2_ID: "form2", - CHANGE_INPUT_ID: "input2", - BODY_INPUT_ID: "input3", -}; - -function task(contentConsts) { - let resolve; - let promise = new Promise(r => { resolve = r; }); - - function unexpectedContentEvent(evt) { - Assert.ok(false, "Received a " + evt.type + " event on content"); - } - - var gDoc = null; - - addEventListener("load", tabLoad, true); - - function tabLoad() { - removeEventListener("load", tabLoad, true); - gDoc = content.document; - // These events shouldn't escape to content. - gDoc.addEventListener("DOMInputPasswordAdded", unexpectedContentEvent, false); - gDoc.defaultView.setTimeout(test_inputAdd, 0); - } - - function test_inputAdd() { - addEventListener("DOMInputPasswordAdded", test_inputAddHandler, false); - let input = gDoc.createElementNS(contentConsts.HTML_NS, "input"); - input.setAttribute("type", "password"); - input.setAttribute("id", contentConsts.INPUT_ID); - input.setAttribute("data-test", "unique-attribute"); - gDoc.getElementById(contentConsts.FORM1_ID).appendChild(input); - info("Done appending the input element"); - } - - 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)"); - gDoc.defaultView.setTimeout(test_inputAddOutsideForm, 0); - } - - function test_inputAddOutsideForm() { - addEventListener("DOMInputPasswordAdded", test_inputAddOutsideFormHandler, false); - let input = gDoc.createElementNS(contentConsts.HTML_NS, "input"); - input.setAttribute("type", "password"); - input.setAttribute("id", contentConsts.BODY_INPUT_ID); - input.setAttribute("data-test", "unique-attribute"); - gDoc.body.appendChild(input); - info("Done appending the input element to the body"); - } - - 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)"); - gDoc.defaultView.setTimeout(test_inputChangesType, 0); - } - - function test_inputChangesType() { - addEventListener("DOMInputPasswordAdded", test_inputChangesTypeHandler, false); - let input = gDoc.getElementById(contentConsts.CHANGE_INPUT_ID); - input.setAttribute("type", "password"); - } - - 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)"); - gDoc.defaultView.setTimeout(completeTest, 0); - } - - function completeTest() { - Assert.ok(true, "Test completed"); - gDoc.removeEventListener("DOMInputPasswordAdded", unexpectedContentEvent, false); - resolve(); - } - - return promise; -} - -add_task(function* () { - let tab = gBrowser.selectedTab = gBrowser.addTab(); - let promise = ContentTask.spawn(tab.linkedBrowser, consts, task); - tab.linkedBrowser.loadURI("data:text/html;charset=utf-8," + - "<html><body>" + - "<form id='" + consts.FORM1_ID + "'>" + - "<input id='" + consts.CHANGE_INPUT_ID + "'></form>" + - "<form id='" + consts.FORM2_ID + "'></form>" + - "</body></html>"); - yield promise; - gBrowser.removeCurrentTab(); -}); - diff --git a/toolkit/components/passwordmgr/test/browser/browser_autocomplete_insecure_warning.js b/toolkit/components/passwordmgr/test/browser/browser_autocomplete_insecure_warning.js deleted file mode 100644 index 6aa8e5cf7..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_autocomplete_insecure_warning.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; - -const EXPECTED_SUPPORT_URL = Services.urlFormatter.formatURLPref("app.support.baseURL") + - "insecure-password"; - -add_task(function* test_clickInsecureFieldWarning() { - let url = "https://example.com" + DIRECTORY_PATH + "form_cross_origin_insecure_action.html"; - - yield BrowserTestUtils.withNewTab({ - gBrowser, - url, - }, function*(browser) { - let popup = document.getElementById("PopupAutoComplete"); - ok(popup, "Got popup"); - - let promiseShown = BrowserTestUtils.waitForEvent(popup, "popupshown"); - - yield SimpleTest.promiseFocus(browser); - info("content window focused"); - - // Focus the username field to open the popup. - yield ContentTask.spawn(browser, null, function openAutocomplete() { - content.document.getElementById("form-basic-username").focus(); - }); - - yield promiseShown; - ok(promiseShown, "autocomplete shown"); - - let warningItem = document.getAnonymousElementByAttribute(popup, "type", "insecureWarning"); - ok(warningItem, "Got warning richlistitem"); - - yield BrowserTestUtils.waitForCondition(() => !warningItem.collapsed, "Wait for warning to show"); - - info("Clicking on warning"); - let supportTabPromise = BrowserTestUtils.waitForNewTab(gBrowser, EXPECTED_SUPPORT_URL); - EventUtils.synthesizeMouseAtCenter(warningItem, {}); - let supportTab = yield supportTabPromise; - ok(supportTab, "Support tab opened"); - yield BrowserTestUtils.removeTab(supportTab); - }); -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger.js b/toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger.js deleted file mode 100644 index b6bfdbf50..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger.js +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Test capture popup notifications - */ - -const BRAND_BUNDLE = Services.strings.createBundle("chrome://branding/locale/brand.properties"); -const BRAND_SHORT_NAME = BRAND_BUNDLE.GetStringFromName("brandShortName"); - -let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); -let login1 = new nsLoginInfo("http://example.com", "http://example.com", null, - "notifyu1", "notifyp1", "user", "pass"); -let login2 = new nsLoginInfo("http://example.com", "http://example.com", null, - "", "notifyp1", "", "pass"); -let login1B = new nsLoginInfo("http://example.com", "http://example.com", null, - "notifyu1B", "notifyp1B", "user", "pass"); -let login2B = new nsLoginInfo("http://example.com", "http://example.com", null, - "", "notifyp1B", "", "pass"); - -requestLongerTimeout(2); - -add_task(function* setup() { - // Load recipes for this test. - let recipeParent = yield LoginManagerParent.recipeParentPromise; - yield recipeParent.load({ - siteRecipes: [{ - hosts: ["example.org"], - usernameSelector: "#user", - passwordSelector: "#pass", - }], - }); -}); - -add_task(function* test_remember_opens() { - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "got notification popup"); - notif.remove(); - }); -}); - -add_task(function* test_clickNever() { - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "got notification popup"); - is(true, Services.logins.getLoginSavingEnabled("http://example.com"), - "Checking for login saving enabled"); - - yield* checkDoorhangerUsernamePassword("notifyu1", "notifyp1"); - clickDoorhangerButton(notif, NEVER_BUTTON); - }); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); - - info("Make sure Never took effect"); - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(!notif, "checking for no notification popup"); - is(false, Services.logins.getLoginSavingEnabled("http://example.com"), - "Checking for login saving disabled"); - Services.logins.setLoginSavingEnabled("http://example.com", true); - }); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); -}); - -add_task(function* test_clickRemember() { - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "got notification popup"); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); - - yield* checkDoorhangerUsernamePassword("notifyu1", "notifyp1"); - clickDoorhangerButton(notif, REMEMBER_BUTTON); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username used on the new entry"); - is(login.password, "notifyp1", "Check the password used on the new entry"); - is(login.timesUsed, 1, "Check times used on new entry"); - - info("Make sure Remember took effect and we don't prompt for an existing login"); - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(!notif, "checking for no notification popup"); - }); - - logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username used"); - is(login.password, "notifyp1", "Check the password used"); - is(login.timesUsed, 2, "Check times used incremented"); - - checkOnlyLoginWasUsedTwice({ justChanged: false }); - - // remove that login - Services.logins.removeLogin(login1); -}); - -/* signons.rememberSignons pref tests... */ - -add_task(function* test_rememberSignonsFalse() { - info("Make sure we don't prompt with rememberSignons=false"); - Services.prefs.setBoolPref("signon.rememberSignons", false); - - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(!notif, "checking for no notification popup"); - }); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); -}); - -add_task(function* test_rememberSignonsTrue() { - info("Make sure we prompt with rememberSignons=true"); - Services.prefs.setBoolPref("signon.rememberSignons", true); - - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "got notification popup"); - notif.remove(); - }); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); -}); - -/* autocomplete=off tests... */ - -add_task(function* test_autocompleteOffUsername() { - info("Check for notification popup when autocomplete=off present on username"); - - yield testSubmittingLoginForm("subtst_notifications_2.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "checking for notification popup"); - notif.remove(); - }); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); -}); - -add_task(function* test_autocompleteOffPassword() { - info("Check for notification popup when autocomplete=off present on password"); - - yield testSubmittingLoginForm("subtst_notifications_3.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "checking for notification popup"); - notif.remove(); - }); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); -}); - -add_task(function* test_autocompleteOffForm() { - info("Check for notification popup when autocomplete=off present on form"); - - yield testSubmittingLoginForm("subtst_notifications_4.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "checking for notification popup"); - notif.remove(); - }); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); -}); - - -add_task(function* test_noPasswordField() { - info("Check for no notification popup when no password field present"); - - yield testSubmittingLoginForm("subtst_notifications_5.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "null", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(!notif, "checking for no notification popup"); - }); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); -}); - -add_task(function* test_pwOnlyLoginMatchesForm() { - info("Check for update popup when existing pw-only login matches form."); - Services.logins.addLogin(login2); - - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-change"); - ok(notif, "checking for notification popup"); - notif.remove(); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "", "Check the username"); - is(login.password, "notifyp1", "Check the password"); - is(login.timesUsed, 1, "Check times used"); - - Services.logins.removeLogin(login2); -}); - -add_task(function* test_pwOnlyFormMatchesLogin() { - info("Check for no notification popup when pw-only form matches existing login."); - Services.logins.addLogin(login1); - - yield testSubmittingLoginForm("subtst_notifications_6.html", function*(fieldValues) { - is(fieldValues.username, "null", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(!notif, "checking for no notification popup"); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username"); - is(login.password, "notifyp1", "Check the password"); - is(login.timesUsed, 2, "Check times used"); - - Services.logins.removeLogin(login1); -}); - -add_task(function* test_pwOnlyFormDoesntMatchExisting() { - info("Check for notification popup when pw-only form doesn't match existing login."); - Services.logins.addLogin(login1B); - - yield testSubmittingLoginForm("subtst_notifications_6.html", function*(fieldValues) { - is(fieldValues.username, "null", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "got notification popup"); - notif.remove(); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1B", "Check the username unchanged"); - is(login.password, "notifyp1B", "Check the password unchanged"); - is(login.timesUsed, 1, "Check times used"); - - Services.logins.removeLogin(login1B); -}); - -add_task(function* test_changeUPLoginOnUPForm_dont() { - info("Check for change-password popup, u+p login on u+p form. (not changed)"); - Services.logins.addLogin(login1); - - yield testSubmittingLoginForm("subtst_notifications_8.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "pass2", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-change"); - ok(notif, "got notification popup"); - - yield* checkDoorhangerUsernamePassword("notifyu1", "pass2"); - clickDoorhangerButton(notif, DONT_CHANGE_BUTTON); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username unchanged"); - is(login.password, "notifyp1", "Check the password unchanged"); - is(login.timesUsed, 1, "Check times used"); - - Services.logins.removeLogin(login1); -}); - -add_task(function* test_changeUPLoginOnUPForm_change() { - info("Check for change-password popup, u+p login on u+p form."); - Services.logins.addLogin(login1); - - yield testSubmittingLoginForm("subtst_notifications_8.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "pass2", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-change"); - ok(notif, "got notification popup"); - - yield* checkDoorhangerUsernamePassword("notifyu1", "pass2"); - clickDoorhangerButton(notif, CHANGE_BUTTON); - - ok(!getCaptureDoorhanger("password-change"), "popup should be gone"); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username unchanged"); - is(login.password, "pass2", "Check the password changed"); - is(login.timesUsed, 2, "Check times used"); - - checkOnlyLoginWasUsedTwice({ justChanged: true }); - - // cleanup - login1.password = "pass2"; - Services.logins.removeLogin(login1); - login1.password = "notifyp1"; -}); - -add_task(function* test_changePLoginOnUPForm() { - info("Check for change-password popup, p-only login on u+p form."); - Services.logins.addLogin(login2); - - yield testSubmittingLoginForm("subtst_notifications_9.html", function*(fieldValues) { - is(fieldValues.username, "", "Checking submitted username"); - is(fieldValues.password, "pass2", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-change"); - ok(notif, "got notification popup"); - - yield* checkDoorhangerUsernamePassword("", "pass2"); - clickDoorhangerButton(notif, CHANGE_BUTTON); - - ok(!getCaptureDoorhanger("password-change"), "popup should be gone"); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "", "Check the username unchanged"); - is(login.password, "pass2", "Check the password changed"); - is(login.timesUsed, 2, "Check times used"); - - // no cleanup -- saved password to be used in the next test. -}); - -add_task(function* test_changePLoginOnPForm() { - info("Check for change-password popup, p-only login on p-only form."); - - yield testSubmittingLoginForm("subtst_notifications_10.html", function*(fieldValues) { - is(fieldValues.username, "null", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-change"); - ok(notif, "got notification popup"); - - yield* checkDoorhangerUsernamePassword("", "notifyp1"); - clickDoorhangerButton(notif, CHANGE_BUTTON); - - ok(!getCaptureDoorhanger("password-change"), "popup should be gone"); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "", "Check the username unchanged"); - is(login.password, "notifyp1", "Check the password changed"); - is(login.timesUsed, 3, "Check times used"); - - Services.logins.removeLogin(login2); -}); - -add_task(function* test_checkUPSaveText() { - info("Check text on a user+pass notification popup"); - - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "got notification popup"); - // Check the text, which comes from the localized saveLoginText string. - let notificationText = notif.message; - let expectedText = "Would you like " + BRAND_SHORT_NAME + " to remember this login?"; - is(expectedText, notificationText, "Checking text: " + notificationText); - notif.remove(); - }); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); -}); - -add_task(function* test_checkPSaveText() { - info("Check text on a pass-only notification popup"); - - yield testSubmittingLoginForm("subtst_notifications_6.html", function*(fieldValues) { - is(fieldValues.username, "null", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "got notification popup"); - // Check the text, which comes from the localized saveLoginTextNoUser string. - let notificationText = notif.message; - let expectedText = "Would you like " + BRAND_SHORT_NAME + " to remember this password?"; - is(expectedText, notificationText, "Checking text: " + notificationText); - notif.remove(); - }); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); -}); - -add_task(function* test_capture2pw0un() { - info("Check for notification popup when a form with 2 password fields (no username) " + - "is submitted and there are no saved logins."); - - yield testSubmittingLoginForm("subtst_notifications_2pw_0un.html", function*(fieldValues) { - is(fieldValues.username, "null", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "got notification popup"); - notif.remove(); - }); - - is(Services.logins.getAllLogins().length, 0, "Should not have any logins yet"); -}); - -add_task(function* test_change2pw0unExistingDifferentUP() { - info("Check for notification popup when a form with 2 password fields (no username) " + - "is submitted and there is a saved login with a username and different password."); - - Services.logins.addLogin(login1B); - - yield testSubmittingLoginForm("subtst_notifications_2pw_0un.html", function*(fieldValues) { - is(fieldValues.username, "null", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-change"); - ok(notif, "got notification popup"); - notif.remove(); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1B", "Check the username unchanged"); - is(login.password, "notifyp1B", "Check the password unchanged"); - is(login.timesUsed, 1, "Check times used"); - - Services.logins.removeLogin(login1B); -}); - -add_task(function* test_change2pw0unExistingDifferentP() { - info("Check for notification popup when a form with 2 password fields (no username) " + - "is submitted and there is a saved login with no username and different password."); - - Services.logins.addLogin(login2B); - - yield testSubmittingLoginForm("subtst_notifications_2pw_0un.html", function*(fieldValues) { - is(fieldValues.username, "null", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-change"); - ok(notif, "got notification popup"); - notif.remove(); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "", "Check the username unchanged"); - is(login.password, "notifyp1B", "Check the password unchanged"); - is(login.timesUsed, 1, "Check times used"); - - Services.logins.removeLogin(login2B); -}); - -add_task(function* test_change2pw0unExistingWithSameP() { - info("Check for no notification popup when a form with 2 password fields (no username) " + - "is submitted and there is a saved login with a username and the same password."); - - Services.logins.addLogin(login2); - - yield testSubmittingLoginForm("subtst_notifications_2pw_0un.html", function*(fieldValues) { - is(fieldValues.username, "null", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-change"); - ok(!notif, "checking for no notification popup"); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "", "Check the username unchanged"); - is(login.password, "notifyp1", "Check the password unchanged"); - is(login.timesUsed, 2, "Check times used incremented"); - - checkOnlyLoginWasUsedTwice({ justChanged: false }); - - Services.logins.removeLogin(login2); -}); - -add_task(function* test_changeUPLoginOnPUpdateForm() { - info("Check for change-password popup, u+p login on password update form."); - Services.logins.addLogin(login1); - - yield testSubmittingLoginForm("subtst_notifications_change_p.html", function*(fieldValues) { - is(fieldValues.username, "null", "Checking submitted username"); - is(fieldValues.password, "pass2", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-change"); - ok(notif, "got notification popup"); - - yield* checkDoorhangerUsernamePassword("notifyu1", "pass2"); - clickDoorhangerButton(notif, CHANGE_BUTTON); - - ok(!getCaptureDoorhanger("password-change"), "popup should be gone"); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username unchanged"); - is(login.password, "pass2", "Check the password changed"); - is(login.timesUsed, 2, "Check times used"); - - checkOnlyLoginWasUsedTwice({ justChanged: true }); - - // cleanup - login1.password = "pass2"; - Services.logins.removeLogin(login1); - login1.password = "notifyp1"; -}); - -add_task(function* test_recipeCaptureFields_NewLogin() { - info("Check that we capture the proper fields when a field recipe is in use."); - - yield testSubmittingLoginForm("subtst_notifications_2pw_1un_1text.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "got notification popup"); - - // Sanity check, no logins should exist yet. - let logins = Services.logins.getAllLogins(); - is(logins.length, 0, "Should not have any logins yet"); - - yield* checkDoorhangerUsernamePassword("notifyu1", "notifyp1"); - clickDoorhangerButton(notif, REMEMBER_BUTTON); - - }, "http://example.org"); // The recipe is for example.org - - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username unchanged"); - is(login.password, "notifyp1", "Check the password unchanged"); - is(login.timesUsed, 1, "Check times used"); -}); - -add_task(function* test_recipeCaptureFields_ExistingLogin() { - info("Check that we capture the proper fields when a field recipe is in use " + - "and there is a matching login"); - - yield testSubmittingLoginForm("subtst_notifications_2pw_1un_1text.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(!notif, "checking for no notification popup"); - }, "http://example.org"); - - checkOnlyLoginWasUsedTwice({ justChanged: false }); - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username unchanged"); - is(login.password, "notifyp1", "Check the password unchanged"); - is(login.timesUsed, 2, "Check times used incremented"); - - Services.logins.removeAllLogins(); -}); - -add_task(function* test_noShowPasswordOnDismissal() { - info("Check for no Show Password field when the doorhanger is dismissed"); - - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - info("Opening popup"); - let notif = getCaptureDoorhanger("password-save"); - let { panel } = PopupNotifications; - - info("Hiding popup."); - let promiseHidden = BrowserTestUtils.waitForEvent(panel, "popuphidden"); - panel.hidePopup(); - yield promiseHidden; - - info("Clicking on anchor to reshow popup."); - let promiseShown = BrowserTestUtils.waitForEvent(panel, "popupshown"); - notif.anchorElement.click(); - yield promiseShown; - - let passwordVisiblityToggle = panel.querySelector("#password-notification-visibilityToggle"); - is(passwordVisiblityToggle.hidden, true, "Check that the Show Password field is Hidden"); - }); -}); - -// TODO: -// * existing login test, form has different password --> change password, no save prompt diff --git a/toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger_httpsUpgrade.js b/toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger_httpsUpgrade.js deleted file mode 100644 index 9be0aa631..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger_httpsUpgrade.js +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Test capture popup notifications with HTTPS upgrades - */ - -let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); -let login1 = new nsLoginInfo("http://example.com", "http://example.com", null, - "notifyu1", "notifyp1", "user", "pass"); -let login1HTTPS = new nsLoginInfo("https://example.com", "https://example.com", null, - "notifyu1", "notifyp1", "user", "pass"); - -add_task(function* test_httpsUpgradeCaptureFields_noChange() { - info("Check that we don't prompt to remember when capturing an upgraded login with no change"); - Services.logins.addLogin(login1); - // Sanity check the HTTP login exists. - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should have the HTTP login"); - - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(!notif, "checking for no notification popup"); - }, "https://example.com"); // This is HTTPS whereas the saved login is HTTP - - logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login still"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.hostname, "http://example.com", "Check the hostname is unchanged"); - is(login.username, "notifyu1", "Check the username is unchanged"); - is(login.password, "notifyp1", "Check the password is unchanged"); - is(login.timesUsed, 2, "Check times used increased"); - - Services.logins.removeLogin(login1); -}); - -add_task(function* test_httpsUpgradeCaptureFields_changePW() { - info("Check that we prompt to change when capturing an upgraded login with a new PW"); - Services.logins.addLogin(login1); - // Sanity check the HTTP login exists. - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should have the HTTP login"); - - yield testSubmittingLoginForm("subtst_notifications_8.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "pass2", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-change"); - ok(notif, "checking for a change popup"); - - yield* checkDoorhangerUsernamePassword("notifyu1", "pass2"); - clickDoorhangerButton(notif, CHANGE_BUTTON); - - ok(!getCaptureDoorhanger("password-change"), "popup should be gone"); - }, "https://example.com"); // This is HTTPS whereas the saved login is HTTP - - checkOnlyLoginWasUsedTwice({ justChanged: true }); - logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login still"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.hostname, "https://example.com", "Check the hostname is upgraded"); - is(login.formSubmitURL, "https://example.com", "Check the formSubmitURL is upgraded"); - is(login.username, "notifyu1", "Check the username is unchanged"); - is(login.password, "pass2", "Check the password changed"); - is(login.timesUsed, 2, "Check times used increased"); - - Services.logins.removeAllLogins(); -}); - -add_task(function* test_httpsUpgradeCaptureFields_captureMatchingHTTP() { - info("Capture a new HTTP login which matches a stored HTTPS one."); - Services.logins.addLogin(login1HTTPS); - - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(notif, "got notification popup"); - - is(Services.logins.getAllLogins().length, 1, "Should only have the HTTPS login"); - - yield* checkDoorhangerUsernamePassword("notifyu1", "notifyp1"); - clickDoorhangerButton(notif, REMEMBER_BUTTON); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 2, "Should have both HTTP and HTTPS logins"); - for (let login of logins) { - login = login.QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username used on the new entry"); - is(login.password, "notifyp1", "Check the password used on the new entry"); - is(login.timesUsed, 1, "Check times used on entry"); - } - - info("Make sure Remember took effect and we don't prompt for an existing HTTP login"); - yield testSubmittingLoginForm("subtst_notifications_1.html", function*(fieldValues) { - is(fieldValues.username, "notifyu1", "Checking submitted username"); - is(fieldValues.password, "notifyp1", "Checking submitted password"); - let notif = getCaptureDoorhanger("password-save"); - ok(!notif, "checking for no notification popup"); - }); - - logins = Services.logins.getAllLogins(); - is(logins.length, 2, "Should have both HTTP and HTTPS still"); - - let httpsLogins = LoginHelper.searchLoginsWithObject({ - hostname: "https://example.com", - }); - is(httpsLogins.length, 1, "Check https logins count"); - let httpsLogin = httpsLogins[0].QueryInterface(Ci.nsILoginMetaInfo); - ok(httpsLogin.equals(login1HTTPS), "Check HTTPS login didn't change"); - is(httpsLogin.timesUsed, 1, "Check times used"); - - let httpLogins = LoginHelper.searchLoginsWithObject({ - hostname: "http://example.com", - }); - is(httpLogins.length, 1, "Check http logins count"); - let httpLogin = httpLogins[0].QueryInterface(Ci.nsILoginMetaInfo); - ok(httpLogin.equals(login1), "Check HTTP login is as expected"); - is(httpLogin.timesUsed, 2, "Check times used increased"); - - Services.logins.removeLogin(login1); - Services.logins.removeLogin(login1HTTPS); -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger_window_open.js b/toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger_window_open.js deleted file mode 100644 index 1bcfec5eb..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_capture_doorhanger_window_open.js +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Test capture popup notifications in content opened by window.open - */ - -let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); -let login1 = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null, - "notifyu1", "notifyp1", "user", "pass"); -let login2 = new nsLoginInfo("http://mochi.test:8888", "http://mochi.test:8888", null, - "notifyu2", "notifyp2", "user", "pass"); - - -function withTestTabUntilStorageChange(aPageFile, aTaskFn) { - function storageChangedObserved(subject, data) { - // Watch for actions triggered from a doorhanger (not cleanup tasks with removeLogin) - if (data == "removeLogin") { - return false; - } - return true; - } - - let storageChangedPromised = TestUtils.topicObserved("passwordmgr-storage-changed", - storageChangedObserved); - return BrowserTestUtils.withNewTab({ - gBrowser, - url: "http://mochi.test:8888" + DIRECTORY_PATH + aPageFile, - }, function*(browser) { - ok(true, "loaded " + aPageFile); - info("running test case task"); - yield* aTaskFn(); - info("waiting for storage change"); - yield storageChangedPromised; - }); -} - -add_task(function* setup() { - yield SimpleTest.promiseFocus(window); -}); - -add_task(function* test_saveChromeHiddenAutoClose() { - let notifShownPromise = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); - // query arguments are: username, password, features, auto-close (delimited by '|') - let url = "subtst_notifications_11.html?notifyu1|notifyp1|" + - "menubar=no,toolbar=no,location=no|autoclose"; - yield withTestTabUntilStorageChange(url, function*() { - info("waiting for popupshown"); - yield notifShownPromise; - // the popup closes and the doorhanger should appear in the opener - let popup = getCaptureDoorhanger("password-save"); - ok(popup, "got notification popup"); - yield* checkDoorhangerUsernamePassword("notifyu1", "notifyp1"); - // Sanity check, no logins should exist yet. - let logins = Services.logins.getAllLogins(); - is(logins.length, 0, "Should not have any logins yet"); - - clickDoorhangerButton(popup, REMEMBER_BUTTON); - }); - // Check result of clicking Remember - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.timesUsed, 1, "Check times used on new entry"); - is(login.username, "notifyu1", "Check the username used on the new entry"); - is(login.password, "notifyp1", "Check the password used on the new entry"); -}); - -add_task(function* test_changeChromeHiddenAutoClose() { - let notifShownPromise = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); - let url = "subtst_notifications_11.html?notifyu1|pass2|menubar=no,toolbar=no,location=no|autoclose"; - yield withTestTabUntilStorageChange(url, function*() { - info("waiting for popupshown"); - yield notifShownPromise; - let popup = getCaptureDoorhanger("password-change"); - ok(popup, "got notification popup"); - yield* checkDoorhangerUsernamePassword("notifyu1", "pass2"); - clickDoorhangerButton(popup, CHANGE_BUTTON); - }); - - // Check to make sure we updated the password, timestamps and use count for - // the login being changed with this form. - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username"); - is(login.password, "pass2", "Check password changed"); - is(login.timesUsed, 2, "check .timesUsed incremented on change"); - ok(login.timeCreated < login.timeLastUsed, "timeLastUsed bumped"); - ok(login.timeLastUsed == login.timePasswordChanged, "timeUsed == timeChanged"); - - login1.password = "pass2"; - Services.logins.removeLogin(login1); - login1.password = "notifyp1"; -}); - -add_task(function* test_saveChromeVisibleSameWindow() { - // This test actually opens a new tab in the same window with default browser settings. - let url = "subtst_notifications_11.html?notifyu2|notifyp2||"; - let notifShownPromise = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); - yield withTestTabUntilStorageChange(url, function*() { - yield notifShownPromise; - let popup = getCaptureDoorhanger("password-save"); - ok(popup, "got notification popup"); - yield* checkDoorhangerUsernamePassword("notifyu2", "notifyp2"); - clickDoorhangerButton(popup, REMEMBER_BUTTON); - yield BrowserTestUtils.removeTab(gBrowser.selectedTab); - }); - - // Check result of clicking Remember - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login now"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu2", "Check the username used on the new entry"); - is(login.password, "notifyp2", "Check the password used on the new entry"); - is(login.timesUsed, 1, "Check times used on new entry"); -}); - -add_task(function* test_changeChromeVisibleSameWindow() { - let url = "subtst_notifications_11.html?notifyu2|pass2||"; - let notifShownPromise = BrowserTestUtils.waitForEvent(PopupNotifications.panel, "popupshown"); - yield withTestTabUntilStorageChange(url, function*() { - yield notifShownPromise; - let popup = getCaptureDoorhanger("password-change"); - ok(popup, "got notification popup"); - yield* checkDoorhangerUsernamePassword("notifyu2", "pass2"); - clickDoorhangerButton(popup, CHANGE_BUTTON); - yield BrowserTestUtils.removeTab(gBrowser.selectedTab); - }); - - // Check to make sure we updated the password, timestamps and use count for - // the login being changed with this form. - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should have 1 login"); - let login = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu2", "Check the username"); - is(login.password, "pass2", "Check password changed"); - is(login.timesUsed, 2, "check .timesUsed incremented on change"); - ok(login.timeCreated < login.timeLastUsed, "timeLastUsed bumped"); - ok(login.timeLastUsed == login.timePasswordChanged, "timeUsed == timeChanged"); - - // cleanup - login2.password = "pass2"; - Services.logins.removeLogin(login2); - login2.password = "notifyp2"; -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_context_menu.js b/toolkit/components/passwordmgr/test/browser/browser_context_menu.js deleted file mode 100644 index 6cfcaa7c2..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_context_menu.js +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Test the password manager context menu. - */ - -/* eslint no-shadow:"off" */ - -"use strict"; - -// The hostname for the test URIs. -const TEST_HOSTNAME = "https://example.com"; -const MULTIPLE_FORMS_PAGE_PATH = "/browser/toolkit/components/passwordmgr/test/browser/multiple_forms.html"; - -const CONTEXT_MENU = document.getElementById("contentAreaContextMenu"); -const POPUP_HEADER = document.getElementById("fill-login"); - -/** - * Initialize logins needed for the tests and disable autofill - * for login forms for easier testing of manual fill. - */ -add_task(function* test_initialize() { - Services.prefs.setBoolPref("signon.autofillForms", false); - registerCleanupFunction(() => { - Services.prefs.clearUserPref("signon.autofillForms"); - Services.prefs.clearUserPref("signon.schemeUpgrades"); - }); - for (let login of loginList()) { - Services.logins.addLogin(login); - } -}); - -/** - * Check if the context menu is populated with the right - * menuitems for the target password input field. - */ -add_task(function* test_context_menu_populate_password_noSchemeUpgrades() { - Services.prefs.setBoolPref("signon.schemeUpgrades", false); - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: TEST_HOSTNAME + MULTIPLE_FORMS_PAGE_PATH, - }, function* (browser) { - yield openPasswordContextMenu(browser, "#test-password-1"); - - // Check the content of the password manager popup - let popupMenu = document.getElementById("fill-login-popup"); - checkMenu(popupMenu, 2); - - CONTEXT_MENU.hidePopup(); - }); -}); - -/** - * Check if the context menu is populated with the right - * menuitems for the target password input field. - */ -add_task(function* test_context_menu_populate_password_schemeUpgrades() { - Services.prefs.setBoolPref("signon.schemeUpgrades", true); - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: TEST_HOSTNAME + MULTIPLE_FORMS_PAGE_PATH, - }, function* (browser) { - yield openPasswordContextMenu(browser, "#test-password-1"); - - // Check the content of the password manager popup - let popupMenu = document.getElementById("fill-login-popup"); - checkMenu(popupMenu, 3); - - CONTEXT_MENU.hidePopup(); - }); -}); - -/** - * Check if the context menu is populated with the right menuitems - * for the target username field with a password field present. - */ -add_task(function* test_context_menu_populate_username_with_password_noSchemeUpgrades() { - Services.prefs.setBoolPref("signon.schemeUpgrades", false); - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: TEST_HOSTNAME + "/browser/toolkit/components/" + - "passwordmgr/test/browser/multiple_forms.html", - }, function* (browser) { - yield openPasswordContextMenu(browser, "#test-username-2"); - - // Check the content of the password manager popup - let popupMenu = document.getElementById("fill-login-popup"); - checkMenu(popupMenu, 2); - - CONTEXT_MENU.hidePopup(); - }); -}); -/** - * Check if the context menu is populated with the right menuitems - * for the target username field with a password field present. - */ -add_task(function* test_context_menu_populate_username_with_password_schemeUpgrades() { - Services.prefs.setBoolPref("signon.schemeUpgrades", true); - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: TEST_HOSTNAME + "/browser/toolkit/components/" + - "passwordmgr/test/browser/multiple_forms.html", - }, function* (browser) { - yield openPasswordContextMenu(browser, "#test-username-2"); - - // Check the content of the password manager popup - let popupMenu = document.getElementById("fill-login-popup"); - checkMenu(popupMenu, 3); - - CONTEXT_MENU.hidePopup(); - }); -}); - -/** - * Check if the password field is correctly filled when one - * login menuitem is clicked. - */ -add_task(function* test_context_menu_password_fill() { - Services.prefs.setBoolPref("signon.schemeUpgrades", true); - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: TEST_HOSTNAME + MULTIPLE_FORMS_PAGE_PATH, - }, function* (browser) { - let formDescriptions = yield ContentTask.spawn(browser, {}, function*() { - let forms = Array.from(content.document.getElementsByClassName("test-form")); - return forms.map((f) => f.getAttribute("description")); - }); - - for (let description of formDescriptions) { - info("Testing form: " + description); - - let passwordInputIds = yield ContentTask.spawn(browser, {description}, function*({description}) { - let formElement = content.document.querySelector(`[description="${description}"]`); - let passwords = Array.from(formElement.querySelectorAll("input[type='password']")); - return passwords.map((p) => p.id); - }); - - for (let inputId of passwordInputIds) { - info("Testing password field: " + inputId); - - // Synthesize a right mouse click over the username input element. - yield openPasswordContextMenu(browser, "#" + inputId, function*() { - let inputDisabled = yield ContentTask - .spawn(browser, {inputId}, 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. - if (inputDisabled) { - Assert.ok(!POPUP_HEADER.hidden, "Popup menu is not hidden."); - Assert.ok(POPUP_HEADER.disabled, "Popup menu is disabled."); - CONTEXT_MENU.hidePopup(); - } - - return !inputDisabled; - }); - - if (CONTEXT_MENU.state != "open") { - continue; - } - - // The only field affected by the password fill - // should be the target password field itself. - yield assertContextMenuFill(browser, description, null, inputId, 1); - yield ContentTask.spawn(browser, {inputId}, function*({inputId}) { - let passwordField = content.document.getElementById(inputId); - Assert.equal(passwordField.value, "password1", "Check upgraded login was actually used"); - }); - - CONTEXT_MENU.hidePopup(); - } - } - }); -}); - -/** - * Check if the form is correctly filled when one - * username context menu login menuitem is clicked. - */ -add_task(function* test_context_menu_username_login_fill() { - Services.prefs.setBoolPref("signon.schemeUpgrades", true); - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: TEST_HOSTNAME + MULTIPLE_FORMS_PAGE_PATH, - }, function* (browser) { - - let formDescriptions = yield ContentTask.spawn(browser, {}, function*() { - let forms = Array.from(content.document.getElementsByClassName("test-form")); - return forms.map((f) => f.getAttribute("description")); - }); - - for (let description of formDescriptions) { - info("Testing form: " + description); - let usernameInputIds = yield ContentTask - .spawn(browser, {description}, function*({description}) { - 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); - - // Synthesize a right mouse click over the username input element. - yield openPasswordContextMenu(browser, "#" + inputId, function*() { - let headerHidden = POPUP_HEADER.hidden; - let headerDisabled = POPUP_HEADER.disabled; - - let data = {description, inputId, headerHidden, headerDisabled}; - let shouldContinue = yield ContentTask.spawn(browser, data, function*(data) { - let {description, inputId, headerHidden, headerDisabled} = data; - let formElement = content.document.querySelector(`[description="${description}"]`); - let usernameField = content.document.getElementById(inputId); - // We always want to check if the first password field is filled, - // since this is the current behavior from the _fillForm function. - let passwordField = formElement.querySelector("input[type='password']"); - - // If we don't want to see the actual popup menu, - // check if the popup is hidden or disabled. - if (!passwordField || usernameField.disabled || usernameField.readOnly || - passwordField.disabled || passwordField.readOnly) { - if (!passwordField) { - Assert.ok(headerHidden, "Popup menu is hidden."); - } else { - Assert.ok(!headerHidden, "Popup menu is not hidden."); - Assert.ok(headerDisabled, "Popup menu is disabled."); - } - return false; - } - return true; - }); - - if (!shouldContinue) { - CONTEXT_MENU.hidePopup(); - } - - return shouldContinue; - }); - - if (CONTEXT_MENU.state != "open") { - continue; - } - - let passwordFieldId = yield ContentTask - .spawn(browser, {description}, 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 - yield assertContextMenuFill(browser, description, inputId, passwordFieldId, 1); - - yield ContentTask.spawn(browser, {passwordFieldId}, function*({passwordFieldId}) { - let passwordField = content.document.getElementById(passwordFieldId); - if (!passwordField.hasAttribute("expectedFail")) { - Assert.equal(passwordField.value, "password1", "Check upgraded login was actually used"); - } - }); - - CONTEXT_MENU.hidePopup(); - } - } - }); -}); - -/** - * Synthesize mouse clicks to open the password manager context menu popup - * for a target password input element. - * - * assertCallback should return true if we should continue or else false. - */ -function* openPasswordContextMenu(browser, passwordInput, assertCallback = null) { - // Synthesize a right mouse click over the password input element. - let contextMenuShownPromise = BrowserTestUtils.waitForEvent(CONTEXT_MENU, "popupshown"); - let eventDetails = {type: "contextmenu", button: 2}; - BrowserTestUtils.synthesizeMouseAtCenter(passwordInput, eventDetails, browser); - yield contextMenuShownPromise; - - if (assertCallback) { - let shouldContinue = yield assertCallback(); - if (!shouldContinue) { - return; - } - } - - // Synthesize a mouse click over the fill login menu header. - let popupShownPromise = BrowserTestUtils.waitForEvent(POPUP_HEADER, "popupshown"); - EventUtils.synthesizeMouseAtCenter(POPUP_HEADER, {}); - yield popupShownPromise; -} - -/** - * Verify that only the expected form fields are filled. - */ -function* assertContextMenuFill(browser, formId, usernameFieldId, passwordFieldId, loginIndex) { - let popupMenu = document.getElementById("fill-login-popup"); - let unchangedSelector = `[description="${formId}"] input:not(#${passwordFieldId})`; - - if (usernameFieldId) { - unchangedSelector += `:not(#${usernameFieldId})`; - } - - yield ContentTask.spawn(browser, {unchangedSelector}, function*({unchangedSelector}) { - let unchangedFields = content.document.querySelectorAll(unchangedSelector); - - // Store the value of fields that should remain unchanged. - if (unchangedFields.length) { - for (let field of unchangedFields) { - field.setAttribute("original-value", field.value); - } - } - }); - - // Execute the default command of the specified login menuitem found in the context menu. - let loginItem = popupMenu.getElementsByClassName("context-login-item")[loginIndex]; - - // Find the used login by it's username (Use only unique usernames in this test). - let {username, password} = getLoginFromUsername(loginItem.label); - - let data = {username, password, usernameFieldId, passwordFieldId, formId, unchangedSelector}; - let continuePromise = ContentTask.spawn(browser, data, function*(data) { - let {username, password, usernameFieldId, passwordFieldId, formId, unchangedSelector} = data; - let form = content.document.querySelector(`[description="${formId}"]`); - yield ContentTaskUtils.waitForEvent(form, "input", "Username input value changed"); - - if (usernameFieldId) { - let usernameField = content.document.getElementById(usernameFieldId); - - // If we have an username field, check if it's correctly filled - if (usernameField.getAttribute("expectedFail") == null) { - Assert.equal(username, usernameField.value, "Username filled and correct."); - } - } - - if (passwordFieldId) { - let passwordField = content.document.getElementById(passwordFieldId); - - // If we have a password field, check if it's correctly filled - if (passwordField && passwordField.getAttribute("expectedFail") == null) { - Assert.equal(password, passwordField.value, "Password filled and correct."); - } - } - - let unchangedFields = content.document.querySelectorAll(unchangedSelector); - - // Check that all fields that should not change have the same value as before. - if (unchangedFields.length) { - Assert.ok(() => { - for (let field of unchangedFields) { - if (field.value != field.getAttribute("original-value")) { - return false; - } - } - return true; - }, "Other fields were not changed."); - } - }); - - loginItem.doCommand(); - - return continuePromise; -} - -/** - * Check if every login that matches the page hostname are available at the context menu. - * @param {Element} contextMenu - * @param {Number} expectedCount - Number of logins expected in the context menu. Used to ensure -* we continue testing something useful. - */ -function checkMenu(contextMenu, expectedCount) { - let logins = loginList().filter(login => { - return LoginHelper.isOriginMatching(login.hostname, TEST_HOSTNAME, { - schemeUpgrades: Services.prefs.getBoolPref("signon.schemeUpgrades"), - }); - }); - // Make an array of menuitems for easier comparison. - let menuitems = [...CONTEXT_MENU.getElementsByClassName("context-login-item")]; - Assert.equal(menuitems.length, expectedCount, "Expected number of menu items"); - Assert.ok(logins.every(l => menuitems.some(m => l.username == m.label)), "Every login have an item at the menu."); -} - -/** - * Search for a login by it's username. - * - * Only unique login/hostname combinations should be used at this test. - */ -function getLoginFromUsername(username) { - return loginList().find(login => login.username == username); -} - -/** - * List of logins used for the test. - * - * We should only use unique usernames in this test, - * because we need to search logins by username. There is one duplicate u+p combo - * in order to test de-duping in the menu. - */ -function loginList() { - return [ - LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username: "username", - password: "password", - }), - // Same as above but HTTP in order to test de-duping. - LoginTestUtils.testData.formLogin({ - hostname: "http://example.com", - formSubmitURL: "http://example.com", - username: "username", - password: "password", - }), - LoginTestUtils.testData.formLogin({ - hostname: "http://example.com", - formSubmitURL: "http://example.com", - username: "username1", - password: "password1", - }), - LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username: "username2", - password: "password2", - }), - LoginTestUtils.testData.formLogin({ - hostname: "http://example.org", - formSubmitURL: "http://example.org", - username: "username-cross-origin", - password: "password-cross-origin", - }), - ]; -} diff --git a/toolkit/components/passwordmgr/test/browser/browser_context_menu_autocomplete_interaction.js b/toolkit/components/passwordmgr/test/browser/browser_context_menu_autocomplete_interaction.js deleted file mode 100644 index 1b37e3f79..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_context_menu_autocomplete_interaction.js +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Test the password manager context menu interaction with autocomplete. - */ - -"use strict"; - -const TEST_HOSTNAME = "https://example.com"; -const BASIC_FORM_PAGE_PATH = DIRECTORY_PATH + "form_basic.html"; - -var gUnexpectedIsTODO = false; - -/** - * Initialize logins needed for the tests and disable autofill - * for login forms for easier testing of manual fill. - */ -add_task(function* test_initialize() { - let autocompletePopup = document.getElementById("PopupAutoComplete"); - Services.prefs.setBoolPref("signon.autofillForms", false); - registerCleanupFunction(() => { - Services.prefs.clearUserPref("signon.autofillForms"); - autocompletePopup.removeEventListener("popupshowing", autocompleteUnexpectedPopupShowing); - }); - for (let login of loginList()) { - Services.logins.addLogin(login); - } - autocompletePopup.addEventListener("popupshowing", autocompleteUnexpectedPopupShowing); -}); - -add_task(function* test_context_menu_username() { - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: TEST_HOSTNAME + BASIC_FORM_PAGE_PATH, - }, function* (browser) { - yield openContextMenu(browser, "#form-basic-username"); - - let contextMenu = document.getElementById("contentAreaContextMenu"); - Assert.equal(contextMenu.state, "open", "Context menu opened"); - contextMenu.hidePopup(); - }); -}); - -add_task(function* test_context_menu_password() { - gUnexpectedIsTODO = true; - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: TEST_HOSTNAME + BASIC_FORM_PAGE_PATH, - }, function* (browser) { - yield openContextMenu(browser, "#form-basic-password"); - - let contextMenu = document.getElementById("contentAreaContextMenu"); - Assert.equal(contextMenu.state, "open", "Context menu opened"); - contextMenu.hidePopup(); - }); -}); - -function autocompleteUnexpectedPopupShowing(event) { - if (gUnexpectedIsTODO) { - todo(false, "Autocomplete shouldn't appear"); - } else { - Assert.ok(false, "Autocomplete shouldn't appear"); - } - event.target.hidePopup(); -} - -/** - * Synthesize mouse clicks to open the context menu popup - * for a target login input element. - */ -function* openContextMenu(browser, loginInput) { - // First synthesize a mousedown. We need this to get the focus event with the "contextmenu" event. - let eventDetails1 = {type: "mousedown", button: 2}; - BrowserTestUtils.synthesizeMouseAtCenter(loginInput, eventDetails1, browser); - - // Then synthesize the contextmenu click over the input element. - let contextMenuShownPromise = BrowserTestUtils.waitForEvent(window, "popupshown"); - let eventDetails = {type: "contextmenu", button: 2}; - BrowserTestUtils.synthesizeMouseAtCenter(loginInput, eventDetails, browser); - yield contextMenuShownPromise; - - // Wait to see which popups are shown. - yield new Promise(resolve => setTimeout(resolve, 1000)); -} - -function loginList() { - return [ - LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username: "username", - password: "password", - }), - LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username: "username2", - password: "password2", - }), - ]; -} diff --git a/toolkit/components/passwordmgr/test/browser/browser_context_menu_iframe.js b/toolkit/components/passwordmgr/test/browser/browser_context_menu_iframe.js deleted file mode 100644 index c5219789d..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_context_menu_iframe.js +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Test the password manager context menu. - */ - -"use strict"; - -const TEST_HOSTNAME = "https://example.com"; - -// Test with a page that only has a form within an iframe, not in the top-level document -const IFRAME_PAGE_PATH = "/browser/toolkit/components/passwordmgr/test/browser/form_basic_iframe.html"; - -/** - * Initialize logins needed for the tests and disable autofill - * for login forms for easier testing of manual fill. - */ -add_task(function* test_initialize() { - Services.prefs.setBoolPref("signon.autofillForms", false); - registerCleanupFunction(() => { - Services.prefs.clearUserPref("signon.autofillForms"); - Services.prefs.clearUserPref("signon.schemeUpgrades"); - }); - for (let login of loginList()) { - Services.logins.addLogin(login); - } -}); - -/** - * Check if the password field is correctly filled when it's in an iframe. - */ -add_task(function* test_context_menu_iframe_fill() { - Services.prefs.setBoolPref("signon.schemeUpgrades", true); - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: TEST_HOSTNAME + IFRAME_PAGE_PATH - }, function* (browser) { - function getPasswordInput() { - let frame = content.document.getElementById("test-iframe"); - return frame.contentDocument.getElementById("form-basic-password"); - } - - let contextMenuShownPromise = BrowserTestUtils.waitForEvent(window, "popupshown"); - let eventDetails = {type: "contextmenu", button: 2}; - - // To click at the right point we have to take into account the iframe offset. - // Synthesize a right mouse click over the password input element. - BrowserTestUtils.synthesizeMouseAtCenter(getPasswordInput, eventDetails, browser); - yield contextMenuShownPromise; - - // Synthesize a mouse click over the fill login menu header. - let popupHeader = document.getElementById("fill-login"); - let popupShownPromise = BrowserTestUtils.waitForEvent(popupHeader, "popupshown"); - EventUtils.synthesizeMouseAtCenter(popupHeader, {}); - yield popupShownPromise; - - let popupMenu = document.getElementById("fill-login-popup"); - - // Stores the original value of username - function promiseFrameInputValue(name) { - return ContentTask.spawn(browser, name, function(inputname) { - let iframe = content.document.getElementById("test-iframe"); - let input = iframe.contentDocument.getElementById(inputname); - return input.value; - }); - } - let usernameOriginalValue = yield promiseFrameInputValue("form-basic-username"); - - // Execute the command of the first login menuitem found at the context menu. - let passwordChangedPromise = ContentTask.spawn(browser, null, function* () { - let frame = content.document.getElementById("test-iframe"); - let passwordInput = frame.contentDocument.getElementById("form-basic-password"); - yield ContentTaskUtils.waitForEvent(passwordInput, "input"); - }); - - let firstLoginItem = popupMenu.getElementsByClassName("context-login-item")[0]; - firstLoginItem.doCommand(); - - yield passwordChangedPromise; - - // Find the used login by it's username. - let login = getLoginFromUsername(firstLoginItem.label); - let passwordValue = yield promiseFrameInputValue("form-basic-password"); - is(login.password, passwordValue, "Password filled and correct."); - - let usernameNewValue = yield promiseFrameInputValue("form-basic-username"); - is(usernameOriginalValue, - usernameNewValue, - "Username value was not changed."); - - let contextMenu = document.getElementById("contentAreaContextMenu"); - contextMenu.hidePopup(); - }); -}); - -/** - * Search for a login by it's username. - * - * Only unique login/hostname combinations should be used at this test. - */ -function getLoginFromUsername(username) { - return loginList().find(login => login.username == username); -} - -/** - * List of logins used for the test. - * - * We should only use unique usernames in this test, - * because we need to search logins by username. There is one duplicate u+p combo - * in order to test de-duping in the menu. - */ -function loginList() { - return [ - LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username: "username", - password: "password", - }), - // Same as above but HTTP in order to test de-duping. - LoginTestUtils.testData.formLogin({ - hostname: "http://example.com", - formSubmitURL: "http://example.com", - username: "username", - password: "password", - }), - LoginTestUtils.testData.formLogin({ - hostname: "http://example.com", - formSubmitURL: "http://example.com", - username: "username1", - password: "password1", - }), - LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username: "username2", - password: "password2", - }), - LoginTestUtils.testData.formLogin({ - hostname: "http://example.org", - formSubmitURL: "http://example.org", - username: "username-cross-origin", - password: "password-cross-origin", - }), - ]; -} diff --git a/toolkit/components/passwordmgr/test/browser/browser_exceptions_dialog.js b/toolkit/components/passwordmgr/test/browser/browser_exceptions_dialog.js deleted file mode 100644 index 09fbe0eea..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_exceptions_dialog.js +++ /dev/null @@ -1,56 +0,0 @@ - -"use strict"; - -const LOGIN_HOST = "http://example.com"; - -function openExceptionsDialog() { - return window.openDialog( - "chrome://browser/content/preferences/permissions.xul", - "Toolkit:PasswordManagerExceptions", "", - { - blockVisible: true, - sessionVisible: false, - allowVisible: false, - hideStatusColumn: true, - prefilledHost: "", - permissionType: "login-saving" - } - ); -} - -function countDisabledHosts(dialog) { - let doc = dialog.document; - let rejectsTree = doc.getElementById("permissionsTree"); - - return rejectsTree.view.rowCount; -} - -function promiseStorageChanged(expectedData) { - function observer(subject, data) { - return data == expectedData && subject.QueryInterface(Ci.nsISupportsString).data == LOGIN_HOST; - } - - return TestUtils.topicObserved("passwordmgr-storage-changed", observer); -} - -add_task(function* test_disable() { - let dialog = openExceptionsDialog(); - let promiseChanged = promiseStorageChanged("hostSavingDisabled"); - - yield BrowserTestUtils.waitForEvent(dialog, "load"); - Services.logins.setLoginSavingEnabled(LOGIN_HOST, false); - yield promiseChanged; - is(countDisabledHosts(dialog), 1, "Verify disabled host added"); - yield BrowserTestUtils.closeWindow(dialog); -}); - -add_task(function* test_enable() { - let dialog = openExceptionsDialog(); - let promiseChanged = promiseStorageChanged("hostSavingEnabled"); - - yield BrowserTestUtils.waitForEvent(dialog, "load"); - Services.logins.setLoginSavingEnabled(LOGIN_HOST, true); - yield promiseChanged; - is(countDisabledHosts(dialog), 0, "Verify disabled host removed"); - yield BrowserTestUtils.closeWindow(dialog); -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_formless_submit_chrome.js b/toolkit/components/passwordmgr/test/browser/browser_formless_submit_chrome.js deleted file mode 100644 index c6d9ce50a..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_formless_submit_chrome.js +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Test that browser chrome UI interactions don't trigger a capture doorhanger. - */ - -"use strict"; - -function* fillTestPage(aBrowser) { - yield ContentTask.spawn(aBrowser, null, function*() { - content.document.getElementById("form-basic-username").value = "my_username"; - content.document.getElementById("form-basic-password").value = "my_password"; - }); - info("fields filled"); -} - -function* withTestPage(aTaskFn) { - return BrowserTestUtils.withNewTab({ - gBrowser, - url: "https://example.com" + DIRECTORY_PATH + "formless_basic.html", - }, function*(aBrowser) { - info("tab opened"); - yield fillTestPage(aBrowser); - yield* aTaskFn(aBrowser); - - // Give a chance for the doorhanger to appear - yield new Promise(resolve => SimpleTest.executeSoon(resolve)); - ok(!getCaptureDoorhanger("any"), "No doorhanger should be present"); - }); -} - -add_task(function* setup() { - yield SimpleTest.promiseFocus(window); -}); - -add_task(function* test_urlbar_new_URL() { - yield withTestPage(function*(aBrowser) { - gURLBar.value = ""; - let focusPromise = BrowserTestUtils.waitForEvent(gURLBar, "focus"); - gURLBar.focus(); - yield focusPromise; - info("focused"); - EventUtils.sendString("http://mochi.test:8888/"); - EventUtils.synthesizeKey("VK_RETURN", {}); - yield BrowserTestUtils.browserLoaded(aBrowser, false, "http://mochi.test:8888/"); - }); -}); - -add_task(function* test_urlbar_fragment_enter() { - yield withTestPage(function*(aBrowser) { - gURLBar.focus(); - EventUtils.synthesizeKey("VK_RIGHT", {}); - EventUtils.sendString("#fragment"); - EventUtils.synthesizeKey("VK_RETURN", {}); - }); -}); - -add_task(function* test_backButton_forwardButton() { - yield withTestPage(function*(aBrowser) { - // Load a new page in the tab so we can test going back - aBrowser.loadURI("https://example.com" + DIRECTORY_PATH + "formless_basic.html?second"); - yield BrowserTestUtils.browserLoaded(aBrowser, false, - "https://example.com" + DIRECTORY_PATH + - "formless_basic.html?second"); - yield fillTestPage(aBrowser); - - let forwardButton = document.getElementById("forward-button"); - // We need to wait for the forward button transition to complete before we - // can click it, so we hook up a listener to wait for it to be ready. - let forwardTransitionPromise = BrowserTestUtils.waitForEvent(forwardButton, "transitionend"); - - let backPromise = BrowserTestUtils.browserStopped(aBrowser); - EventUtils.synthesizeMouseAtCenter(document.getElementById("back-button"), {}); - yield backPromise; - - // Give a chance for the doorhanger to appear - yield new Promise(resolve => SimpleTest.executeSoon(resolve)); - ok(!getCaptureDoorhanger("any"), "No doorhanger should be present"); - - // Now go forward again after filling - yield fillTestPage(aBrowser); - - yield forwardTransitionPromise; - info("transition done"); - yield BrowserTestUtils.waitForCondition(() => { - return forwardButton.disabled == false; - }); - let forwardPromise = BrowserTestUtils.browserStopped(aBrowser); - info("click the forward button"); - EventUtils.synthesizeMouseAtCenter(forwardButton, {}); - yield forwardPromise; - }); -}); - - -add_task(function* test_reloadButton() { - yield withTestPage(function*(aBrowser) { - let reloadButton = document.getElementById("urlbar-reload-button"); - let loadPromise = BrowserTestUtils.browserLoaded(aBrowser, false, - "https://example.com" + DIRECTORY_PATH + - "formless_basic.html"); - - yield BrowserTestUtils.waitForCondition(() => { - return reloadButton.disabled == false; - }); - EventUtils.synthesizeMouseAtCenter(reloadButton, {}); - yield loadPromise; - }); -}); - -add_task(function* test_back_keyboard_shortcut() { - if (Services.prefs.getIntPref("browser.backspace_action") != 0) { - ok(true, "Skipped testing backspace to go back since it's disabled"); - return; - } - yield withTestPage(function*(aBrowser) { - // Load a new page in the tab so we can test going back - aBrowser.loadURI("https://example.com" + DIRECTORY_PATH + "formless_basic.html?second"); - yield BrowserTestUtils.browserLoaded(aBrowser, false, - "https://example.com" + DIRECTORY_PATH + - "formless_basic.html?second"); - yield fillTestPage(aBrowser); - - let backPromise = BrowserTestUtils.browserStopped(aBrowser); - EventUtils.synthesizeKey("VK_BACK_SPACE", {}); - yield backPromise; - }); -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_hasInsecureLoginForms.js b/toolkit/components/passwordmgr/test/browser/browser_hasInsecureLoginForms.js deleted file mode 100644 index 039312b7d..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_hasInsecureLoginForms.js +++ /dev/null @@ -1,93 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -Cu.import("resource://gre/modules/LoginManagerParent.jsm", this); - -const testUrlPath = - "://example.com/browser/toolkit/components/passwordmgr/test/browser/"; - -/** - * Waits for the given number of occurrences of InsecureLoginFormsStateChange - * on the given browser element. - */ -function waitForInsecureLoginFormsStateChange(browser, count) { - return BrowserTestUtils.waitForEvent(browser, "InsecureLoginFormsStateChange", - false, () => --count == 0); -} - -/** - * Checks that hasInsecureLoginForms is true for a simple HTTP page and false - * for a simple HTTPS page. - */ -add_task(function* test_simple() { - for (let scheme of ["http", "https"]) { - let tab = gBrowser.addTab(scheme + testUrlPath + "form_basic.html"); - let browser = tab.linkedBrowser; - yield Promise.all([ - BrowserTestUtils.switchTab(gBrowser, tab), - BrowserTestUtils.browserLoaded(browser), - // One event is triggered by pageshow and one by DOMFormHasPassword. - waitForInsecureLoginFormsStateChange(browser, 2), - ]); - - Assert.equal(LoginManagerParent.hasInsecureLoginForms(browser), - scheme == "http"); - - gBrowser.removeTab(tab); - } -}); - -/** - * Checks that hasInsecureLoginForms is true if a password field is present in - * an HTTP page loaded as a subframe of a top-level HTTPS page, when mixed - * active content blocking is disabled. - * - * When the subframe is navigated to an HTTPS page, hasInsecureLoginForms should - * be set to false. - * - * Moving back in history should set hasInsecureLoginForms to true again. - */ -add_task(function* test_subframe_navigation() { - yield new Promise(resolve => SpecialPowers.pushPrefEnv({ - "set": [["security.mixed_content.block_active_content", false]], - }, resolve)); - - // Load the page with the subframe in a new tab. - let tab = gBrowser.addTab("https" + testUrlPath + "insecure_test.html"); - let browser = tab.linkedBrowser; - yield Promise.all([ - BrowserTestUtils.switchTab(gBrowser, tab), - BrowserTestUtils.browserLoaded(browser), - // Two events are triggered by pageshow and one by DOMFormHasPassword. - waitForInsecureLoginFormsStateChange(browser, 3), - ]); - - Assert.ok(LoginManagerParent.hasInsecureLoginForms(browser)); - - // Navigate the subframe to a secure page. - let promiseSubframeReady = Promise.all([ - BrowserTestUtils.browserLoaded(browser, true), - // One event is triggered by pageshow and one by DOMFormHasPassword. - waitForInsecureLoginFormsStateChange(browser, 2), - ]); - yield ContentTask.spawn(browser, null, function* () { - content.document.getElementById("test-iframe") - .contentDocument.getElementById("test-link").click(); - }); - yield promiseSubframeReady; - - Assert.ok(!LoginManagerParent.hasInsecureLoginForms(browser)); - - // Navigate back to the insecure page. We only have to wait for the - // InsecureLoginFormsStateChange event that is triggered by pageshow. - let promise = waitForInsecureLoginFormsStateChange(browser, 1); - yield ContentTask.spawn(browser, null, function* () { - content.document.getElementById("test-iframe") - .contentWindow.history.back(); - }); - yield promise; - - Assert.ok(LoginManagerParent.hasInsecureLoginForms(browser)); - - gBrowser.removeTab(tab); -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_hasInsecureLoginForms_streamConverter.js b/toolkit/components/passwordmgr/test/browser/browser_hasInsecureLoginForms_streamConverter.js deleted file mode 100644 index 2dbffb9cc..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_hasInsecureLoginForms_streamConverter.js +++ /dev/null @@ -1,102 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -Cu.import("resource://gre/modules/LoginManagerParent.jsm", this); - -function* registerConverter() { - Cu.import("resource://gre/modules/Services.jsm", this); - Cu.import("resource://gre/modules/NetUtil.jsm", this); - - /** - * Converts the "test/content" MIME type, served by the test over HTTP, to an - * HTML viewer page containing the "form_basic.html" code. The viewer is - * served from a "resource:" URI while keeping the "resource:" principal. - */ - function TestStreamConverter() {} - - TestStreamConverter.prototype = { - classID: Components.ID("{5f01d6ef-c090-45a4-b3e5-940d64713eb7}"), - contractID: "@mozilla.org/streamconv;1?from=test/content&to=*/*", - QueryInterface: XPCOMUtils.generateQI([ - Ci.nsIRequestObserver, - Ci.nsIStreamListener, - Ci.nsIStreamConverter, - ]), - - // nsIStreamConverter - convert() {}, - - // nsIStreamConverter - asyncConvertData(aFromType, aToType, aListener, aCtxt) { - this.listener = aListener; - }, - - // nsIRequestObserver - onStartRequest(aRequest, aContext) { - let channel = NetUtil.newChannel({ - uri: "resource://testing-common/form_basic.html", - loadUsingSystemPrincipal: true, - }); - channel.originalURI = aRequest.QueryInterface(Ci.nsIChannel).URI; - channel.loadGroup = aRequest.loadGroup; - channel.owner = Services.scriptSecurityManager - .createCodebasePrincipal(channel.URI, {}); - // In this test, we pass the new channel to the listener but don't fire a - // redirect notification, even if it would be required. This keeps the - // test code simpler and doesn't impact the principal check we're testing. - channel.asyncOpen2(this.listener); - }, - - // nsIRequestObserver - onStopRequest() {}, - - // nsIStreamListener - onDataAvailable() {}, - }; - - let factory = XPCOMUtils._getFactory(TestStreamConverter); - let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); - registrar.registerFactory(TestStreamConverter.prototype.classID, "", - TestStreamConverter.prototype.contractID, factory); - this.cleanupFunction = function () { - registrar.unregisterFactory(TestStreamConverter.prototype.classID, factory); - }; -} - -/** - * Waits for the given number of occurrences of InsecureLoginFormsStateChange - * on the given browser element. - */ -function waitForInsecureLoginFormsStateChange(browser, count) { - return BrowserTestUtils.waitForEvent(browser, "InsecureLoginFormsStateChange", - false, () => --count == 0); -} - -/** - * Checks that hasInsecureLoginForms is false for a viewer served internally - * using a "resource:" URI. - */ -add_task(function* test_streamConverter() { - let originalBrowser = gBrowser.selectedTab.linkedBrowser; - - yield ContentTask.spawn(originalBrowser, null, registerConverter); - - let tab = gBrowser.addTab("http://example.com/browser/toolkit/components/" + - "passwordmgr/test/browser/streamConverter_content.sjs", - { relatedBrowser: originalBrowser.linkedBrowser }); - let browser = tab.linkedBrowser; - yield Promise.all([ - BrowserTestUtils.switchTab(gBrowser, tab), - BrowserTestUtils.browserLoaded(browser), - // One event is triggered by pageshow and one by DOMFormHasPassword. - waitForInsecureLoginFormsStateChange(browser, 2), - ]); - - Assert.ok(!LoginManagerParent.hasInsecureLoginForms(browser)); - - yield BrowserTestUtils.removeTab(tab); - - yield ContentTask.spawn(originalBrowser, null, function* () { - this.cleanupFunction(); - }); -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_http_autofill.js b/toolkit/components/passwordmgr/test/browser/browser_http_autofill.js deleted file mode 100644 index beb928a34..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_http_autofill.js +++ /dev/null @@ -1,78 +0,0 @@ -const TEST_URL_PATH = "://example.org/browser/toolkit/components/passwordmgr/test/browser/"; - -add_task(function* setup() { - let login = LoginTestUtils.testData.formLogin({ - hostname: "http://example.org", - formSubmitURL: "http://example.org", - username: "username", - password: "password", - }); - Services.logins.addLogin(login); - login = LoginTestUtils.testData.formLogin({ - hostname: "http://example.org", - formSubmitURL: "http://another.domain", - username: "username", - password: "password", - }); - Services.logins.addLogin(login); - yield SpecialPowers.pushPrefEnv({ "set": [["signon.autofillForms.http", false]] }); -}); - -add_task(function* test_http_autofill() { - for (let scheme of ["http", "https"]) { - let tab = yield BrowserTestUtils - .openNewForegroundTab(gBrowser, `${scheme}${TEST_URL_PATH}form_basic.html`); - - let [username, password] = yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () { - let doc = content.document; - let contentUsername = doc.getElementById("form-basic-username").value; - let contentPassword = doc.getElementById("form-basic-password").value; - return [contentUsername, contentPassword]; - }); - - is(username, scheme == "http" ? "" : "username", "Username filled correctly"); - is(password, scheme == "http" ? "" : "password", "Password filled correctly"); - - gBrowser.removeTab(tab); - } -}); - -add_task(function* test_iframe_in_http_autofill() { - for (let scheme of ["http", "https"]) { - let tab = yield BrowserTestUtils - .openNewForegroundTab(gBrowser, `${scheme}${TEST_URL_PATH}form_basic_iframe.html`); - - let [username, password] = yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () { - let doc = content.document; - let iframe = doc.getElementById("test-iframe"); - let contentUsername = iframe.contentWindow.document.getElementById("form-basic-username").value; - let contentPassword = iframe.contentWindow.document.getElementById("form-basic-password").value; - return [contentUsername, contentPassword]; - }); - - is(username, scheme == "http" ? "" : "username", "Username filled correctly"); - is(password, scheme == "http" ? "" : "password", "Password filled correctly"); - - gBrowser.removeTab(tab); - } -}); - -add_task(function* test_http_action_autofill() { - for (let type of ["insecure", "secure"]) { - let tab = yield BrowserTestUtils - .openNewForegroundTab(gBrowser, `https${TEST_URL_PATH}form_cross_origin_${type}_action.html`); - - let [username, password] = yield ContentTask.spawn(gBrowser.selectedBrowser, null, function* () { - let doc = content.document; - let contentUsername = doc.getElementById("form-basic-username").value; - let contentPassword = doc.getElementById("form-basic-password").value; - return [contentUsername, contentPassword]; - }); - - is(username, type == "insecure" ? "" : "username", "Username filled correctly"); - is(password, type == "insecure" ? "" : "password", "Password filled correctly"); - - gBrowser.removeTab(tab); - } -}); - diff --git a/toolkit/components/passwordmgr/test/browser/browser_insecurePasswordConsoleWarning.js b/toolkit/components/passwordmgr/test/browser/browser_insecurePasswordConsoleWarning.js deleted file mode 100644 index f16ae1b98..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_insecurePasswordConsoleWarning.js +++ /dev/null @@ -1,94 +0,0 @@ -"use strict"; - -const WARNING_PATTERN = [{ - key: "INSECURE_FORM_ACTION", - msg: 'JavaScript Warning: "Password fields present in a form with an insecure (http://) form action. This is a security risk that allows user login credentials to be stolen."' -}, { - key: "INSECURE_PAGE", - msg: 'JavaScript Warning: "Password fields present on an insecure (http://) page. This is a security risk that allows user login credentials to be stolen."' -}]; - -add_task(function* testInsecurePasswordWarning() { - let warningPatternHandler; - - function messageHandler(msgObj) { - function findWarningPattern(msg) { - return WARNING_PATTERN.find(patternPair => { - return msg.indexOf(patternPair.msg) !== -1; - }); - } - - let warning = findWarningPattern(msgObj.message); - - // Only handle the insecure password related warning messages. - if (warning) { - // Prevent any unexpected or redundant matched warning message coming after - // the test case is ended. - ok(warningPatternHandler, "Invoke a valid warning message handler"); - warningPatternHandler(warning, msgObj.message); - } - } - Services.console.registerListener(messageHandler); - registerCleanupFunction(function() { - Services.console.unregisterListener(messageHandler); - }); - - for (let [origin, testFile, expectWarnings] of [ - ["http://127.0.0.1", "form_basic.html", []], - ["http://127.0.0.1", "formless_basic.html", []], - ["http://example.com", "form_basic.html", ["INSECURE_PAGE"]], - ["http://example.com", "formless_basic.html", ["INSECURE_PAGE"]], - ["https://example.com", "form_basic.html", []], - ["https://example.com", "formless_basic.html", []], - - // For a form with customized action link in the same origin. - ["http://127.0.0.1", "form_same_origin_action.html", []], - ["http://example.com", "form_same_origin_action.html", ["INSECURE_PAGE"]], - ["https://example.com", "form_same_origin_action.html", []], - - // For a form with an insecure (http) customized action link. - ["http://127.0.0.1", "form_cross_origin_insecure_action.html", ["INSECURE_FORM_ACTION"]], - ["http://example.com", "form_cross_origin_insecure_action.html", ["INSECURE_PAGE"]], - ["https://example.com", "form_cross_origin_insecure_action.html", ["INSECURE_FORM_ACTION"]], - - // For a form with a secure (https) customized action link. - ["http://127.0.0.1", "form_cross_origin_secure_action.html", []], - ["http://example.com", "form_cross_origin_secure_action.html", ["INSECURE_PAGE"]], - ["https://example.com", "form_cross_origin_secure_action.html", []], - ]) { - let testURL = origin + DIRECTORY_PATH + testFile; - let promiseConsoleMessages = new Promise(resolve => { - warningPatternHandler = function (warning, originMessage) { - ok(warning, "Handling a warning pattern"); - let fullMessage = `[${warning.msg} {file: "${testURL}" line: 0 column: 0 source: "0"}]`; - is(originMessage, fullMessage, "Message full matched:" + originMessage); - - let index = expectWarnings.indexOf(warning.key); - isnot(index, -1, "Found warning: " + warning.key + " for URL:" + testURL); - if (index !== -1) { - // Remove the shown message. - expectWarnings.splice(index, 1); - } - if (expectWarnings.length === 0) { - info("All warnings are shown for URL:" + testURL); - resolve(); - } - }; - }); - - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: testURL - }, function*() { - if (expectWarnings.length === 0) { - info("All warnings are shown for URL:" + testURL); - return Promise.resolve(); - } - return promiseConsoleMessages; - }); - - // Remove warningPatternHandler to stop handling the matched warning pattern - // and the task should not get any warning anymore. - warningPatternHandler = null; - } -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_master_password_autocomplete.js b/toolkit/components/passwordmgr/test/browser/browser_master_password_autocomplete.js deleted file mode 100644 index f3bc62b0a..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_master_password_autocomplete.js +++ /dev/null @@ -1,59 +0,0 @@ -const HOST = "https://example.com"; -const URL = HOST + "/browser/toolkit/components/passwordmgr/test/browser/form_basic.html"; -const TIMEOUT_PREF = "signon.masterPasswordReprompt.timeout_ms"; - -// Waits for the master password prompt and cancels it. -function waitForDialog() { - let dialogShown = TestUtils.topicObserved("common-dialog-loaded"); - return dialogShown.then(function([subject]) { - let dialog = subject.Dialog; - is(dialog.args.title, "Password Required"); - dialog.ui.button1.click(); - }); -} - -// Test that autocomplete does not trigger a master password prompt -// for a certain time after it was cancelled. -add_task(function* test_mpAutocompleteTimeout() { - let login = LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username: "username", - password: "password", - }); - Services.logins.addLogin(login); - LoginTestUtils.masterPassword.enable(); - - registerCleanupFunction(function() { - LoginTestUtils.masterPassword.disable(); - Services.logins.removeAllLogins(); - }); - - // Set master password prompt timeout to 3s. - // If this test goes intermittent, you likely have to increase this value. - yield SpecialPowers.pushPrefEnv({set: [[TIMEOUT_PREF, 3000]]}); - - // Wait for initial master password dialog after opening the tab. - let dialogShown = waitForDialog(); - - yield BrowserTestUtils.withNewTab(URL, function*(browser) { - yield dialogShown; - - yield ContentTask.spawn(browser, null, function*() { - // Focus the password field to trigger autocompletion. - content.document.getElementById("form-basic-password").focus(); - }); - - // Wait 4s, dialog should not have been shown - // (otherwise the code below will not work). - yield new Promise((c) => setTimeout(c, 4000)); - - dialogShown = waitForDialog(); - yield ContentTask.spawn(browser, null, function*() { - // Re-focus the password field to trigger autocompletion. - content.document.getElementById("form-basic-username").focus(); - content.document.getElementById("form-basic-password").focus(); - }); - yield dialogShown; - }); -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_notifications.js b/toolkit/components/passwordmgr/test/browser/browser_notifications.js deleted file mode 100644 index 4fb012f14..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_notifications.js +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Test that the doorhanger notification for password saving is populated with - * the correct values in various password capture cases. - */ -add_task(function* test_save_change() { - let testCases = [{ - username: "username", - password: "password", - }, { - username: "", - password: "password", - }, { - username: "username", - oldPassword: "password", - password: "newPassword", - }, { - username: "", - oldPassword: "password", - password: "newPassword", - }]; - - for (let { username, oldPassword, password } of testCases) { - // Add a login for the origin of the form if testing a change notification. - if (oldPassword) { - Services.logins.addLogin(LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username, - password: oldPassword, - })); - } - - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "https://example.com/browser/toolkit/components/" + - "passwordmgr/test/browser/form_basic.html", - }, 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); - yield ContentTask.spawn(browser, [username, password], - 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(); - }); - yield promiseShown; - let notificationElement = PopupNotifications.panel.childNodes[0]; - // Style flush to make sure binding is attached - notificationElement.querySelector("#password-notification-password").clientTop; - - // Check the actual content of the popup notification. - Assert.equal(notificationElement.querySelector("#password-notification-username") - .value, username); - Assert.equal(notificationElement.querySelector("#password-notification-password") - .value, password); - - // Simulate the action on the notification to request the login to be - // saved, and wait for the data to be updated or saved based on the type - // of operation we expect. - let expectedNotification = oldPassword ? "modifyLogin" : "addLogin"; - let promiseLogin = TestUtils.topicObserved("passwordmgr-storage-changed", - (_, data) => data == expectedNotification); - notificationElement.button.doCommand(); - let [result] = yield promiseLogin; - - // Check that the values in the database match the expected values. - let login = oldPassword ? result.QueryInterface(Ci.nsIArray) - .queryElementAt(1, Ci.nsILoginInfo) - : result.QueryInterface(Ci.nsILoginInfo); - Assert.equal(login.username, username); - Assert.equal(login.password, password); - }); - - // Clean up the database before the next test case is executed. - Services.logins.removeAllLogins(); - } -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_notifications_2.js b/toolkit/components/passwordmgr/test/browser/browser_notifications_2.js deleted file mode 100644 index 48c73b0e6..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_notifications_2.js +++ /dev/null @@ -1,125 +0,0 @@ -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({"set": [ - ["signon.rememberSignons.visibilityToggle", true] - ]}); -}); - -/** - * Test that the doorhanger main action button is disabled - * when the password field is empty. - * - * Also checks that submiting an empty password throws an error. - */ -add_task(function* test_empty_password() { - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "https://example.com/browser/toolkit/components/" + - "passwordmgr/test/browser/form_basic.html", - }, 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); - yield ContentTask.spawn(browser, null, - function* () { - let doc = content.document; - doc.getElementById("form-basic-username").value = "username"; - doc.getElementById("form-basic-password").value = "p"; - doc.getElementById("form-basic").submit(); - }); - yield promiseShown; - - 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(); - yield EventUtils.synthesizeKey("VK_RIGHT", {}); - yield EventUtils.synthesizeKey("VK_BACK_SPACE", {}); - - let mainActionButton = document.getAnonymousElementByAttribute(notificationElement.button, "anonid", "button"); - Assert.ok(mainActionButton.disabled, "Main action button is disabled"); - - // Makes sure submiting an empty password throws an error - Assert.throws(notificationElement.button.doCommand(), - "Can't add a login with a null or empty password.", - "Should fail for an empty password"); - }); -}); - -/** - * Test that the doorhanger password field shows plain or * text - * when the checkbox is checked. - */ -add_task(function* test_toggle_password() { - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "https://example.com/browser/toolkit/components/" + - "passwordmgr/test/browser/form_basic.html", - }, 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); - yield ContentTask.spawn(browser, null, - function* () { - let doc = content.document; - doc.getElementById("form-basic-username").value = "username"; - doc.getElementById("form-basic-password").value = "p"; - doc.getElementById("form-basic").submit(); - }); - yield promiseShown; - - let notificationElement = PopupNotifications.panel.childNodes[0]; - let passwordTextbox = notificationElement.querySelector("#password-notification-password"); - let toggleCheckbox = notificationElement.querySelector("#password-notification-visibilityToggle"); - - yield EventUtils.synthesizeMouseAtCenter(toggleCheckbox, {}); - Assert.ok(toggleCheckbox.checked); - Assert.equal(passwordTextbox.type, "", "Password textbox changed to plain text"); - - yield EventUtils.synthesizeMouseAtCenter(toggleCheckbox, {}); - Assert.ok(!toggleCheckbox.checked); - Assert.equal(passwordTextbox.type, "password", "Password textbox changed to * text"); - }); -}); - -/** - * Test that the doorhanger password toggle checkbox is disabled - * when the master password is set. - */ -add_task(function* test_checkbox_disabled_if_has_master_password() { - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "https://example.com/browser/toolkit/components/" + - "passwordmgr/test/browser/form_basic.html", - }, 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(); - - yield ContentTask.spawn(browser, null, function* () { - let doc = content.document; - doc.getElementById("form-basic-username").value = "username"; - doc.getElementById("form-basic-password").value = "p"; - doc.getElementById("form-basic").submit(); - }); - yield 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(); -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_notifications_password.js b/toolkit/components/passwordmgr/test/browser/browser_notifications_password.js deleted file mode 100644 index 8ac49dac5..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_notifications_password.js +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Test changing the password inside the doorhanger notification for passwords. - * - * We check the following cases: - * - Editing the password of a new login. - * - Editing the password of an existing login. - * - Changing both username and password to an existing login. - * - Changing the username to an existing login. - * - Editing username to an empty one and a new password. - * - * If both the username and password matches an already existing login, we should not - * update it's password, but only it's usage timestamp and count. - */ -add_task(function* test_edit_password() { - let testCases = [{ - usernameInPage: "username", - passwordInPage: "password", - passwordChangedTo: "newPassword", - timesUsed: 1, - }, { - usernameInPage: "username", - usernameInPageExists: true, - passwordInPage: "password", - passwordInStorage: "oldPassword", - passwordChangedTo: "newPassword", - timesUsed: 2, - }, { - usernameInPage: "username", - usernameChangedTo: "newUsername", - usernameChangedToExists: true, - passwordInPage: "password", - passwordChangedTo: "newPassword", - timesUsed: 2, - }, { - usernameInPage: "username", - usernameChangedTo: "newUsername", - usernameChangedToExists: true, - passwordInPage: "password", - passwordChangedTo: "password", - timesUsed: 2, - checkPasswordNotUpdated: true, - }, { - usernameInPage: "newUsername", - usernameChangedTo: "", - usernameChangedToExists: true, - passwordInPage: "password", - passwordChangedTo: "newPassword", - timesUsed: 2, - }]; - - for (let testCase of testCases) { - info("Test case: " + JSON.stringify(testCase)); - - // Create the pre-existing logins when needed. - if (testCase.usernameInPageExists) { - Services.logins.addLogin(LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username: testCase.usernameInPage, - password: testCase.passwordInStorage, - })); - } - - if (testCase.usernameChangedToExists) { - Services.logins.addLogin(LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username: testCase.usernameChangedTo, - password: testCase.passwordChangedTo, - })); - } - - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "https://example.com/browser/toolkit/components/" + - "passwordmgr/test/browser/form_basic.html", - }, 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); - yield ContentTask.spawn(browser, testCase, - 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(); - }); - yield promiseShown; - let notificationElement = PopupNotifications.panel.childNodes[0]; - // Style flush to make sure binding is attached - notificationElement.querySelector("#password-notification-password").clientTop; - - // Modify the username in the dialog if requested. - if (testCase.usernameChangedTo) { - notificationElement.querySelector("#password-notification-username") - .value = testCase.usernameChangedTo; - } - - // Modify the password in the dialog if requested. - if (testCase.passwordChangedTo) { - notificationElement.querySelector("#password-notification-password") - .value = testCase.passwordChangedTo; - } - - // We expect a modifyLogin notification if the final username used by the - // dialog exists in the logins database, otherwise an addLogin one. - let expectModifyLogin = typeof testCase.usernameChangedTo !== "undefined" - ? testCase.usernameChangedToExists - : testCase.usernameInPageExists; - - // Simulate the action on the notification to request the login to be - // saved, and wait for the data to be updated or saved based on the type - // of operation we expect. - let expectedNotification = expectModifyLogin ? "modifyLogin" : "addLogin"; - let promiseLogin = TestUtils.topicObserved("passwordmgr-storage-changed", - (_, data) => data == expectedNotification); - notificationElement.button.doCommand(); - let [result] = yield promiseLogin; - - // Check that the values in the database match the expected values. - let login = expectModifyLogin ? result.QueryInterface(Ci.nsIArray) - .queryElementAt(1, Ci.nsILoginInfo) - : result.QueryInterface(Ci.nsILoginInfo); - - Assert.equal(login.username, testCase.usernameChangedTo || - testCase.usernameInPage); - Assert.equal(login.password, testCase.passwordChangedTo || - testCase.passwordInPage); - - let meta = login.QueryInterface(Ci.nsILoginMetaInfo); - Assert.equal(meta.timesUsed, testCase.timesUsed); - - // Check that the password was not updated if the user is empty - if (testCase.checkPasswordNotUpdated) { - Assert.ok(meta.timeLastUsed > meta.timeCreated); - Assert.ok(meta.timeCreated == meta.timePasswordChanged); - } - }); - - // Clean up the database before the next test case is executed. - Services.logins.removeAllLogins(); - } -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_notifications_username.js b/toolkit/components/passwordmgr/test/browser/browser_notifications_username.js deleted file mode 100644 index 2c9ea2607..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_notifications_username.js +++ /dev/null @@ -1,119 +0,0 @@ -/** - * Test changing the username inside the doorhanger notification for passwords. - * - * We have to test combination of existing and non-existing logins both for - * the original one from the webpage and the final one used by the dialog. - * - * We also check switching to and from empty usernames. - */ -add_task(function* test_edit_username() { - let testCases = [{ - usernameInPage: "username", - usernameChangedTo: "newUsername", - }, { - usernameInPage: "username", - usernameInPageExists: true, - usernameChangedTo: "newUsername", - }, { - usernameInPage: "username", - usernameChangedTo: "newUsername", - usernameChangedToExists: true, - }, { - usernameInPage: "username", - usernameInPageExists: true, - usernameChangedTo: "newUsername", - usernameChangedToExists: true, - }, { - usernameInPage: "", - usernameChangedTo: "newUsername", - }, { - usernameInPage: "newUsername", - usernameChangedTo: "", - }, { - usernameInPage: "", - usernameChangedTo: "newUsername", - usernameChangedToExists: true, - }, { - usernameInPage: "newUsername", - usernameChangedTo: "", - usernameChangedToExists: true, - }]; - - for (let testCase of testCases) { - info("Test case: " + JSON.stringify(testCase)); - - // Create the pre-existing logins when needed. - if (testCase.usernameInPageExists) { - Services.logins.addLogin(LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username: testCase.usernameInPage, - password: "old password", - })); - } - - if (testCase.usernameChangedToExists) { - Services.logins.addLogin(LoginTestUtils.testData.formLogin({ - hostname: "https://example.com", - formSubmitURL: "https://example.com", - username: testCase.usernameChangedTo, - password: "old password", - })); - } - - yield BrowserTestUtils.withNewTab({ - gBrowser, - url: "https://example.com/browser/toolkit/components/" + - "passwordmgr/test/browser/form_basic.html", - }, 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); - yield ContentTask.spawn(browser, testCase.usernameInPage, - 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(); - }); - yield promiseShown; - let notificationElement = PopupNotifications.panel.childNodes[0]; - // Style flush to make sure binding is attached - notificationElement.querySelector("#password-notification-password").clientTop; - - // Modify the username in the dialog if requested. - if (testCase.usernameChangedTo) { - notificationElement.querySelector("#password-notification-username") - .value = testCase.usernameChangedTo; - } - - // We expect a modifyLogin notification if the final username used by the - // dialog exists in the logins database, otherwise an addLogin one. - let expectModifyLogin = testCase.usernameChangedTo - ? testCase.usernameChangedToExists - : testCase.usernameInPageExists; - - // Simulate the action on the notification to request the login to be - // saved, and wait for the data to be updated or saved based on the type - // of operation we expect. - let expectedNotification = expectModifyLogin ? "modifyLogin" : "addLogin"; - let promiseLogin = TestUtils.topicObserved("passwordmgr-storage-changed", - (_, data) => data == expectedNotification); - notificationElement.button.doCommand(); - let [result] = yield promiseLogin; - - // Check that the values in the database match the expected values. - let login = expectModifyLogin ? result.QueryInterface(Ci.nsIArray) - .queryElementAt(1, Ci.nsILoginInfo) - : result.QueryInterface(Ci.nsILoginInfo); - Assert.equal(login.username, testCase.usernameChangedTo || - testCase.usernameInPage); - Assert.equal(login.password, "password"); - }); - - // Clean up the database before the next test case is executed. - Services.logins.removeAllLogins(); - } -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_contextmenu.js b/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_contextmenu.js deleted file mode 100644 index ece2b731f..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_contextmenu.js +++ /dev/null @@ -1,100 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -function test() { - waitForExplicitFinish(); - - Services.logins.removeAllLogins(); - - // Add some initial logins - let urls = [ - "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") - ]; - logins.forEach(login => 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); - - // 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"); - - function copyField() { - info("Select all"); - selection.selectAll(); - 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("copyusername", false, "empty username"); - assertMenuitemEnabled("editusername", true); - assertMenuitemEnabled("copypassword", true); - assertMenuitemEnabled("editpassword", false, "password column hidden"); - - info("Clear the selection"); - selection.clearSelection(); - 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("copyusername", true); - assertMenuitemEnabled("editusername", true); - assertMenuitemEnabled("copypassword", true); - assertMenuitemEnabled("editpassword", true, "password column visible"); - 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 cleanUp() { - Services.ww.registerNotification(function (aSubject, aTopic, aData) { - Services.ww.unregisterNotification(arguments.callee); - Services.logins.removeAllLogins(); - doc.getElementById("passwordCol").hidden = true; - finish(); - }); - pwmgrdlg.close(); - } - - function testPassword() { - info("Testing Copy Password"); - waitForClipboard("coded", function copyPassword() { - menuitem = doc.getElementById("context-copypassword"); - menuitem.doCommand(); - }, cleanUp, cleanUp); - } - - info("Testing Copy Username"); - waitForClipboard("ehsan", copyField, testPassword, testPassword); - } -} diff --git a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_editing.js b/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_editing.js deleted file mode 100644 index 2b2e42273..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_editing.js +++ /dev/null @@ -1,126 +0,0 @@ -const { ContentTaskUtils } = Cu.import("resource://testing-common/ContentTaskUtils.jsm", {}); -const PWMGR_DLG = "chrome://passwordmgr/content/passwordManager.xul"; - -var doc; -var pwmgr; -var pwmgrdlg; -var signonsTree; - -function addLogin(site, username, password) { - let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); - let login = new nsLoginInfo(site, site, null, username, password, "u", "p"); - Services.logins.addLogin(login); -} - -function getUsername(row) { - return signonsTree.view.getCellText(row, signonsTree.columns.getNamedColumn("userCol")); -} - -function getPassword(row) { - return signonsTree.view.getCellText(row, signonsTree.columns.getNamedColumn("passwordCol")); -} - -function synthesizeDblClickOnCell(aTree, column, row) { - let tbo = aTree.treeBoxObject; - let rect = tbo.getCoordsForCellItem(row, aTree.columns[column], "text"); - let x = rect.x + rect.width / 2; - let y = rect.y + rect.height / 2; - // Simulate the double click. - EventUtils.synthesizeMouse(aTree.body, x, y, { clickCount: 2 }, - aTree.ownerDocument.defaultView); -} - -function* togglePasswords() { - pwmgrdlg.document.querySelector("#togglePasswords").doCommand(); - yield new Promise(resolve => waitForFocus(resolve, pwmgrdlg)); -} - -function* editUsernamePromises(site, oldUsername, newUsername) { - is(Services.logins.findLogins({}, site, "", "").length, 1, "Correct login found"); - let login = Services.logins.findLogins({}, site, "", "")[0]; - is(login.username, oldUsername, "Correct username saved"); - is(getUsername(0), oldUsername, "Correct username shown"); - synthesizeDblClickOnCell(signonsTree, 1, 0); - yield ContentTaskUtils.waitForCondition(() => signonsTree.getAttribute("editing"), - "Waiting for editing"); - - EventUtils.sendString(newUsername, pwmgrdlg); - let signonsIntro = doc.querySelector("#signonsIntro"); - EventUtils.sendMouseEvent({type: "click"}, signonsIntro, pwmgrdlg); - yield ContentTaskUtils.waitForCondition(() => !signonsTree.getAttribute("editing"), - "Waiting for editing to stop"); - - is(Services.logins.findLogins({}, site, "", "").length, 1, "Correct login replaced"); - login = Services.logins.findLogins({}, site, "", "")[0]; - is(login.username, newUsername, "Correct username updated"); - is(getUsername(0), newUsername, "Correct username shown after the update"); -} - -function* editPasswordPromises(site, oldPassword, newPassword) { - is(Services.logins.findLogins({}, site, "", "").length, 1, "Correct login found"); - let login = Services.logins.findLogins({}, site, "", "")[0]; - is(login.password, oldPassword, "Correct password saved"); - is(getPassword(0), oldPassword, "Correct password shown"); - - synthesizeDblClickOnCell(signonsTree, 2, 0); - yield ContentTaskUtils.waitForCondition(() => signonsTree.getAttribute("editing"), - "Waiting for editing"); - - EventUtils.sendString(newPassword, pwmgrdlg); - let signonsIntro = doc.querySelector("#signonsIntro"); - EventUtils.sendMouseEvent({type: "click"}, signonsIntro, pwmgrdlg); - yield ContentTaskUtils.waitForCondition(() => !signonsTree.getAttribute("editing"), - "Waiting for editing to stop"); - - is(Services.logins.findLogins({}, site, "", "").length, 1, "Correct login replaced"); - login = Services.logins.findLogins({}, site, "", "")[0]; - is(login.password, newPassword, "Correct password updated"); - is(getPassword(0), newPassword, "Correct password shown after the update"); -} - -add_task(function* test_setup() { - registerCleanupFunction(function() { - Services.logins.removeAllLogins(); - }); - - Services.logins.removeAllLogins(); - // Open the password manager dialog. - pwmgrdlg = window.openDialog(PWMGR_DLG, "Toolkit:PasswordManager", ""); - - Services.ww.registerNotification(function (aSubject, aTopic, aData) { - if (aTopic == "domwindowopened") { - let win = aSubject.QueryInterface(Ci.nsIDOMEventTarget); - SimpleTest.waitForFocus(function() { - EventUtils.sendKey("RETURN", win); - }, win); - } else if (aSubject.location == pwmgrdlg.location && aTopic == "domwindowclosed") { - // Unregister ourself. - Services.ww.unregisterNotification(arguments.callee); - } - }); - - yield new Promise((resolve) => { - SimpleTest.waitForFocus(() => { - doc = pwmgrdlg.document; - signonsTree = doc.querySelector("#signonsTree"); - resolve(); - }, pwmgrdlg); - }); -}); - -add_task(function* test_edit_multiple_logins() { - function* testLoginChange(site, oldUsername, oldPassword, newUsername, newPassword) { - addLogin(site, oldUsername, oldPassword); - yield* editUsernamePromises(site, oldUsername, newUsername); - yield* togglePasswords(); - yield* editPasswordPromises(site, oldPassword, newPassword); - yield* togglePasswords(); - } - - yield* testLoginChange("http://c.tn/", "userC", "passC", "usernameC", "passwordC"); - yield* testLoginChange("http://b.tn/", "userB", "passB", "usernameB", "passwordB"); - yield* testLoginChange("http://a.tn/", "userA", "passA", "usernameA", "passwordA"); - - pwmgrdlg.close(); -}); diff --git a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_fields.js b/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_fields.js deleted file mode 100644 index 95bcee9ed..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_fields.js +++ /dev/null @@ -1,65 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -function test() { - waitForExplicitFinish(); - - let pwmgr = Cc["@mozilla.org/login-manager;1"]. - getService(Ci.nsILoginManager); - pwmgr.removeAllLogins(); - - // 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"); - pwmgr.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); - - function doTest() { - let doc = pwmgrdlg.document; - - 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("userCol")), - "user", - "Correct user saved"); - - 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 timePasswordChangedCol = doc.getElementById("timePasswordChangedCol"); - is(timePasswordChangedCol.getAttribute("hidden"), "", - "Last Changed column is displayed"); - - // cleanup - Services.ww.registerNotification(function (aSubject, aTopic, aData) { - if (aSubject.location == pwmgrdlg.location && aTopic == "domwindowclosed") { - // unregister ourself - Services.ww.unregisterNotification(arguments.callee); - - pwmgr.removeAllLogins(); - - finish(); - } - }); - - pwmgrdlg.close(); - } -} diff --git a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_observers.js b/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_observers.js deleted file mode 100644 index 1dc7076aa..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_observers.js +++ /dev/null @@ -1,129 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -function test() { - waitForExplicitFinish(); - - 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 logins = []; - let loginCounter = 0; - let loginOrder = null; - let modifiedLogin; - let testNumber = 0; - let testObserver = { - observe: function (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); - } - 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)); - } - 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 startTest() { - Services.obs.addObserver( - testObserver, "passwordmgr-dialog-updated", false); - 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.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", false); - pmDialog.close(); - finish(); - break; - } - } -} diff --git a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_sort.js b/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_sort.js deleted file mode 100644 index 83272a9c4..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_sort.js +++ /dev/null @@ -1,208 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -function test() { - waitForExplicitFinish(); - - let pwmgr = Cc["@mozilla.org/login-manager;1"]. - getService(Ci.nsILoginManager); - pwmgr.removeAllLogins(); - - // 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/", - ]; - let users = [ - "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", - ]; - let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); - for (let i = 0; i < 10; i++) - pwmgr.addLogin(new nsLoginInfo(urls[i], urls[i], null, users[i], pwds[i], - "u" + (i + 1), "p" + (i + 1))); - - // 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); - - // 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 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 (aSubject, aTopic, aData) { - if (aTopic == "domwindowclosed") - Services.ww.unregisterNotification(arguments.callee); - else if (aTopic == "domwindowopened") { - let targetWin = aSubject.QueryInterface(Ci.nsIDOMEventTarget); - SimpleTest.waitForFocus(function() { - EventUtils.sendKey("RETURN", targetWin); - }, targetWin); - } - }); - } - - Services.obs.addObserver(function (aSubject, aTopic, aData) { - if (aTopic == "passwordmgr-password-toggle-complete") { - Services.obs.removeObserver(arguments.callee, aTopic); - func(); - } - }, "passwordmgr-password-toggle-complete", false); - - 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 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 (aSubject, aTopic, aData) { - // unregister ourself - Services.ww.unregisterNotification(arguments.callee); - - pwmgr.removeAllLogins(); - finish(); - }); - pwmgrdlg.close(); - } - } - - // Toggle Show Passwords to display Password column, then start tests - toggleShowPasswords(runNextTest); - } -} diff --git a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_switchtab.js b/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_switchtab.js deleted file mode 100644 index bd4f265b5..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgr_switchtab.js +++ /dev/null @@ -1,42 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -const PROMPT_URL = "chrome://global/content/commonDialog.xul"; -var { interfaces: Ci } = Components; - -function test() { - waitForExplicitFinish(); - - let tab = gBrowser.addTab(); - isnot(tab, gBrowser.selectedTab, "New tab shouldn't be selected"); - - let listener = { - onOpenWindow: function(window) { - var domwindow = window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow); - 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"); - - domwindow.document.documentElement.cancelDialog(); - }, domwindow); - }, - - onCloseWindow: function() { - } - }; - - Services.wm.addListener(listener); - registerCleanupFunction(() => { - Services.wm.removeListener(listener); - gBrowser.removeTab(tab); - }); - - tab.linkedBrowser.addEventListener("load", () => { - finish(); - }, true); - tab.linkedBrowser.loadURI("http://example.com/browser/toolkit/components/passwordmgr/test/browser/authenticate.sjs"); -} diff --git a/toolkit/components/passwordmgr/test/browser/browser_passwordmgrdlg.js b/toolkit/components/passwordmgr/test/browser/browser_passwordmgrdlg.js deleted file mode 100644 index 57cfa9f83..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_passwordmgrdlg.js +++ /dev/null @@ -1,192 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -function test() { - waitForExplicitFinish(); - - let pwmgr = Cc["@mozilla.org/login-manager;1"]. - getService(Ci.nsILoginManager); - pwmgr.removeAllLogins(); - - // 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/", - ]; - 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"), - ]; - logins.forEach(login => pwmgr.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); - - // 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; - - 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}, - ]; - - 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 (aSubject, aTopic, aData) { - if (aTopic == "domwindowclosed") - Services.ww.unregisterNotification(arguments.callee); - else if (aTopic == "domwindowopened") { - let targetWin = aSubject.QueryInterface(Ci.nsIDOMEventTarget); - SimpleTest.waitForFocus(function() { - EventUtils.sendKey("RETURN", targetWin); - }, targetWin); - } - }); - } - - Services.obs.addObserver(function (aSubject, aTopic, aData) { - if (aTopic == "passwordmgr-password-toggle-complete") { - Services.obs.removeObserver(arguments.callee, aTopic); - func(); - } - }, "passwordmgr-password-toggle-complete", false); - - EventUtils.synthesizeMouse(toggleButton, 1, 1, {}, win); - } - - function runTests(mode, endFunction) { - let testCounter = 0; - - 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(); - 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 runNextTest() { - let testCase = tests[testCounter++]; - setFilter(testCase.filter); - setTimeout(runOneTest, 0, testCase); - } - - runNextTest(); - } - - function step1() { - runTests(1, step2); - } - - function step2() { - toggleShowPasswords(function() { - runTests(2, step3); - }); - } - - function step3() { - toggleShowPasswords(function() { - runTests(3, lastStep); - }); - } - - function lastStep() { - // cleanup - Services.ww.registerNotification(function (aSubject, aTopic, aData) { - // unregister ourself - Services.ww.unregisterNotification(arguments.callee); - - pwmgr.removeAllLogins(); - finish(); - }); - pwmgrdlg.close(); - } - - step1(); - } -} diff --git a/toolkit/components/passwordmgr/test/browser/browser_username_select_dialog.js b/toolkit/components/passwordmgr/test/browser/browser_username_select_dialog.js deleted file mode 100644 index 8df89b510..000000000 --- a/toolkit/components/passwordmgr/test/browser/browser_username_select_dialog.js +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Test username selection dialog, on password update from a p-only form, - * when there are multiple saved logins on the domain. - */ - -// Copied from prompt_common.js. TODO: share the code. -function getSelectDialogDoc() { - // Trudge through all the open windows, until we find the one - // that has selectDialog.xul loaded. - var wm = Cc["@mozilla.org/appshell/window-mediator;1"]. - getService(Ci.nsIWindowMediator); - // var enumerator = wm.getEnumerator("navigator:browser"); - var enumerator = wm.getXULWindowEnumerator(null); - - while (enumerator.hasMoreElements()) { - var win = enumerator.getNext(); - var windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell; - - var containedDocShells = windowDocShell.getDocShellEnumerator( - Ci.nsIDocShellTreeItem.typeChrome, - Ci.nsIDocShell.ENUMERATE_FORWARDS); - while (containedDocShells.hasMoreElements()) { - // Get the corresponding document for this docshell - var childDocShell = containedDocShells.getNext(); - // We don't want it if it's not done loading. - if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE) - continue; - var childDoc = childDocShell.QueryInterface(Ci.nsIDocShell) - .contentViewer - .DOMDocument; - - if (childDoc.location.href == "chrome://global/content/selectDialog.xul") - return childDoc; - } - } - - return null; -} - -let nsLoginInfo = new Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); -let login1 = new nsLoginInfo("http://example.com", "http://example.com", null, - "notifyu1", "notifyp1", "user", "pass"); -let login1B = new nsLoginInfo("http://example.com", "http://example.com", null, - "notifyu1B", "notifyp1B", "user", "pass"); - -add_task(function* test_changeUPLoginOnPUpdateForm_accept() { - info("Select an u+p login from multiple logins, on password update form, and accept."); - Services.logins.addLogin(login1); - Services.logins.addLogin(login1B); - - yield testSubmittingLoginForm("subtst_notifications_change_p.html", function*(fieldValues) { - is(fieldValues.username, "null", "Checking submitted username"); - is(fieldValues.password, "pass2", "Checking submitted password"); - - yield ContentTaskUtils.waitForCondition(() => { - return getSelectDialogDoc(); - }, "Wait for selection dialog to be accessible."); - - let doc = getSelectDialogDoc(); - let dialog = doc.getElementsByTagName("dialog")[0]; - let listbox = doc.getElementById("list"); - - is(listbox.selectedIndex, 0, "Checking selected index"); - is(listbox.itemCount, 2, "Checking selected length"); - ['notifyu1', 'notifyu1B'].forEach((username, i) => { - is(listbox.getItemAtIndex(i).label, username, "Check username selection on dialog"); - }); - - dialog.acceptDialog(); - - yield ContentTaskUtils.waitForCondition(() => { - return !getSelectDialogDoc(); - }, "Wait for selection dialog to disappear."); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 2, "Should have 2 logins"); - - let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username unchanged"); - is(login.password, "pass2", "Check the password changed"); - is(login.timesUsed, 2, "Check times used"); - - login = SpecialPowers.wrap(logins[1]).QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1B", "Check the username unchanged"); - is(login.password, "notifyp1B", "Check the password unchanged"); - is(login.timesUsed, 1, "Check times used"); - - // cleanup - login1.password = "pass2"; - Services.logins.removeLogin(login1); - login1.password = "notifyp1"; - - Services.logins.removeLogin(login1B); -}); - -add_task(function* test_changeUPLoginOnPUpdateForm_cancel() { - info("Select an u+p login from multiple logins, on password update form, and cancel."); - Services.logins.addLogin(login1); - Services.logins.addLogin(login1B); - - yield testSubmittingLoginForm("subtst_notifications_change_p.html", function*(fieldValues) { - is(fieldValues.username, "null", "Checking submitted username"); - is(fieldValues.password, "pass2", "Checking submitted password"); - - yield ContentTaskUtils.waitForCondition(() => { - return getSelectDialogDoc(); - }, "Wait for selection dialog to be accessible."); - - let doc = getSelectDialogDoc(); - let dialog = doc.getElementsByTagName("dialog")[0]; - let listbox = doc.getElementById("list"); - - is(listbox.selectedIndex, 0, "Checking selected index"); - is(listbox.itemCount, 2, "Checking selected length"); - ['notifyu1', 'notifyu1B'].forEach((username, i) => { - is(listbox.getItemAtIndex(i).label, username, "Check username selection on dialog"); - }); - - dialog.cancelDialog(); - - yield ContentTaskUtils.waitForCondition(() => { - return !getSelectDialogDoc(); - }, "Wait for selection dialog to disappear."); - }); - - let logins = Services.logins.getAllLogins(); - is(logins.length, 2, "Should have 2 logins"); - - let login = SpecialPowers.wrap(logins[0]).QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1", "Check the username unchanged"); - is(login.password, "notifyp1", "Check the password unchanged"); - is(login.timesUsed, 1, "Check times used"); - - login = SpecialPowers.wrap(logins[1]).QueryInterface(Ci.nsILoginMetaInfo); - is(login.username, "notifyu1B", "Check the username unchanged"); - is(login.password, "notifyp1B", "Check the password unchanged"); - is(login.timesUsed, 1, "Check times used"); - - // cleanup - Services.logins.removeLogin(login1); - Services.logins.removeLogin(login1B); -}); diff --git a/toolkit/components/passwordmgr/test/browser/form_autofocus_js.html b/toolkit/components/passwordmgr/test/browser/form_autofocus_js.html deleted file mode 100644 index 76056e375..000000000 --- a/toolkit/components/passwordmgr/test/browser/form_autofocus_js.html +++ /dev/null @@ -1,10 +0,0 @@ -<!DOCTYPE html><html><head><meta charset="utf-8"></head> -<body onload="document.getElementById('form-basic-username').focus();"> -<!-- Username field is focused by js onload --> -<form id="form-basic"> - <input id="form-basic-username" name="username"> - <input id="form-basic-password" name="password" type="password"> - <input id="form-basic-submit" type="submit"> -</form> - -</body></html> diff --git a/toolkit/components/passwordmgr/test/browser/form_basic.html b/toolkit/components/passwordmgr/test/browser/form_basic.html deleted file mode 100644 index df2083a93..000000000 --- a/toolkit/components/passwordmgr/test/browser/form_basic.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE html><html><head><meta charset="utf-8"></head><body> -<!-- Any copyright is dedicated to the Public Domain. - - http://creativecommons.org/publicdomain/zero/1.0/ --> - -<!-- Simplest form with username and password fields. --> -<form id="form-basic"> - <input id="form-basic-username" name="username"> - <input id="form-basic-password" name="password" type="password"> - <input id="form-basic-submit" type="submit"> -</form> - -</body></html> diff --git a/toolkit/components/passwordmgr/test/browser/form_basic_iframe.html b/toolkit/components/passwordmgr/test/browser/form_basic_iframe.html deleted file mode 100644 index 616f56947..000000000 --- a/toolkit/components/passwordmgr/test/browser/form_basic_iframe.html +++ /dev/null @@ -1,13 +0,0 @@ -<!DOCTYPE html> -<html> - -<head> - <meta charset="utf-8"> -</head> - -<body> - <!-- Form in an iframe --> - <iframe src="https://example.org/browser/toolkit/components/passwordmgr/test/browser/form_basic.html" id="test-iframe"></iframe> -</body> - -</html> diff --git a/toolkit/components/passwordmgr/test/browser/form_cross_origin_insecure_action.html b/toolkit/components/passwordmgr/test/browser/form_cross_origin_insecure_action.html deleted file mode 100644 index e8aa8b215..000000000 --- a/toolkit/components/passwordmgr/test/browser/form_cross_origin_insecure_action.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE html><html><head><meta charset="utf-8"></head><body> -<!-- Any copyright is dedicated to the Public Domain. - - http://creativecommons.org/publicdomain/zero/1.0/ --> - -<!-- Simplest form with username and password fields. --> -<form id="form-basic" action="http://another.domain/custom_action.html"> - <input id="form-basic-username" name="username"> - <input id="form-basic-password" name="password" type="password"> - <input id="form-basic-submit" type="submit"> -</form> - -</body></html> diff --git a/toolkit/components/passwordmgr/test/browser/form_cross_origin_secure_action.html b/toolkit/components/passwordmgr/test/browser/form_cross_origin_secure_action.html deleted file mode 100644 index 892a9f6f6..000000000 --- a/toolkit/components/passwordmgr/test/browser/form_cross_origin_secure_action.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE html><html><head><meta charset="utf-8"></head><body> -<!-- Any copyright is dedicated to the Public Domain. - - http://creativecommons.org/publicdomain/zero/1.0/ --> - -<!-- Simplest form with username and password fields. --> -<form id="form-basic" action="https://another.domain/custom_action.html"> - <input id="form-basic-username" name="username"> - <input id="form-basic-password" name="password" type="password"> - <input id="form-basic-submit" type="submit"> -</form> - -</body></html> diff --git a/toolkit/components/passwordmgr/test/browser/form_same_origin_action.html b/toolkit/components/passwordmgr/test/browser/form_same_origin_action.html deleted file mode 100644 index 8f0c9a14e..000000000 --- a/toolkit/components/passwordmgr/test/browser/form_same_origin_action.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE html><html><head><meta charset="utf-8"></head><body> -<!-- Any copyright is dedicated to the Public Domain. - - http://creativecommons.org/publicdomain/zero/1.0/ --> - -<!-- Simplest form with username and password fields. --> -<form id="form-basic" action="./custom_action.html"> - <input id="form-basic-username" name="username"> - <input id="form-basic-password" name="password" type="password"> - <input id="form-basic-submit" type="submit"> -</form> - -</body></html> diff --git a/toolkit/components/passwordmgr/test/browser/formless_basic.html b/toolkit/components/passwordmgr/test/browser/formless_basic.html deleted file mode 100644 index 2f4c5de52..000000000 --- a/toolkit/components/passwordmgr/test/browser/formless_basic.html +++ /dev/null @@ -1,18 +0,0 @@ -<!DOCTYPE html><html><head><meta charset="utf-8"></head><body> - -<!-- Simplest form with username and password fields. --> - <input id="form-basic-username" name="username"> - <input id="form-basic-password" name="password" type="password"> - <input id="form-basic-submit" type="submit"> - - <button id="add">Add input[type=password]</button> - - <script> - document.getElementById("add").addEventListener("click", function () { - var node = document.createElement("input"); - node.setAttribute("type", "password"); - document.querySelector("body").appendChild(node); - }); - </script> - -</body></html> diff --git a/toolkit/components/passwordmgr/test/browser/head.js b/toolkit/components/passwordmgr/test/browser/head.js deleted file mode 100644 index 926cb6616..000000000 --- a/toolkit/components/passwordmgr/test/browser/head.js +++ /dev/null @@ -1,137 +0,0 @@ -const DIRECTORY_PATH = "/browser/toolkit/components/passwordmgr/test/browser/"; - -Cu.import("resource://testing-common/LoginTestUtils.jsm", this); -Cu.import("resource://testing-common/ContentTaskUtils.jsm", this); - -registerCleanupFunction(function* cleanup_removeAllLoginsAndResetRecipes() { - Services.logins.removeAllLogins(); - - let recipeParent = LoginTestUtils.recipes.getRecipeParent(); - if (!recipeParent) { - // No need to reset the recipes if the recipe module wasn't even loaded. - return; - } - yield recipeParent.then(recipeParentResult => recipeParentResult.reset()); -}); - -/** - * Loads a test page in `DIRECTORY_URL` which automatically submits to formsubmit.sjs and returns a - * promise resolving with the field values when the optional `aTaskFn` is done. - * - * @param {String} aPageFile - test page file name which auto-submits to formsubmit.sjs - * @param {Function} aTaskFn - task which can be run before the tab closes. - * @param {String} [aOrigin="http://example.com"] - origin of the server to use - * to load `aPageFile`. - */ -function testSubmittingLoginForm(aPageFile, aTaskFn, aOrigin = "http://example.com") { - return BrowserTestUtils.withNewTab({ - gBrowser, - url: aOrigin + DIRECTORY_PATH + aPageFile, - }, function*(browser) { - ok(true, "loaded " + aPageFile); - let fieldValues = yield ContentTask.spawn(browser, undefined, function*() { - yield ContentTaskUtils.waitForCondition(() => { - return content.location.pathname.endsWith("/formsubmit.sjs") && - content.document.readyState == "complete"; - }, "Wait for form submission load (formsubmit.sjs)"); - let username = content.document.getElementById("user").textContent; - let password = content.document.getElementById("pass").textContent; - return { - username, - password, - }; - }); - ok(true, "form submission loaded"); - if (aTaskFn) { - yield* aTaskFn(fieldValues); - } - return fieldValues; - }); -} - -function checkOnlyLoginWasUsedTwice({ justChanged }) { - // Check to make sure we updated the timestamps and use count on the - // existing login that was submitted for the test. - let logins = Services.logins.getAllLogins(); - is(logins.length, 1, "Should only have 1 login"); - ok(logins[0] instanceof Ci.nsILoginMetaInfo, "metainfo QI"); - is(logins[0].timesUsed, 2, "check .timesUsed for existing login submission"); - ok(logins[0].timeCreated < logins[0].timeLastUsed, "timeLastUsed bumped"); - if (justChanged) { - is(logins[0].timeLastUsed, logins[0].timePasswordChanged, "timeLastUsed == timePasswordChanged"); - } else { - is(logins[0].timeCreated, logins[0].timePasswordChanged, "timeChanged not updated"); - } -} - -// Begin popup notification (doorhanger) functions // - -const REMEMBER_BUTTON = 0; -const NEVER_BUTTON = 1; - -const CHANGE_BUTTON = 0; -const DONT_CHANGE_BUTTON = 1; - -/** - * Checks if we have a password capture popup notification - * of the right type and with the right label. - * - * @param {String} aKind The desired `passwordNotificationType` - * @param {Object} [popupNotifications = PopupNotifications] - * @return the found password popup notification. - */ -function getCaptureDoorhanger(aKind, popupNotifications = PopupNotifications) { - ok(true, "Looking for " + aKind + " popup notification"); - let notification = popupNotifications.getNotification("password"); - if (notification) { - is(notification.options.passwordNotificationType, aKind, "Notification type matches."); - if (aKind == "password-change") { - is(notification.mainAction.label, "Update", "Main action label matches update doorhanger."); - } else if (aKind == "password-save") { - is(notification.mainAction.label, "Remember", "Main action label matches save doorhanger."); - } - } - return notification; -} - -/** - * Clicks the specified popup notification button. - * - * @param {Element} aPopup Popup Notification element - * @param {Number} aButtonIndex Number indicating which button to click. - * See the constants in this file. - */ -function clickDoorhangerButton(aPopup, aButtonIndex) { - ok(true, "Looking for action at index " + aButtonIndex); - - let notifications = aPopup.owner.panel.childNodes; - ok(notifications.length > 0, "at least one notification displayed"); - ok(true, notifications.length + " notification(s)"); - let notification = notifications[0]; - - if (aButtonIndex == 0) { - ok(true, "Triggering main action"); - notification.button.doCommand(); - } else if (aButtonIndex <= aPopup.secondaryActions.length) { - ok(true, "Triggering secondary action " + aButtonIndex); - notification.childNodes[aButtonIndex].doCommand(); - } -} - -/** - * Checks the doorhanger's username and password. - * - * @param {String} username The username. - * @param {String} password The password. - */ -function* checkDoorhangerUsernamePassword(username, password) { - yield BrowserTestUtils.waitForCondition(() => { - return document.getElementById("password-notification-username").value == username; - }, "Wait for nsLoginManagerPrompter writeDataToUI()"); - is(document.getElementById("password-notification-username").value, username, - "Check doorhanger username"); - is(document.getElementById("password-notification-password").value, password, - "Check doorhanger password"); -} - -// End popup notification (doorhanger) functions // diff --git a/toolkit/components/passwordmgr/test/browser/insecure_test.html b/toolkit/components/passwordmgr/test/browser/insecure_test.html deleted file mode 100644 index fedea1428..000000000 --- a/toolkit/components/passwordmgr/test/browser/insecure_test.html +++ /dev/null @@ -1,9 +0,0 @@ -<!DOCTYPE html><html><head><meta charset="utf-8"></head><body> -<!-- Any copyright is dedicated to the Public Domain. - - http://creativecommons.org/publicdomain/zero/1.0/ --> - -<!-- This frame is initially loaded over HTTP. --> -<iframe id="test-iframe" - src="http://example.org/browser/toolkit/components/passwordmgr/test/browser/insecure_test_subframe.html"/> - -</body></html> diff --git a/toolkit/components/passwordmgr/test/browser/insecure_test_subframe.html b/toolkit/components/passwordmgr/test/browser/insecure_test_subframe.html deleted file mode 100644 index 3f01e36a6..000000000 --- a/toolkit/components/passwordmgr/test/browser/insecure_test_subframe.html +++ /dev/null @@ -1,13 +0,0 @@ -<!DOCTYPE html><html><head><meta charset="utf-8"></head><body> -<!-- Any copyright is dedicated to the Public Domain. - - http://creativecommons.org/publicdomain/zero/1.0/ --> - -<form> - <input name="password" type="password"> -</form> - -<!-- Link to reload this page over HTTPS. --> -<a id="test-link" - href="https://example.org/browser/toolkit/components/passwordmgr/test/browser/insecure_test_subframe.html">HTTPS</a> - -</body></html> diff --git a/toolkit/components/passwordmgr/test/browser/multiple_forms.html b/toolkit/components/passwordmgr/test/browser/multiple_forms.html deleted file mode 100644 index 3f64f8993..000000000 --- a/toolkit/components/passwordmgr/test/browser/multiple_forms.html +++ /dev/null @@ -1,129 +0,0 @@ -<!DOCTYPE html><html><head><meta charset="utf-8"></head><body> -<!-- Any copyright is dedicated to the Public Domain. - - http://creativecommons.org/publicdomain/zero/1.0/ --> - - -<form class="test-form" - description="Password only form"> - <input id='test-password-1' type='password' name='pname' value=''> - <input type='submit'>Submit</input> -</form> - - -<form class="test-form" - description="Username only form"> - <input id='test-username-1' type='text' name='uname' value=''> - <input type='submit'>Submit</input> -</form> - - -<form class="test-form" - description="Simple username and password blank form"> - <input id='test-username-2' type='text' name='uname' value=''> - <input id='test-password-2' type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - - -<form class="test-form" - description="Simple username and password form, prefilled username"> - <input id='test-username-3' type='text' name='uname' value='testuser'> - <input id='test-password-3' type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - - -<form class="test-form" - description="Simple username and password form, prefilled username and password"> - <input id='test-username-4' type='text' name='uname' value='testuser'> - <input id='test-password-4' type='password' name='pname' value='testpass'> - <button type='submit'>Submit</button> -</form> - - -<form class="test-form" - description="One username and two passwords empty form"> - <input id='test-username-5' type='text' name='uname'> - <input id='test-password-5' type='password' name='pname'> - <input id='test-password2-5' type='password' name='pname2'> - <button type='submit'>Submit</button> -</form> - - -<form class="test-form" - description="One username and two passwords form, fields prefiled"> - <input id='test-username-6' type='text' name='uname' value="testuser"> - <input id='test-password-6' type='password' name='pname' value="testpass"> - <input id='test-password2-6' type='password' name='pname2' value="testpass"> - <button type='submit'>Submit</button> -</form> - - -<div class="test-form" - description="Username and password fields with no form"> - <input id='test-username-7' type='text' name='uname' value="testuser"> - <input id='test-password-7' type='password' name='pname' value="testpass"> -</div> - - -<form class="test-form" - description="Simple username and password blank form, with disabled password"> - <input id='test-username-8' type='text' name='uname' value=''> - <input id='test-password-8' type='password' name='pname' value='' disabled> - <button type='submit'>Submit</button> -</form> - - -<form class="test-form" - description="Simple username and password blank form, with disabled username"> - <input id='test-username-9' type='text' name='uname' value='' disabled> - <input id='test-password-9' type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - - -<form class="test-form" - description="Simple username and password blank form, with readonly password"> - <input id='test-username-10' type='text' name='uname' value=''> - <input id='test-password-10' type='password' name='pname' value='' readonly> - <button type='submit'>Submit</button> -</form> - - -<form class="test-form" - description="Simple username and password blank form, with readonly username"> - <input id='test-username-11' type='text' name='uname' value='' readonly> - <input id='test-password-11' type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - - -<form class="test-form" - description="Two username and one passwords form, fields prefiled"> - <input id='test-username-12' type='text' name='uname' value="testuser"> - <input id='test-username2-12' type='text' name='uname2' value="testuser"> - <input id='test-password-12' type='password' name='pname' value="testpass"> - <button type='submit'>Submit</button> -</form> - - -<form class="test-form" - description="Two username and one passwords form, one disabled username field"> - <input id='test-username-13' type='text' name='uname'> - <input id='test-username2-13' type='text' name='uname2' disabled> - <input id='test-password-13' type='password' name='pname'> - <button type='submit'>Submit</button> -</form> - - -<div class="test-form" - description="Second username and password fields with no form"> - <input id='test-username-14' type='text' name='uname'> - <input id='test-password-14' type='password' name='pname' expectedFail> -</div> - -<!-- Form in an iframe --> -<iframe src="https://example.org/browser/toolkit/components/passwordmgr/test/browser/form_basic.html" id="test-iframe"></iframe> - -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/streamConverter_content.sjs b/toolkit/components/passwordmgr/test/browser/streamConverter_content.sjs deleted file mode 100644 index 84c75437e..000000000 --- a/toolkit/components/passwordmgr/test/browser/streamConverter_content.sjs +++ /dev/null @@ -1,6 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -function handleRequest(request, response) { - response.setHeader("Content-Type", "test/content", false); -} diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_1.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_1.html deleted file mode 100644 index b96faf2ee..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_1.html +++ /dev/null @@ -1,29 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications - Basic 1un 1pw</title> -</head> -<body> -<h2>Subtest 1</h2> -<form id="form" action="formsubmit.sjs"> - <input id="user" name="user"> - <input id="pass" name="pass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - userField.value = "notifyu1"; - passField.value = "notifyp1"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); -var passField = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_10.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_10.html deleted file mode 100644 index 2dc96b4fd..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_10.html +++ /dev/null @@ -1,27 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications</title> -</head> -<body> -<h2>Subtest 10</h2> -<form id="form" action="formsubmit.sjs"> - <input id="pass" name="pass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - passField.value = "notifyp1"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); -var passField = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_11.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_11.html deleted file mode 100644 index cf3df5275..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_11.html +++ /dev/null @@ -1,25 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications - Popup Windows</title> -</head> -<body> -<h2>Subtest 11 (popup windows)</h2> -<script> - -// Ignore the '?' and split on | -[username, password, features, autoClose] = window.location.search.substring(1).split('|'); - -var url = "subtst_notifications_11_popup.html?" + username + "|" + password; -var popupWin = window.open(url, "subtst_11", features); - -// Popup window will call this function on form submission. -function formSubmitted() { - if (autoClose) - popupWin.close(); -} - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_11_popup.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_11_popup.html deleted file mode 100644 index 2e8e4135c..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_11_popup.html +++ /dev/null @@ -1,32 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications</title> -</head> -<body> -<h2>Subtest 11</h2> -<form id="form" action="formsubmit.sjs"> - <input id="user" name="user"> - <input id="pass" name="pass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - // Get the password from the query string (exclude '?'). - [username, password] = window.location.search.substring(1).split('|'); - userField.value = username; - passField.value = password; - form.submit(); - window.opener.formSubmitted(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); -var passField = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_2.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_2.html deleted file mode 100644 index 72651d6c1..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_2.html +++ /dev/null @@ -1,30 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications - autocomplete=off on the username field</title> -</head> -<body> -<h2>Subtest 2</h2> -(username autocomplete=off) -<form id="form" action="formsubmit.sjs"> - <input id="user" name="user" autocomplete="off"> - <input id="pass" name="pass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - userField.value = "notifyu1"; - passField.value = "notifyp1"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); -var passField = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_0un.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_0un.html deleted file mode 100644 index 7ddbf0851..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_0un.html +++ /dev/null @@ -1,27 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications with 2 password fields and no username</title> -</head> -<body> -<h2>Subtest 24</h2> -<form id="form" action="formsubmit.sjs"> - <input id="pass1" name="pass1" type="password" value="staticpw"> - <input id="pass" name="pass" type="password"> - <button type="submit">Submit</button> -</form> - -<script> -function submitForm() { - pass.value = "notifyp1"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var pass = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_1un_1text.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_1un_1text.html deleted file mode 100644 index 893f18724..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_2pw_1un_1text.html +++ /dev/null @@ -1,31 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications with 2 password fields and 1 username field and one other text field before the first password field</title> -</head> -<body> -<h2>1 username field followed by a text field followed by 2 username fields</h2> -<form id="form" action="formsubmit.sjs"> - <input id="user" name="user" value="staticpw"> - <input id="city" name="city" value="city"> - <input id="pass" name="pass" type="password"> - <input id="pin" name="pin" type="password" value="static-pin"> - <button type="submit">Submit</button> -</form> - -<script> -function submitForm() { - userField.value = "notifyu1"; - passField.value = "notifyp1"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); -var passField = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_3.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_3.html deleted file mode 100644 index 291e735d0..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_3.html +++ /dev/null @@ -1,30 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications - autocomplete=off on the password field</title> -</head> -<body> -<h2>Subtest 3</h2> -(password autocomplete=off) -<form id="form" action="formsubmit.sjs"> - <input id="user" name="user"> - <input id="pass" name="pass" type="password" autocomplete="off"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - userField.value = "notifyu1"; - passField.value = "notifyp1"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); -var passField = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_4.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_4.html deleted file mode 100644 index 63df3a42d..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_4.html +++ /dev/null @@ -1,30 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8" > - <title>Subtest for Login Manager notifications</title> -</head> -<body> -<h2>Subtest 4</h2> -(form autocomplete=off) -<form id="form" action="formsubmit.sjs" autocomplete="off"> - <input id="user" name="user"> - <input id="pass" name="pass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - userField.value = "notifyu1"; - passField.value = "notifyp1"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); -var passField = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_5.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_5.html deleted file mode 100644 index 72a3df95f..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_5.html +++ /dev/null @@ -1,26 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications - Form with only a username field</title> -</head> -<body> -<h2>Subtest 5</h2> -<form id="form" action="formsubmit.sjs"> - <input id="user" name="user"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - userField.value = "notifyu1"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_6.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_6.html deleted file mode 100644 index 47e23e972..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_6.html +++ /dev/null @@ -1,27 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications</title> -</head> -<body> -<h2>Subtest 6</h2> -(password-only form) -<form id="form" action="formsubmit.sjs"> - <input id="pass" name="pass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - passField.value = "notifyp1"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var passField = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_8.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_8.html deleted file mode 100644 index abeea4262..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_8.html +++ /dev/null @@ -1,29 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications</title> -</head> -<body> -<h2>Subtest 8</h2> -<form id="form" action="formsubmit.sjs"> - <input id="user" name="user"> - <input id="pass" name="pass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - userField.value = "notifyu1"; - passField.value = "pass2"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); -var passField = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_9.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_9.html deleted file mode 100644 index c6f741068..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_9.html +++ /dev/null @@ -1,29 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications</title> -</head> -<body> -<h2>Subtest 9</h2> -<form id="form" action="formsubmit.sjs"> - <input id="user" name="user"> - <input id="pass" name="pass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - userField.value = ""; - passField.value = "pass2"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); -var passField = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/browser/subtst_notifications_change_p.html b/toolkit/components/passwordmgr/test/browser/subtst_notifications_change_p.html deleted file mode 100644 index d74f3bcdf..000000000 --- a/toolkit/components/passwordmgr/test/browser/subtst_notifications_change_p.html +++ /dev/null @@ -1,32 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications</title> -</head> -<body> -<h2>Change password</h2> -<form id="form" action="formsubmit.sjs"> - <input id="pass_current" name="pass_current" type="password" value="notifyp1"> - <input id="pass" name="pass" type="password"> - <input id="pass_confirm" name="pass_confirm" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - passField.value = "pass2"; - passConfirmField.value = "pass2"; - - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); -var passField = document.getElementById("pass"); -var passConfirmField = document.getElementById("pass_confirm"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/chrome/chrome.ini b/toolkit/components/passwordmgr/test/chrome/chrome.ini deleted file mode 100644 index 093b87b7d..000000000 --- a/toolkit/components/passwordmgr/test/chrome/chrome.ini +++ /dev/null @@ -1,13 +0,0 @@ -[DEFAULT] -skip-if = os == 'android' - -[test_privbrowsing_perwindowpb.html] -skip-if = true # Bug 1173337 -support-files = - ../formsubmit.sjs - notification_common.js - privbrowsing_perwindowpb_iframe.html - subtst_privbrowsing_1.html - subtst_privbrowsing_2.html - subtst_privbrowsing_3.html - subtst_privbrowsing_4.html diff --git a/toolkit/components/passwordmgr/test/chrome/notification_common.js b/toolkit/components/passwordmgr/test/chrome/notification_common.js deleted file mode 100644 index e8a52929d..000000000 --- a/toolkit/components/passwordmgr/test/chrome/notification_common.js +++ /dev/null @@ -1,111 +0,0 @@ -/* - * 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(); - } -} -cleanUpPopupNotifications(); - -/* - * getPopupNotifications - * - * 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 chromeWin = SpecialPowers.wrap(aWindow) - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell) - .chromeEventHandler.ownerDocument.defaultView; - - var popupNotifications = chromeWin.PopupNotifications; - return popupNotifications; -} - - -/** - * Checks if we have a password popup notification - * of the right type and with the right label. - * - * @deprecated Write a browser-chrome test instead and use the fork of this method there. - * @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."); - } - } - return notification; -} - - -/** - * @deprecated - Use a browser chrome test instead. - * - * Clicks the specified popup notification button. - */ -function clickPopupButton(aPopup, 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]; - - 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; -const kNeverButton = 1; - -const kChangeButton = 0; -const kDontChangeButton = 1; - -function dumpNotifications() { - try { - // PopupNotifications - var container = getPopupNotifications(window.top); - ok(true, "is popup panel open? " + container.isPanelOpen); - 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); - } - - // Notification bars - var chromeWin = SpecialPowers.wrap(window.top) - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShell) - .chromeEventHandler.ownerDocument.defaultView; - var nb = chromeWin.getNotificationBox(window.top); - 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")); - } - } catch (e) { todo(false, "WOAH! " + e); } -} diff --git a/toolkit/components/passwordmgr/test/chrome/privbrowsing_perwindowpb_iframe.html b/toolkit/components/passwordmgr/test/chrome/privbrowsing_perwindowpb_iframe.html deleted file mode 100644 index 2efdab265..000000000 --- a/toolkit/components/passwordmgr/test/chrome/privbrowsing_perwindowpb_iframe.html +++ /dev/null @@ -1,9 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> -</head> -<body> -<iframe id="iframe"></iframe> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_1.html b/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_1.html deleted file mode 100644 index 8c7202dd0..000000000 --- a/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_1.html +++ /dev/null @@ -1,33 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications (private browsing)</title> -</head> -<body> -<h2>Subtest 1</h2> -<!-- - Make sure that the password-save notification appears outside of - the private mode, but not inside it. ---> -<form id="form" action="formsubmit.sjs"> - <input id="user" name="user" type="text"> - <input id="pass" name="pass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - userField.value = "notifyu1"; - passField.value = "notifyp1"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var userField = document.getElementById("user"); -var passField = document.getElementById("pass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_2.html b/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_2.html deleted file mode 100644 index bf3b85159..000000000 --- a/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_2.html +++ /dev/null @@ -1,33 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications (private browsing)</title> -</head> -<body> -<h2>Subtest 2</h2> -<!-- - Make sure that the password-change notification appears outside of - the private mode, but not inside it. ---> -<form id="form" action="formsubmit.sjs"> - <input id="pass" name="pass" type="password"> - <input id="newpass" name="newpass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - passField.value = "notifyp1"; - passField2.value = "notifyp2"; - form.submit(); -} - -window.onload = submitForm; -var form = document.getElementById("form"); -var passField = document.getElementById("pass"); -var passField2 = document.getElementById("newpass"); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_3.html b/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_3.html deleted file mode 100644 index e88a302e0..000000000 --- a/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_3.html +++ /dev/null @@ -1,29 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications (private browsing)</title> -</head> -<body> -<h2>Subtest 3</h2> -<!-- - Make sure that the user/pass fields are auto-filled outside of - the private mode, but not inside it. ---> -<form id="form" action="formsubmit.sjs"> - <input id="user" name="user" type="text"> - <input id="pass" name="pass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function submitForm() { - form.submit(); -} - -var form = document.getElementById("form"); -window.addEventListener('message', () => { submitForm(); }); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_4.html b/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_4.html deleted file mode 100644 index 184142743..000000000 --- a/toolkit/components/passwordmgr/test/chrome/subtst_privbrowsing_4.html +++ /dev/null @@ -1,40 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Subtest for Login Manager notifications (private browsing)</title> - <script type="text/javascript" src="pwmgr_common.js"></script> -</head> -<body> -<h2>Subtest 4</h2> -<!-- - Make sure that the user/pass fields have manual filling enabled - in private mode. ---> -<form id="form" action="formsubmit.sjs"> - <input id="user" name="user" type="text"> - <input id="pass" name="pass" type="password"> - <button type='submit'>Submit</button> -</form> - -<script> -function startAutocomplete() { - userField.focus(); - doKey("down"); - setTimeout(submitForm, 100); -} - -function submitForm() { - doKey("down"); - doKey("return"); - setTimeout(function() { form.submit(); }, 100); -} - -var form = document.getElementById("form"); -var userField = document.getElementById("user"); - -window.addEventListener('message', () => { startAutocomplete(); }); - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/chrome/test_privbrowsing_perwindowpb.html b/toolkit/components/passwordmgr/test/chrome/test_privbrowsing_perwindowpb.html deleted file mode 100644 index 6b7d4abb3..000000000 --- a/toolkit/components/passwordmgr/test/chrome/test_privbrowsing_perwindowpb.html +++ /dev/null @@ -1,322 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=248970 ---> -<head> - <meta charset="utf-8"> - <title>Test for Private Browsing</title> - <script type="application/javascript" - src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="notification_common.js"></script> - <link rel="stylesheet" type="text/css" - href="chrome://mochikit/content/tests/SimpleTest/test.css"> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=248970">Mozilla Bug 248970</a> -<p id="display"></p> -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Bug 248970 **/ -// based on test_notifications.html - -const Ci = SpecialPowers.Ci; -const Cc = SpecialPowers.Cc; -const Cr = SpecialPowers.Cr; - -Components.utils.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 - ]; -var observer; - -var testNum = 0; -function loadNextTest() { - // run the initialization code for each test - switch (++ testNum) { - case 1: - popupNotifications = normalWindowPopupNotifications; - iframe = normalWindowIframe; - break; - - case 2: - popupNotifications = privateWindowPopupNotifications; - iframe = privateWindowIframe; - break; - - case 3: - popupNotifications = normalWindowPopupNotifications; - iframe = normalWindowIframe; - break; - - case 4: - pwmgr.addLogin(login); - break; - - case 5: - popupNotifications = privateWindowPopupNotifications; - iframe = privateWindowIframe; - break; - - case 6: - popupNotifications = normalWindowPopupNotifications; - iframe = normalWindowIframe; - break; - - case 7: - pwmgr.addLogin(login); - break; - - case 8: - popupNotifications = privateWindowPopupNotifications; - iframe = privateWindowIframe; - break; - - case 9: - break; - - case 10: - popupNotifications = normalWindowPopupNotifications; - iframe = normalWindowIframe; - break; - - default: - ok(false, "Unexpected call to loadNextTest for test #" + testNum); - } - - if (testNum === 7) { - observer = SpecialPowers.wrapCallback(function(subject, topic, data) { - SimpleTest.executeSoon(() => { iframe.contentWindow.postMessage("go", "*"); }); - }); - SpecialPowers.addObserver(observer, "passwordmgr-processed-form", false); - } - - ok(true, "Starting test #" + testNum); - iframe.src = prefix + subtests[testNum - 1]; -} - -function checkTest() { - var popup; - var gotUser; - var gotPass; - - switch (testNum) { - case 1: - // run outside of private mode, popup notification should appear - popup = getPopup(popupNotifications, "password-save"); - ok(popup, "got popup notification"); - popup.remove(); - break; - - case 2: - // run inside of private mode, popup notification should not appear - popup = getPopup(popupNotifications, "password-save"); - ok(!popup, "checking for no popup notification"); - break; - - case 3: - // run outside of private mode, popup notification should appear - popup = getPopup(popupNotifications, "password-save"); - ok(popup, "got popup notification"); - popup.remove(); - break; - - case 4: - // run outside of private mode, popup notification should appear - popup = getPopup(popupNotifications, "password-change"); - ok(popup, "got popup notification"); - popup.remove(); - break; - - case 5: - // run inside of private mode, popup notification should not appear - popup = getPopup(popupNotifications, "password-change"); - ok(!popup, "checking for no popup notification"); - break; - - case 6: - // run outside of private mode, popup notification should appear - popup = getPopup(popupNotifications, "password-change"); - ok(popup, "got popup notification"); - popup.remove(); - pwmgr.removeLogin(login); - break; - - case 7: - // verify that the user/pass pair was autofilled - gotUser = iframe.contentDocument.getElementById("user").textContent; - gotPass = iframe.contentDocument.getElementById("pass").textContent; - is(gotUser, "notifyu1", "Checking submitted username"); - is(gotPass, "notifyp1", "Checking submitted password"); - break; - - case 8: - // verify that the user/pass pair was not autofilled - gotUser = iframe.contentDocument.getElementById("user").textContent; - gotPass = iframe.contentDocument.getElementById("pass").textContent; - is(gotUser, "", "Checking submitted username"); - is(gotPass, "", "Checking submitted password"); - break; - - case 9: - // verify that the user/pass pair was available for autocomplete - gotUser = iframe.contentDocument.getElementById("user").textContent; - gotPass = iframe.contentDocument.getElementById("pass").textContent; - is(gotUser, "notifyu1", "Checking submitted username"); - is(gotPass, "notifyp1", "Checking submitted password"); - break; - - case 10: - // verify that the user/pass pair was autofilled - gotUser = iframe.contentDocument.getElementById("user").textContent; - gotPass = iframe.contentDocument.getElementById("pass").textContent; - is(gotUser, "notifyu1", "Checking submitted username"); - is(gotPass, "notifyp1", "Checking submitted password"); - pwmgr.removeLogin(login); - break; - - default: - ok(false, "Unexpected call to checkTest for test #" + testNum); - - } -} - -var mainWindow = window.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation) - .QueryInterface(Ci.nsIDocShellTreeItem) - .rootTreeItem - .QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDOMWindow); -var contentPage = "http://mochi.test:8888/chrome/toolkit/components/passwordmgr/test/chrome/privbrowsing_perwindowpb_iframe.html"; -var testWindows = []; - -function whenDelayedStartupFinished(aWindow, aCallback) { - Services.obs.addObserver(function obs(aSubject, aTopic) { - if (aWindow == aSubject) { - Services.obs.removeObserver(obs, aTopic); - setTimeout(aCallback, 0); - } - }, "browser-delayed-startup-finished", false); -} - -function testOnWindow(aIsPrivate, aCallback) { - var win = mainWindow.OpenBrowserWindow({private: aIsPrivate}); - win.addEventListener("load", function onLoad() { - win.removeEventListener("load", onLoad, false); - whenDelayedStartupFinished(win, function() { - win.addEventListener("DOMContentLoaded", function onInnerLoad() { - if (win.content.location.href != contentPage) { - win.gBrowser.loadURI(contentPage); - return; - } - win.removeEventListener("DOMContentLoaded", onInnerLoad, true); - - win.content.addEventListener('load', function innerLoad2() { - win.content.removeEventListener('load', innerLoad2, false); - testWindows.push(win); - SimpleTest.executeSoon(function() { aCallback(win); }); - }, false, true); - }, true); - SimpleTest.executeSoon(function() { win.gBrowser.loadURI(contentPage); }); - }); - }, true); -} - -var ignoreLoad = false; -function handleLoad(aEvent) { - // ignore every other load event ... We get one for loading the subtest (which - // we want to ignore), and another when the subtest's form submits itself - // (which we want to handle, to start the next test). - ignoreLoad = !ignoreLoad; - if (ignoreLoad) { - ok(true, "Ignoring load of subtest #" + testNum); - return; - } - ok(true, "Processing submission of subtest #" + testNum); - - checkTest(); - - if (testNum < subtests.length) { - loadNextTest(); - } else { - ok(true, "private browsing notification tests finished."); - - testWindows.forEach(function(aWin) { - aWin.close(); - }); - - SpecialPowers.removeObserver(observer, "passwordmgr-processed-form"); - SimpleTest.finish(); - } -} - -var pwmgr = Cc["@mozilla.org/login-manager;1"]. - getService(Ci.nsILoginManager); -ok(pwmgr != null, "Access pwmgr"); - -// We need to make sure no logins have been stored by previous tests -// for forms in |url|, otherwise the change password notification -// would turn into a prompt, and the test will fail. -var url = "http://test2.example.com"; -is(pwmgr.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"); -var login = new nsLoginInfo(url, url, null, "notifyu1", "notifyp1", "user", "pass"); - -var normalWindow; -var privateWindow; - -var iframe; -var normalWindowIframe; -var privateWindowIframe; - -var popupNotifications; -var normalWindowPopupNotifications; -var privateWindowPopupNotifications; - -testOnWindow(false, function(aWin) { - var selectedBrowser = aWin.gBrowser.selectedBrowser; - normalWindowIframe = selectedBrowser.contentDocument.getElementById("iframe"); - normalWindowIframe.onload = handleLoad; - selectedBrowser.focus(); - - normalWindowPopupNotifications = getPopupNotifications(selectedBrowser.contentWindow.top); - ok(normalWindowPopupNotifications, "Got popupNotifications in normal window"); - // ignore the first load for this window; - ignoreLoad = false; - - testOnWindow(true, function(aPrivateWin) { - selectedBrowser = aPrivateWin.gBrowser.selectedBrowser; - privateWindowIframe = selectedBrowser.contentDocument.getElementById("iframe"); - privateWindowIframe.onload = handleLoad; - selectedBrowser.focus(); - - privateWindowPopupNotifications = getPopupNotifications(selectedBrowser.contentWindow.top); - ok(privateWindowPopupNotifications, "Got popupNotifications in private window"); - // ignore the first load for this window; - ignoreLoad = false; - - SimpleTest.executeSoon(loadNextTest); - }); -}); - -SimpleTest.waitForExplicitFinish(); -</script> -</pre> -</body> -</html> - diff --git a/toolkit/components/passwordmgr/test/chrome_timeout.js b/toolkit/components/passwordmgr/test/chrome_timeout.js deleted file mode 100644 index 9049d0bea..000000000 --- a/toolkit/components/passwordmgr/test/chrome_timeout.js +++ /dev/null @@ -1,11 +0,0 @@ -const Cc = Components.classes; -const Ci = Components.interfaces; - -addMessageListener('setTimeout', msg => { - let timer = Cc['@mozilla.org/timer;1'].createInstance(Ci.nsITimer); - timer.init(_ => { - sendAsyncMessage('timeout'); - }, msg.delay, Ci.nsITimer.TYPE_ONE_SHOT); -}); - -sendAsyncMessage('ready'); diff --git a/toolkit/components/passwordmgr/test/formsubmit.sjs b/toolkit/components/passwordmgr/test/formsubmit.sjs deleted file mode 100644 index 4b4a387f7..000000000 --- a/toolkit/components/passwordmgr/test/formsubmit.sjs +++ /dev/null @@ -1,37 +0,0 @@ -function handleRequest(request, response) -{ - try { - reallyHandleRequest(request, response); - } catch (e) { - response.setStatusLine("1.0", 200, "AlmostOK"); - response.write("Error handling request: " + e); - } -} - - -function reallyHandleRequest(request, response) { - var match; - var requestAuth = true; - - // XXX I bet this doesn't work for POST requests. - var query = request.queryString; - - var user = null, pass = null; - // user=xxx - match = /user=([^&]*)/.exec(query); - if (match) - user = match[1]; - - // pass=xxx - match = /pass=([^&]*)/.exec(query); - if (match) - pass = match[1]; - - response.setStatusLine("1.0", 200, "OK"); - - response.setHeader("Content-Type", "application/xhtml+xml", false); - response.write("<html xmlns='http://www.w3.org/1999/xhtml'>"); - response.write("<p>User: <span id='user'>" + user + "</span></p>\n"); - response.write("<p>Pass: <span id='pass'>" + pass + "</span></p>\n"); - response.write("</html>"); -} diff --git a/toolkit/components/passwordmgr/test/mochitest.ini b/toolkit/components/passwordmgr/test/mochitest.ini deleted file mode 100644 index 640f5c256..000000000 --- a/toolkit/components/passwordmgr/test/mochitest.ini +++ /dev/null @@ -1,20 +0,0 @@ -[DEFAULT] -skip-if = e10s -support-files = - authenticate.sjs - blank.html - formsubmit.sjs - prompt_common.js - pwmgr_common.js - subtst_master_pass.html - subtst_prompt_async.html - chrome_timeout.js - -[test_master_password.html] -skip-if = toolkit == 'android' # Tests desktop prompts -[test_prompt_async.html] -skip-if = toolkit == 'android' # Tests desktop prompts -[test_xhr.html] -skip-if = toolkit == 'android' # Tests desktop prompts -[test_xml_load.html] -skip-if = toolkit == 'android' # Tests desktop prompts diff --git a/toolkit/components/passwordmgr/test/mochitest/auth2/authenticate.sjs b/toolkit/components/passwordmgr/test/mochitest/auth2/authenticate.sjs deleted file mode 100644 index d2f650013..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/auth2/authenticate.sjs +++ /dev/null @@ -1,220 +0,0 @@ -function handleRequest(request, response) -{ - try { - reallyHandleRequest(request, response); - } catch (e) { - response.setStatusLine("1.0", 200, "AlmostOK"); - response.write("Error handling request: " + e); - } -} - - -function reallyHandleRequest(request, response) { - var match; - var requestAuth = true, requestProxyAuth = true; - - // Allow the caller to drive how authentication is processed via the query. - // Eg, http://localhost:8888/authenticate.sjs?user=foo&realm=bar - // The extra ? allows the user/pass/realm checks to succeed if the name is - // at the beginning of the query string. - var query = "?" + request.queryString; - - var expected_user = "", expected_pass = "", realm = "mochitest"; - var proxy_expected_user = "", proxy_expected_pass = "", proxy_realm = "mochi-proxy"; - var huge = false, plugin = false, anonymous = false; - var authHeaderCount = 1; - // user=xxx - match = /[^_]user=([^&]*)/.exec(query); - if (match) - expected_user = match[1]; - - // pass=xxx - match = /[^_]pass=([^&]*)/.exec(query); - if (match) - expected_pass = match[1]; - - // realm=xxx - match = /[^_]realm=([^&]*)/.exec(query); - if (match) - realm = match[1]; - - // proxy_user=xxx - match = /proxy_user=([^&]*)/.exec(query); - if (match) - proxy_expected_user = match[1]; - - // proxy_pass=xxx - match = /proxy_pass=([^&]*)/.exec(query); - if (match) - proxy_expected_pass = match[1]; - - // proxy_realm=xxx - match = /proxy_realm=([^&]*)/.exec(query); - if (match) - proxy_realm = match[1]; - - // huge=1 - match = /huge=1/.exec(query); - if (match) - huge = true; - - // plugin=1 - match = /plugin=1/.exec(query); - if (match) - plugin = true; - - // multiple=1 - match = /multiple=([^&]*)/.exec(query); - if (match) - authHeaderCount = match[1]+0; - - // anonymous=1 - match = /anonymous=1/.exec(query); - if (match) - anonymous = true; - - // Look for an authentication header, if any, in the request. - // - // EG: Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== - // - // This test only supports Basic auth. The value sent by the client is - // "username:password", obscured with base64 encoding. - - var actual_user = "", actual_pass = "", authHeader, authPresent = false; - if (request.hasHeader("Authorization")) { - authPresent = true; - authHeader = request.getHeader("Authorization"); - match = /Basic (.+)/.exec(authHeader); - if (match.length != 2) - throw new Error("Couldn't parse auth header: " + authHeader); - - var userpass = base64ToString(match[1]); // no atob() :-( - match = /(.*):(.*)/.exec(userpass); - if (match.length != 3) - throw new Error("Couldn't decode auth header: " + userpass); - actual_user = match[1]; - actual_pass = match[2]; - } - - var proxy_actual_user = "", proxy_actual_pass = ""; - if (request.hasHeader("Proxy-Authorization")) { - authHeader = request.getHeader("Proxy-Authorization"); - match = /Basic (.+)/.exec(authHeader); - if (match.length != 2) - throw new Error("Couldn't parse auth header: " + authHeader); - - var userpass = base64ToString(match[1]); // no atob() :-( - match = /(.*):(.*)/.exec(userpass); - if (match.length != 3) - throw new Error("Couldn't decode auth header: " + userpass); - proxy_actual_user = match[1]; - proxy_actual_pass = match[2]; - } - - // Don't request authentication if the credentials we got were what we - // expected. - if (expected_user == actual_user && - expected_pass == actual_pass) { - requestAuth = false; - } - if (proxy_expected_user == proxy_actual_user && - proxy_expected_pass == proxy_actual_pass) { - requestProxyAuth = false; - } - - if (anonymous) { - if (authPresent) { - response.setStatusLine("1.0", 400, "Unexpected authorization header found"); - } else { - response.setStatusLine("1.0", 200, "Authorization header not found"); - } - } else { - if (requestProxyAuth) { - response.setStatusLine("1.0", 407, "Proxy authentication required"); - for (i = 0; i < authHeaderCount; ++i) - response.setHeader("Proxy-Authenticate", "basic realm=\"" + proxy_realm + "\"", true); - } else if (requestAuth) { - response.setStatusLine("1.0", 401, "Authentication required"); - for (i = 0; i < authHeaderCount; ++i) - response.setHeader("WWW-Authenticate", "basic realm=\"" + realm + "\"", true); - } else { - response.setStatusLine("1.0", 200, "OK"); - } - } - - response.setHeader("Content-Type", "application/xhtml+xml", false); - response.write("<html xmlns='http://www.w3.org/1999/xhtml'>"); - response.write("<p>Login: <span id='ok'>" + (requestAuth ? "FAIL" : "PASS") + "</span></p>\n"); - response.write("<p>Proxy: <span id='proxy'>" + (requestProxyAuth ? "FAIL" : "PASS") + "</span></p>\n"); - response.write("<p>Auth: <span id='auth'>" + authHeader + "</span></p>\n"); - response.write("<p>User: <span id='user'>" + actual_user + "</span></p>\n"); - response.write("<p>Pass: <span id='pass'>" + actual_pass + "</span></p>\n"); - - if (huge) { - response.write("<div style='display: none'>"); - for (i = 0; i < 100000; i++) { - response.write("123456789\n"); - } - response.write("</div>"); - response.write("<span id='footnote'>This is a footnote after the huge content fill</span>"); - } - - if (plugin) { - response.write("<embed id='embedtest' style='width: 400px; height: 100px;' " + - "type='application/x-test'></embed>\n"); - } - - response.write("</html>"); -} - - -// base64 decoder -// -// Yoinked from extensions/xml-rpc/src/nsXmlRpcClient.js because btoa() -// doesn't seem to exist. :-( -/* Convert Base64 data to a string */ -const toBinaryTable = [ - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -]; -const base64Pad = '='; - -function base64ToString(data) { - - var result = ''; - var leftbits = 0; // number of bits decoded, but yet to be appended - var leftdata = 0; // bits decoded, but yet to be appended - - // Convert one by one. - for (var i = 0; i < data.length; i++) { - var c = toBinaryTable[data.charCodeAt(i) & 0x7f]; - var padding = (data[i] == base64Pad); - // Skip illegal characters and whitespace - if (c == -1) continue; - - // Collect data into leftdata, update bitcount - leftdata = (leftdata << 6) | c; - leftbits += 6; - - // If we have 8 or more bits, append 8 bits to the result - if (leftbits >= 8) { - leftbits -= 8; - // Append if not padding. - if (!padding) - result += String.fromCharCode((leftdata >> leftbits) & 0xff); - leftdata &= (1 << leftbits) - 1; - } - } - - // If there are any bits left, the base64 string was corrupted - if (leftbits) - throw Components.Exception('Corrupted base64 string'); - - return result; -} diff --git a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini b/toolkit/components/passwordmgr/test/mochitest/mochitest.ini deleted file mode 100644 index a4170d7e0..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/mochitest.ini +++ /dev/null @@ -1,69 +0,0 @@ -[DEFAULT] -support-files = - ../../../prompts/test/chromeScript.js - ../../../prompts/test/prompt_common.js - ../../../satchel/test/parent_utils.js - ../../../satchel/test/satchel_common.js - ../authenticate.sjs - ../blank.html - ../browser/form_autofocus_js.html - ../browser/form_basic.html - ../browser/form_cross_origin_secure_action.html - ../pwmgr_common.js - auth2/authenticate.sjs - -[test_autocomplete_https_upgrade.html] -skip-if = toolkit == 'android' # autocomplete -[test_autofill_https_upgrade.html] -skip-if = toolkit == 'android' # Bug 1259768 -[test_autofill_password-only.html] -[test_autofocus_js.html] -skip-if = toolkit == 'android' # autocomplete -[test_basic_form.html] -[test_basic_form_0pw.html] -[test_basic_form_1pw.html] -[test_basic_form_1pw_2.html] -[test_basic_form_2pw_1.html] -[test_basic_form_2pw_2.html] -[test_basic_form_3pw_1.html] -[test_basic_form_autocomplete.html] -skip-if = toolkit == 'android' # android:autocomplete. -[test_insecure_form_field_autocomplete.html] -skip-if = toolkit == 'android' # android:autocomplete. -[test_password_field_autocomplete.html] -skip-if = toolkit == 'android' # android:autocomplete. -[test_insecure_form_field_no_saved_login.html] -skip-if = toolkit == 'android' || os == 'linux' # android:autocomplete., linux: bug 1325778 -[test_basic_form_html5.html] -[test_basic_form_pwevent.html] -[test_basic_form_pwonly.html] -[test_bug_627616.html] -skip-if = toolkit == 'android' # Tests desktop prompts -[test_bug_776171.html] -[test_case_differences.html] -skip-if = toolkit == 'android' # autocomplete -[test_form_action_1.html] -[test_form_action_2.html] -[test_form_action_javascript.html] -[test_formless_autofill.html] -[test_formless_submit.html] -[test_formless_submit_navigation.html] -[test_formless_submit_navigation_negative.html] -[test_input_events.html] -[test_input_events_for_identical_values.html] -[test_maxlength.html] -[test_passwords_in_type_password.html] -[test_prompt.html] -skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts -[test_prompt_http.html] -skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts -[test_prompt_noWindow.html] -skip-if = e10s || toolkit == 'android' # Tests desktop prompts. e10s: bug 1217876 -[test_prompt_promptAuth.html] -skip-if = os == "linux" || toolkit == 'android' # Tests desktop prompts -[test_prompt_promptAuth_proxy.html] -skip-if = e10s || os == "linux" || toolkit == 'android' # Tests desktop prompts -[test_recipe_login_fields.html] -[test_username_focus.html] -skip-if = toolkit == 'android' # android:autocomplete. -[test_xhr_2.html] diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_upgrade.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_upgrade.html deleted file mode 100644 index 7d5725322..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_upgrade.html +++ /dev/null @@ -1,218 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test autocomplete on an HTTPS page using upgraded HTTP logins</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="satchel_common.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<script> -const chromeScript = runChecksAfterCommonInit(false); - -runInParent(function addLogins() { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - Cu.import("resource://gre/modules/Services.jsm"); - - // Create some logins just for this form, since we'll be deleting them. - let nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); - - // We have two actual HTTPS to avoid autofill before the schemeUpgrades pref flips to true. - let login0 = new nsLoginInfo("https://example.org", "https://example.org", null, - "name", "pass", "uname", "pword"); - - let login1 = new nsLoginInfo("https://example.org", "https://example.org", null, - "name1", "pass1", "uname", "pword"); - - // Same as above but HTTP instead of HTTPS (to test de-duping) - let login2 = new nsLoginInfo("http://example.org", "http://example.org", null, - "name1", "passHTTP", "uname", "pword"); - - // Different HTTP login to upgrade with secure formSubmitURL - let login3 = new nsLoginInfo("http://example.org", "https://example.org", null, - "name2", "passHTTPtoHTTPS", "uname", "pword"); - - try { - Services.logins.addLogin(login0); - Services.logins.addLogin(login1); - Services.logins.addLogin(login2); - Services.logins.addLogin(login3); - } catch (e) { - assert.ok(false, "addLogin threw: " + e); - } -}); -</script> -<p id="display"></p> - -<!-- we presumably can't hide the content for this test. --> -<div id="content"> - <iframe src="https://example.org/tests/toolkit/components/passwordmgr/test/mochitest/form_basic.html"></iframe> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> -const shiftModifier = SpecialPowers.Ci.nsIDOMEvent.SHIFT_MASK; - -let iframe = SpecialPowers.wrap(document.getElementsByTagName("iframe")[0]); -let iframeDoc; -let uname; -let pword; - -// Restore the form to the default state. -function restoreForm() { - pword.focus(); - uname.value = ""; - pword.value = ""; - uname.focus(); -} - -// Check for expected username/password in form. -function checkACForm(expectedUsername, expectedPassword) { - let formID = uname.parentNode.id; - is(uname.value, expectedUsername, "Checking " + formID + " username"); - is(pword.value, expectedPassword, "Checking " + formID + " password"); -} - -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({"set": [["signon.schemeUpgrades", true]]}); - - yield new Promise(resolve => { - iframe.addEventListener("load", function onLoad() { - iframe.removeEventListener("load", onLoad); - resolve(); - }); - }); - - iframeDoc = iframe.contentDocument; - uname = iframeDoc.getElementById("form-basic-username"); - pword = iframeDoc.getElementById("form-basic-password"); -}); - -add_task(function* test_empty_first_entry() { - // Make sure initial form is empty. - checkACForm("", ""); - // Trigger autocomplete popup - restoreForm(); - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is initially closed"); - let shownPromise = promiseACShown(); - doKey("down"); - let results = yield shownPromise; - popupState = yield getPopupState(); - is(popupState.selectedIndex, -1, "Check no entries are selected"); - checkArrayValues(results, ["name", "name1", "name2"], "initial"); - - // Check first entry - let index0Promise = notifySelectedIndex(0); - doKey("down"); - yield index0Promise; - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("name", "pass"); -}); - -add_task(function* test_empty_second_entry() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - doKey("down"); // first - doKey("down"); // second - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("name1", "pass1"); -}); - -add_task(function* test_search() { - restoreForm(); - let shownPromise = promiseACShown(); - // We need to blur for the autocomplete controller to notice the forced value below. - uname.blur(); - uname.value = "name"; - uname.focus(); - sendChar("1"); - doKey("down"); // open - let results = yield shownPromise; - checkArrayValues(results, ["name1"], "check result deduping for 'name1'"); - doKey("down"); // first - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("name1", "pass1"); - - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is now closed"); -}); - -add_task(function* test_delete_first_entry() { - restoreForm(); - uname.focus(); - let shownPromise = promiseACShown(); - doKey("down"); - yield shownPromise; - - let index0Promise = notifySelectedIndex(0); - doKey("down"); - yield index0Promise; - - let deletionPromise = promiseStorageChanged(["removeLogin"]); - // On OS X, shift-backspace and shift-delete work, just delete does not. - // On Win/Linux, shift-backspace does not work, delete and shift-delete do. - doKey("delete", shiftModifier); - yield deletionPromise; - checkACForm("", ""); - - let results = yield notifyMenuChanged(2, "name1"); - - checkArrayValues(results, ["name1", "name2"], "two should remain after deleting the first"); - let popupState = yield getPopupState(); - is(popupState.open, true, "Check popup stays open after deleting"); - doKey("escape"); - popupState = yield getPopupState(); - is(popupState.open, false, "Check popup closed upon ESC"); -}); - -add_task(function* test_delete_duplicate_entry() { - restoreForm(); - uname.focus(); - let shownPromise = promiseACShown(); - doKey("down"); - yield shownPromise; - - let index0Promise = notifySelectedIndex(0); - doKey("down"); - yield index0Promise; - - let deletionPromise = promiseStorageChanged(["removeLogin"]); - // On OS X, shift-backspace and shift-delete work, just delete does not. - // On Win/Linux, shift-backspace does not work, delete and shift-delete do. - doKey("delete", shiftModifier); - yield deletionPromise; - checkACForm("", ""); - - is(LoginManager.countLogins("http://example.org", "http://example.org", null), 1, - "Check that the HTTP login remains"); - is(LoginManager.countLogins("https://example.org", "https://example.org", null), 0, - "Check that the HTTPS login was deleted"); - - // Two menu items should remain as the HTTPS login should have been deleted but - // the HTTP would remain. - let results = yield notifyMenuChanged(1, "name2"); - - checkArrayValues(results, ["name2"], "one should remain after deleting the HTTPS name1"); - let popupState = yield getPopupState(); - is(popupState.open, true, "Check popup stays open after deleting"); - doKey("escape"); - popupState = yield getPopupState(); - is(popupState.open, false, "Check popup closed upon ESC"); -}); - -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_upgrade.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_upgrade.html deleted file mode 100644 index ee1424002..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_upgrade.html +++ /dev/null @@ -1,117 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test autocomplete on an HTTPS page using upgraded HTTP logins</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="satchel_common.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<script> -const MISSING_ACTION_PATH = TESTS_DIR + "mochitest/form_basic.html"; -const CROSS_ORIGIN_SECURE_PATH = TESTS_DIR + "mochitest/form_cross_origin_secure_action.html"; - -const chromeScript = runChecksAfterCommonInit(false); - -let nsLoginInfo = SpecialPowers.wrap(SpecialPowers.Components).Constructor("@mozilla.org/login-manager/loginInfo;1", -SpecialPowers.Ci.nsILoginInfo, -"init"); -</script> -<p id="display"></p> - -<!-- we presumably can't hide the content for this test. --> -<div id="content"> - <iframe></iframe> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> -let iframe = SpecialPowers.wrap(document.getElementsByTagName("iframe")[0]); - -// Check for expected username/password in form. -function checkACForm(expectedUsername, expectedPassword) { - let iframeDoc = iframe.contentDocument; - let uname = iframeDoc.getElementById("form-basic-username"); - let pword = iframeDoc.getElementById("form-basic-password"); - let formID = uname.parentNode.id; - is(uname.value, expectedUsername, "Checking " + formID + " username"); - is(pword.value, expectedPassword, "Checking " + formID + " password"); -} -function* prepareLoginsAndProcessForm(url, logins = []) { - LoginManager.removeAllLogins(); - - let dates = Date.now(); - for (let login of logins) { - SpecialPowers.do_QueryInterface(login, SpecialPowers.Ci.nsILoginMetaInfo); - // Force all dates to be the same so they don't affect things like deduping. - login.timeCreated = login.timePasswordChanged = login.timeLastUsed = dates; - LoginManager.addLogin(login); - } - - iframe.src = url; - yield promiseFormsProcessed(); -} - -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({"set": [["signon.schemeUpgrades", true]]}); -}); - -add_task(function* test_simpleNoDupesNoAction() { - yield prepareLoginsAndProcessForm("https://example.com" + MISSING_ACTION_PATH, [ - new nsLoginInfo("http://example.com", "http://example.com", null, - "name2", "pass2", "uname", "pword"), - ]); - - checkACForm("name2", "pass2"); -}); - -add_task(function* test_simpleNoDupesUpgradeOriginAndAction() { - yield prepareLoginsAndProcessForm("https://example.com" + CROSS_ORIGIN_SECURE_PATH, [ - new nsLoginInfo("http://example.com", "http://another.domain", null, - "name2", "pass2", "uname", "pword"), - ]); - - checkACForm("name2", "pass2"); -}); - -add_task(function* test_simpleNoDupesUpgradeOriginOnly() { - yield prepareLoginsAndProcessForm("https://example.com" + CROSS_ORIGIN_SECURE_PATH, [ - new nsLoginInfo("http://example.com", "https://another.domain", null, - "name2", "pass2", "uname", "pword"), - ]); - - checkACForm("name2", "pass2"); -}); - -add_task(function* test_simpleNoDupesUpgradeActionOnly() { - yield prepareLoginsAndProcessForm("https://example.com" + CROSS_ORIGIN_SECURE_PATH, [ - new nsLoginInfo("https://example.com", "http://another.domain", null, - "name2", "pass2", "uname", "pword"), - ]); - - checkACForm("name2", "pass2"); -}); - -add_task(function* test_dedupe() { - yield prepareLoginsAndProcessForm("https://example.com" + MISSING_ACTION_PATH, [ - new nsLoginInfo("https://example.com", "https://example.com", null, - "name1", "passHTTPStoHTTPS", "uname", "pword"), - new nsLoginInfo("http://example.com", "http://example.com", null, - "name1", "passHTTPtoHTTP", "uname", "pword"), - new nsLoginInfo("http://example.com", "https://example.com", null, - "name1", "passHTTPtoHTTPS", "uname", "pword"), - new nsLoginInfo("https://example.com", "http://example.com", null, - "name1", "passHTTPStoHTTP", "uname", "pword"), - ]); - - checkACForm("name1", "passHTTPStoHTTPS"); -}); - -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_password-only.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_password-only.html deleted file mode 100644 index 983356371..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_autofill_password-only.html +++ /dev/null @@ -1,143 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test password-only forms should prefer a password-only login when present</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: Bug 444968 -<script> -let pwmgrCommonScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js")); -pwmgrCommonScript.sendSyncMessage("setupParent", { selfFilling: true }); - -SimpleTest.waitForExplicitFinish(); - -let chromeScript = runInParent(function chromeSetup() { - const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; - let pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); - - let login1A = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let login1B = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let login2A = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let login2B = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let login2C = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - - login1A.init("http://mochi.test:8888", "http://bug444968-1", null, - "testuser1A", "testpass1A", "", ""); - login1B.init("http://mochi.test:8888", "http://bug444968-1", null, - "", "testpass1B", "", ""); - - login2A.init("http://mochi.test:8888", "http://bug444968-2", null, - "testuser2A", "testpass2A", "", ""); - login2B.init("http://mochi.test:8888", "http://bug444968-2", null, - "", "testpass2B", "", ""); - login2C.init("http://mochi.test:8888", "http://bug444968-2", null, - "testuser2C", "testpass2C", "", ""); - - pwmgr.addLogin(login1A); - pwmgr.addLogin(login1B); - pwmgr.addLogin(login2A); - pwmgr.addLogin(login2B); - pwmgr.addLogin(login2C); - - addMessageListener("removeLogins", function removeLogins() { - pwmgr.removeLogin(login1A); - pwmgr.removeLogin(login1B); - pwmgr.removeLogin(login2A); - pwmgr.removeLogin(login2B); - pwmgr.removeLogin(login2C); - }); -}); - -SimpleTest.registerCleanupFunction(() => chromeScript.sendSyncMessage("removeLogins")); - -registerRunTests(); -</script> - -<p id="display"></p> -<div id="content" style="display: none"> - <!-- first 3 forms have matching user+pass and pass-only logins --> - - <!-- user+pass form. --> - <form id="form1" action="http://bug444968-1"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- password-only form. --> - <form id="form2" action="http://bug444968-1"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- user+pass form, username prefilled --> - <form id="form3" action="http://bug444968-1"> - <input type="text" name="uname" value="testuser1A"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - - <!-- next 4 forms have matching user+pass (2x) and pass-only (1x) logins --> - - <!-- user+pass form. --> - <form id="form4" action="http://bug444968-2"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- password-only form. --> - <form id="form5" action="http://bug444968-2"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- user+pass form, username prefilled --> - <form id="form6" action="http://bug444968-2"> - <input type="text" name="uname" value="testuser2A"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- user+pass form, username prefilled --> - <form id="form7" action="http://bug444968-2"> - <input type="text" name="uname" value="testuser2C"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - -</div> -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/* Test for Login Manager: 444968 (password-only forms should prefer a - * password-only login when present ) - */ -function startTest() { - checkForm(1, "testuser1A", "testpass1A"); - checkForm(2, "testpass1B"); - checkForm(3, "testuser1A", "testpass1A"); - - checkUnmodifiedForm(4); // 2 logins match - checkForm(5, "testpass2B"); - checkForm(6, "testuser2A", "testpass2A"); - checkForm(7, "testuser2C", "testpass2C"); - - SimpleTest.finish(); -} - -window.addEventListener("runTests", startTest); -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofocus_js.html b/toolkit/components/passwordmgr/test/mochitest/test_autofocus_js.html deleted file mode 100644 index 2ce3293dd..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_autofocus_js.html +++ /dev/null @@ -1,115 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test login autocomplete is activated when focused by js on load</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="satchel_common.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<script> -const chromeScript = runChecksAfterCommonInit(false); - -runInParent(function addLogins() { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - Cu.import("resource://gre/modules/Services.jsm"); - - // Create some logins just for this form, since we'll be deleting them. - let nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); - - let login0 = new nsLoginInfo("https://example.org", "https://example.org", null, - "name", "pass", "uname", "pword"); - - let login1 = new nsLoginInfo("https://example.org", "https://example.org", null, - "name1", "pass1", "uname", "pword"); - - try { - Services.logins.addLogin(login0); - Services.logins.addLogin(login1); - } catch (e) { - assert.ok(false, "addLogin threw: " + e); - } -}); -</script> -<p id="display"></p> - -<div id="content"> - <iframe src="https://example.org/tests/toolkit/components/passwordmgr/test/mochitest/form_autofocus_js.html"></iframe> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -let iframe = SpecialPowers.wrap(document.getElementsByTagName("iframe")[0]); -let iframeDoc; - -add_task(function* setup() { - yield new Promise(resolve => { - iframe.addEventListener("load", function onLoad() { - iframe.removeEventListener("load", onLoad); - resolve(); - }); - }); - - iframeDoc = iframe.contentDocument; - - SimpleTest.requestFlakyTimeout("Giving a chance for the unexpected popupshown to occur"); -}); - -add_task(function* test_initial_focus() { - let results = yield notifyMenuChanged(2, "name"); - checkArrayValues(results, ["name", "name1"], "Two results"); - doKey("down"); - doKey("return"); - yield promiseFormsProcessed(); - is(iframeDoc.getElementById("form-basic-password").value, "pass", "Check first password filled"); - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is now closed"); -}); - -// This depends on the filling from the previous test. -add_task(function* test_not_reopened_if_filled() { - listenForUnexpectedPopupShown(); - let usernameField = iframeDoc.getElementById("form-basic-username"); - usernameField.focus(); - info("Waiting to see if a popupshown occurs"); - yield new Promise(resolve => setTimeout(resolve, 1000)); - - // cleanup - gPopupShownExpected = true; - iframeDoc.getElementById("form-basic-submit").focus(); -}); - -add_task(function* test_reopened_after_edit_not_matching_saved() { - let usernameField = iframeDoc.getElementById("form-basic-username"); - usernameField.value = "nam"; - let shownPromise = promiseACShown(); - usernameField.focus(); - yield shownPromise; - iframeDoc.getElementById("form-basic-submit").focus(); -}); - -add_task(function* test_not_reopened_after_selecting() { - let formFillController = SpecialPowers.Cc["@mozilla.org/satchel/form-fill-controller;1"]. - getService(SpecialPowers.Ci.nsIFormFillController); - let usernameField = iframeDoc.getElementById("form-basic-username"); - usernameField.value = ""; - iframeDoc.getElementById("form-basic-password").value = ""; - listenForUnexpectedPopupShown(); - formFillController.markAsLoginManagerField(usernameField); - info("Waiting to see if a popupshown occurs"); - yield new Promise(resolve => setTimeout(resolve, 1000)); - - // Cleanup - gPopupShownExpected = true; -}); - -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form.html deleted file mode 100644 index 3c38343a5..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form.html +++ /dev/null @@ -1,44 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test basic autofill</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: simple form fill - -<script> -runChecksAfterCommonInit(startTest); - -/** Test for Login Manager: form fill, multiple forms. **/ - -function startTest() { - is($_(1, "uname").value, "testuser", "Checking for filled username"); - is($_(1, "pword").value, "testpass", "Checking for filled password"); - - SimpleTest.finish(); -} -</script> - -<p id="display"></p> - -<div id="content" style="display: none"> - - <form id="form1" action="formtest.js"> - <p>This is form 1.</p> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - -</div> - -<pre id="test"></pre> -</body> -</html> - diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_0pw.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_0pw.html deleted file mode 100644 index 0b416673b..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_0pw.html +++ /dev/null @@ -1,72 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test forms with no password fields</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: forms with no password fields -<p id="display"></p> - -<div id="content" style="display: none"> - - <!-- Form with no user field or password field --> - <form id="form1" action="formtest.js"> - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Form with no user field or password field, but one other field --> - <form id="form2" action="formtest.js"> - <input type="checkbox"> - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Form with no user field or password field, but one other field --> - <form id="form3" action="formtest.js"> - <input type="checkbox" name="uname" value=""> - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Form with a text field, but no password field --> - <form id="form4" action="formtest.js"> - <input type="text" name="yyyyy"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Form with a user field, but no password field --> - <form id="form5" action="formtest.js"> - <input type="text" name="uname"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: form fill, no password fields. **/ - -function startTest() { - is($_(3, "uname").value, "", "Checking for unfilled checkbox (form 3)"); - is($_(4, "yyyyy").value, "", "Checking for unfilled text field (form 4)"); - is($_(5, "uname").value, "", "Checking for unfilled text field (form 5)"); - - SimpleTest.finish(); -} - -runChecksAfterCommonInit(startTest); -</script> -</pre> -</body> -</html> - diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html deleted file mode 100644 index 3937fad4b..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html +++ /dev/null @@ -1,167 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test autofill for forms with 1 password field</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: forms with 1 password field -<script> -runChecksAfterCommonInit(() => startTest()); -</script> -<p id="display"></p> - -<div id="content" style="display: none"> - -<!-- no username fields --> - -<form id='form1' action='formtest.js'> 1 - <!-- Blank, so fill in the password --> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form2' action='formtest.js'> 2 - <!-- Already contains the password, so nothing to do. --> - <input type='password' name='pname' value='testpass'> - <button type='submit'>Submit</button> -</form> - -<form id='form3' action='formtest.js'> 3 - <!-- Contains unknown password, so don't change it --> - <input type='password' name='pname' value='xxxxxxxx'> - <button type='submit'>Submit</button> -</form> - - -<!-- username fields --> - -<form id='form4' action='formtest.js'> 4 - <!-- Blanks, so fill in login --> - <input type='text' name='uname' value=''> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form5' action='formtest.js'> 5 - <!-- Username already set, so fill in password --> - <input type='text' name='uname' value='testuser'> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form6' action='formtest.js'> 6 - <!-- Unknown username, so don't fill in password --> - <input type='text' name='uname' value='xxxxxxxx'> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form7' action='formtest.js'> 7 - <!-- Password already set, could fill in username but that's weird so we don't --> - <input type='text' name='uname' value=''> - <input type='password' name='pname' value='testpass'> - <button type='submit'>Submit</button> -</form> - -<form id='form8' action='formtest.js'> 8 - <!-- Unknown password, so don't fill in a username --> - <input type='text' name='uname' value=''> - <input type='password' name='pname' value='xxxxxxxx'> - <button type='submit'>Submit</button> -</form> - - - -<!-- extra text fields --> - -<form id='form9' action='formtest.js'> 9 - <!-- text field _after_ password should never be treated as a username field --> - <input type='password' name='pname' value=''> - <input type='text' name='uname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form10' action='formtest.js'> 10 - <!-- only the first text field before the password should be for username --> - <input type='text' name='other' value=''> - <input type='text' name='uname' value=''> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form11' action='formtest.js'> 11 - <!-- variation just to make sure extra text field is still ignored --> - <input type='text' name='uname' value=''> - <input type='password' name='pname' value=''> - <input type='text' name='other' value=''> - <button type='submit'>Submit</button> -</form> - - - -<!-- same as last bunch, but with xxxx in the extra field. --> - -<form id='form12' action='formtest.js'> 12 - <!-- text field _after_ password should never be treated as a username field --> - <input type='password' name='pname' value=''> - <input type='text' name='uname' value='xxxxxxxx'> - <button type='submit'>Submit</button> -</form> - -<form id='form13' action='formtest.js'> 13 - <!-- only the first text field before the password should be for username --> - <input type='text' name='other' value='xxxxxxxx'> - <input type='text' name='uname' value=''> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form14' action='formtest.js'> 14 - <!-- variation just to make sure extra text field is still ignored --> - <input type='text' name='uname' value=''> - <input type='password' name='pname' value=''> - <input type='text' name='other' value='xxxxxxxx'> - <button type='submit'>Submit</button> -</form> - - -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: simple form fill **/ - -function startTest() { - var f = 1; - - // 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"); - - // 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(); -} -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw_2.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw_2.html deleted file mode 100644 index 0f6566b9c..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw_2.html +++ /dev/null @@ -1,109 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test forms with 1 password field, part 2</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: forms with 1 password field, part 2 -<script> -runChecksAfterCommonInit(() => startTest()); -</script> -<p id="display"></p> - -<div id="content" style="display: none"> - -<form id='form1' action='formtest.js'> 1 - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form2' action='formtest.js'> 2 - <input type='password' name='pname' value='' disabled> - <button type='submit'>Submit</button> -</form> - -<form id='form3' action='formtest.js'> 3 - <input type='password' name='pname' value='' readonly> - <button type='submit'>Submit</button> -</form> - -<form id='form4' action='formtest.js'> 4 - <input type='text' name='uname' value=''> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form5' action='formtest.js'> 5 - <input type='text' name='uname' value='' disabled> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form6' action='formtest.js'> 6 - <input type='text' name='uname' value='' readonly> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form7' action='formtest.js'> 7 - <input type='text' name='uname' value=''> - <input type='password' name='pname' value='' disabled> - <button type='submit'>Submit</button> -</form> - -<form id='form8' action='formtest.js'> 8 - <input type='text' name='uname' value=''> - <input type='password' name='pname' value='' readonly> - <button type='submit'>Submit</button> -</form> - -<form id='form9' action='formtest.js'> 9 - <input type='text' name='uname' value='TESTUSER'> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form10' action='formtest.js'> 10 - <input type='text' name='uname' value='TESTUSER' readonly> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form11' action='formtest.js'> 11 - <input type='text' name='uname' value='TESTUSER' disabled> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: simple form fill, part 2 **/ - -function startTest() { - 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"); - - SimpleTest.finish(); -} -</script> -</pre> -</body> -</html> - diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_1.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_1.html deleted file mode 100644 index 128ffca7c..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_1.html +++ /dev/null @@ -1,187 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test autofill for forms with 2 password fields</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: forms with 2 password fields -<script> -runChecksAfterCommonInit(() => startTest()); -</script> -<p id="display"></p> - -<div id="content" style="display: none"> - - -<!-- no username fields --> - -<form id='form1' action='formtest.js'> 1 - <!-- simple form, fill in first pw --> - <input type='password' name='pname' value=''> - <input type='password' name='qname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form2' action='formtest.js'> 2 - <!-- same but reverse pname and qname, field names are ignored. --> - <input type='password' name='qname' value=''> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form3' action='formtest.js'> 3 - <!-- text field after password fields should be ignored, no username. --> - <input type='password' name='pname' value=''> - <input type='password' name='qname' value=''> - <input type='text' name='uname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form4' action='formtest.js'> 4 - <!-- nothing to do, password already present --> - <input type='password' name='pname' value='testpass'> - <input type='password' name='qname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form5' action='formtest.js'> 5 - <!-- don't clobber an existing unrecognized password --> - <input type='password' name='pname' value='xxxxxxxx'> - <input type='password' name='qname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form6' action='formtest.js'> 6 - <!-- fill in first field, 2nd field shouldn't be touched anyway. --> - <input type='password' name='pname' value=''> - <input type='password' name='qname' value='xxxxxxxx'> - <button type='submit'>Submit</button> -</form> - - - -<!-- with username fields --> - - - -<form id='form7' action='formtest.js'> 7 - <!-- simple form, should fill in username and first pw --> - <input type='text' name='uname' value=''> - <input type='password' name='pname' value=''> - <input type='password' name='qname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form8' action='formtest.js'> 8 - <!-- reverse pname and qname, field names are ignored. --> - <input type='text' name='uname' value=''> - <input type='password' name='qname' value=''> - <input type='password' name='pname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form9' action='formtest.js'> 9 - <!-- username already filled, so just fill first password --> - <input type='text' name='uname' value='testuser'> - <input type='password' name='pname' value=''> - <input type='password' name='qname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form10' action='formtest.js'> 10 - <!-- unknown username, don't fill in a password --> - <input type='text' name='uname' value='xxxxxxxx'> - <input type='password' name='pname' value=''> - <input type='password' name='qname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form11' action='formtest.js'> 11 - <!-- don't clobber unknown password --> - <input type='text' name='uname' value='testuser'> - <input type='password' name='pname' value='xxxxxxxx'> - <input type='password' name='qname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form12' action='formtest.js'> 12 - <!-- fill in 1st pass, don't clobber 2nd pass --> - <input type='text' name='uname' value='testuser'> - <input type='password' name='pname' value=''> - <input type='password' name='qname' value='xxxxxxxx'> - <button type='submit'>Submit</button> -</form> - -<form id='form13' action='formtest.js'> 13 - <!-- nothing to do, user and pass prefilled. life is easy. --> - <input type='text' name='uname' value='testuser'> - <input type='password' name='pname' value='testpass'> - <input type='password' name='qname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form14' action='formtest.js'> 14 - <!-- shouldn't fill in username because 1st pw field is unknown. --> - <input type='text' name='uname' value=''> - <input type='password' name='pname' value='xxxxxxxx'> - <input type='password' name='qname' value='testpass'> - <button type='submit'>Submit</button> -</form> - -<form id='form15' action='formtest.js'> 15 - <!-- textfield in the middle of pw fields should be ignored --> - <input type='password' name='pname' value=''> - <input type='text' name='uname' value=''> - <input type='password' name='qname' value=''> - <button type='submit'>Submit</button> -</form> - -<form id='form16' action='formtest.js'> 16 - <!-- same, and don't clobber existing unknown password --> - <input type='password' name='pname' value='xxxxxxxx'> - <input type='text' name='uname' value=''> - <input type='password' name='qname' value=''> - <button type='submit'>Submit</button> -</form> - - -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: simple form fill **/ - -function startTest() { - 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"); - - // 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(); -} -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_2.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_2.html deleted file mode 100644 index eba811cf9..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_2.html +++ /dev/null @@ -1,105 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test for form fill with 2 password fields</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: form fill, 2 password fields -<p id="display"></p> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: form fill, 2 password fields **/ - -/* - * If a form has two password fields, other things may be going on.... - * - * 1 - The user might be creating a new login (2nd field for typo checking) - * 2 - The user is changing a password (old and new password each have field) - * - * This test is for case #1. - */ - -var numSubmittedForms = 0; -var numStartingLogins = 0; - -function startTest() { - // Check for unfilled forms - is($_(1, "uname").value, "", "Checking username 1"); - is($_(1, "pword").value, "", "Checking password 1A"); - is($_(1, "qword").value, "", "Checking password 1B"); - - // Fill in the username and password fields, for account creation. - // Form 1 - $_(1, "uname").value = "newuser1"; - $_(1, "pword").value = "newpass1"; - $_(1, "qword").value = "newpass1"; - - var button = getFormSubmitButton(1); - - todo(false, "form submission disabled, can't auto-accept dialog yet"); - SimpleTest.finish(); -} - - -// Called by each form's onsubmit handler. -function checkSubmit(formNum) { - numSubmittedForms++; - - // End the test at the last form. - if (formNum == 999) { - is(numSubmittedForms, 999, "Ensuring all forms submitted for testing."); - - var numEndingLogins = LoginManager.countLogins("", "", ""); - - ok(numEndingLogins > 0, "counting logins at end"); - is(numStartingLogins, numEndingLogins + 222, "counting logins at end"); - - SimpleTest.finish(); - return false; // return false to cancel current form submission - } - - // submit the next form. - var button = getFormSubmitButton(formNum + 1); - button.click(); - - return false; // return false to cancel current form submission -} - - -function getFormSubmitButton(formNum) { - var form = $("form" + formNum); // by id, not name - ok(form != null, "getting form " + formNum); - - // we can't just call form.submit(), because that doesn't seem to - // invoke the form onsubmit handler. - var button = form.firstChild; - while (button && button.type != "submit") { button = button.nextSibling; } - ok(button != null, "getting form submit button"); - - return button; -} - -runChecksAfterCommonInit(startTest); - -</script> -</pre> -<div id="content" style="display: none"> - <form id="form1" onsubmit="return checkSubmit(1)" action="http://newuser.com"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <input type="password" name="qword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - -</div> - -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_3pw_1.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_3pw_1.html deleted file mode 100644 index 30b5a319f..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_3pw_1.html +++ /dev/null @@ -1,177 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test autofill for forms with 3 password fields</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: forms with 3 password fields (form filling) -<script> -runChecksAfterCommonInit(() => startTest()); -</script> -<p id="display"></p> - -<div id="content" style="display: none"> - <p>The next three forms are <b>user/pass/passB/passC</b>, as all-empty, preuser(only), and preuser/pass</p> - <form id="form1" action="formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <input type="password" name="qword"> - <input type="password" name="rword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <form id="form2" action="formtest.js"> - <input type="text" name="uname" value="testuser"> - <input type="password" name="pword"> - <input type="password" name="qword"> - <input type="password" name="rword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <form id="form3" action="formtest.js"> - <input type="text" name="uname" value="testuser"> - <input type="password" name="pword" value="testpass"> - <input type="password" name="qword"> - <input type="password" name="rword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - - <p>The next three forms are <b>user/passB/pass/passC</b>, as all-empty, preuser(only), and preuser/pass</p> - <form id="form4" action="formtest.js"> - <input type="text" name="uname"> - <input type="password" name="qword"> - <input type="password" name="pword"> - <input type="password" name="rword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <form id="form5" action="formtest.js"> - <input type="text" name="uname" value="testuser"> - <input type="password" name="qword"> - <input type="password" name="pword"> - <input type="password" name="rword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <form id="form6" action="formtest.js"> - <input type="text" name="uname" value="testuser"> - <input type="password" name="qword"> - <input type="password" name="pword" value="testpass"> - <input type="password" name="rword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <p>The next three forms are <b>user/passB/passC/pass</b>, as all-empty, preuser(only), and preuser/pass</p> - <form id="form7" action="formtest.js"> - <input type="text" name="uname"> - <input type="password" name="qword"> - <input type="password" name="rword"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <form id="form8" action="formtest.js"> - <input type="text" name="uname" value="testuser"> - <input type="password" name="qword"> - <input type="password" name="rword"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <form id="form9" action="formtest.js"> - <input type="text" name="uname" value="testuser"> - <input type="password" name="qword"> - <input type="password" name="rword"> - <input type="password" name="pword" value="testpass"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: form fill, 3 password fields **/ - -// Test to make sure 3-password forms are filled properly. - -function startTest() { - // Check form 1 - is($_(1, "uname").value, "testuser", "Checking username 1"); - is($_(1, "pword").value, "testpass", "Checking password 1"); - is($_(1, "qword").value, "", "Checking password 1 (q)"); - is($_(1, "rword").value, "", "Checking password 1 (r)"); - // Check form 2 - is($_(2, "uname").value, "testuser", "Checking username 2"); - is($_(2, "pword").value, "testpass", "Checking password 2"); - is($_(2, "qword").value, "", "Checking password 2 (q)"); - is($_(2, "rword").value, "", "Checking password 2 (r)"); - // Check form 3 - is($_(3, "uname").value, "testuser", "Checking username 3"); - is($_(3, "pword").value, "testpass", "Checking password 3"); - is($_(3, "qword").value, "", "Checking password 3 (q)"); - is($_(3, "rword").value, "", "Checking password 3 (r)"); - - // Check form 4 - is($_(4, "uname").value, "testuser", "Checking username 4"); - todo_is($_(4, "qword").value, "", "Checking password 4 (q)"); - todo_is($_(4, "pword").value, "testpass", "Checking password 4"); - is($_(4, "rword").value, "", "Checking password 4 (r)"); - // Check form 5 - is($_(5, "uname").value, "testuser", "Checking username 5"); - todo_is($_(5, "qword").value, "", "Checking password 5 (q)"); - todo_is($_(5, "pword").value, "testpass", "Checking password 5"); - is($_(5, "rword").value, "", "Checking password 5 (r)"); - // Check form 6 - is($_(6, "uname").value, "testuser", "Checking username 6"); - todo_is($_(6, "qword").value, "", "Checking password 6 (q)"); - is($_(6, "pword").value, "testpass", "Checking password 6"); - is($_(6, "rword").value, "", "Checking password 6 (r)"); - - // Check form 7 - is($_(7, "uname").value, "testuser", "Checking username 7"); - todo_is($_(7, "qword").value, "", "Checking password 7 (q)"); - is($_(7, "rword").value, "", "Checking password 7 (r)"); - todo_is($_(7, "pword").value, "testpass", "Checking password 7"); - // Check form 8 - is($_(8, "uname").value, "testuser", "Checking username 8"); - todo_is($_(8, "qword").value, "", "Checking password 8 (q)"); - is($_(8, "rword").value, "", "Checking password 8 (r)"); - todo_is($_(8, "pword").value, "testpass", "Checking password 8"); - // Check form 9 - is($_(9, "uname").value, "testuser", "Checking username 9"); - todo_is($_(9, "qword").value, "", "Checking password 9 (q)"); - is($_(9, "rword").value, "", "Checking password 9 (r)"); - is($_(9, "pword").value, "testpass", "Checking password 9"); - - // TODO: as with the 2-password cases, add tests to check for creating new - // logins and changing passwords. - SimpleTest.finish(); -} -</script> -</pre> -</body> -</html> - diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html deleted file mode 100644 index 0eee8e696..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_autocomplete.html +++ /dev/null @@ -1,859 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test basic login autocomplete</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="satchel_common.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: multiple login autocomplete - -<script> -var chromeScript = runChecksAfterCommonInit(); - -var setupScript = runInParent(function setup() { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - Cu.import("resource://gre/modules/Services.jsm"); - - // Create some logins just for this form, since we'll be deleting them. - var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); - assert.ok(nsLoginInfo != null, "nsLoginInfo constructor"); - - // login0 has no username, so should be filtered out from the autocomplete list. - var login0 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "", "user0pass", "", "pword"); - - var login1 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "tempuser1", "temppass1", "uname", "pword"); - - var login2 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "testuser2", "testpass2", "uname", "pword"); - - var login3 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "testuser3", "testpass3", "uname", "pword"); - - var login4 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "zzzuser4", "zzzpass4", "uname", "pword"); - - // login 5 only used in the single-user forms - var login5 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete2", null, - "singleuser5", "singlepass5", "uname", "pword"); - - var login6A = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete3", null, - "form7user1", "form7pass1", "uname", "pword"); - var login6B = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete3", null, - "form7user2", "form7pass2", "uname", "pword"); - - var login7 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete4", null, - "form8user", "form8pass", "uname", "pword"); - - var login8A = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null, - "form9userAB", "form9pass", "uname", "pword"); - var login8B = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null, - "form9userAAB", "form9pass", "uname", "pword"); - var login8C = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null, - "form9userAABzz", "form9pass", "uname", "pword"); - - var login10 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete7", null, - "testuser10", "testpass10", "uname", "pword"); - - - // try/catch in case someone runs the tests manually, twice. - try { - Services.logins.addLogin(login0); - Services.logins.addLogin(login1); - Services.logins.addLogin(login2); - Services.logins.addLogin(login3); - Services.logins.addLogin(login4); - Services.logins.addLogin(login5); - Services.logins.addLogin(login6A); - Services.logins.addLogin(login6B); - Services.logins.addLogin(login7); - Services.logins.addLogin(login8A); - Services.logins.addLogin(login8B); - // login8C is added later - Services.logins.addLogin(login10); - } catch (e) { - assert.ok(false, "addLogin threw: " + e); - } - - addMessageListener("addLogin", loginVariableName => { - let login = eval(loginVariableName); - assert.ok(!!login, "Login to add is defined: " + loginVariableName); - Services.logins.addLogin(login); - }); - addMessageListener("removeLogin", loginVariableName => { - let login = eval(loginVariableName); - assert.ok(!!login, "Login to delete is defined: " + loginVariableName); - Services.logins.removeLogin(login); - }); -}); -</script> -<p id="display"></p> - -<!-- we presumably can't hide the content for this test. --> -<div id="content"> - - <!-- form1 tests multiple matching logins --> - <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- other forms test single logins, with autocomplete=off set --> - <form id="form2" action="http://autocomplete2" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword" autocomplete="off"> - <button type="submit">Submit</button> - </form> - - <form id="form3" action="http://autocomplete2" onsubmit="return false;"> - <input type="text" name="uname" autocomplete="off"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form4" action="http://autocomplete2" onsubmit="return false;" autocomplete="off"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form5" action="http://autocomplete2" onsubmit="return false;"> - <input type="text" name="uname" autocomplete="off"> - <input type="password" name="pword" autocomplete="off"> - <button type="submit">Submit</button> - </form> - - <!-- control --> - <form id="form6" action="http://autocomplete2" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- This form will be manipulated to insert a different username field. --> - <form id="form7" action="http://autocomplete3" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- test for no autofill after onblur with blank username --> - <form id="form8" action="http://autocomplete4" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- test autocomplete dropdown --> - <form id="form9" action="http://autocomplete5" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- test for onUsernameInput recipe testing --> - <form id="form11" action="http://autocomplete7" onsubmit="return false;"> - <input type="text" name="1"> - <input type="text" name="2"> - <button type="submit">Submit</button> - </form> - - <!-- tests <form>-less autocomplete --> - <div id="form12"> - <input type="text" name="uname" id="uname"> - <input type="password" name="pword" id="pword"> - <button type="submit">Submit</button> - </div> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: multiple login autocomplete. **/ - -var uname = $_(1, "uname"); -var pword = $_(1, "pword"); -const shiftModifier = SpecialPowers.Ci.nsIDOMEvent.SHIFT_MASK; - -// Restore the form to the default state. -function restoreForm() { - uname.value = ""; - pword.value = ""; - uname.focus(); -} - -// Check for expected username/password in form. -function checkACForm(expectedUsername, expectedPassword) { - var formID = uname.parentNode.id; - is(uname.value, expectedUsername, "Checking " + formID + " username is: " + expectedUsername); - is(pword.value, expectedPassword, "Checking " + formID + " password is: " + expectedPassword); -} - -function sendFakeAutocompleteEvent(element) { - var acEvent = document.createEvent("HTMLEvents"); - acEvent.initEvent("DOMAutoComplete", true, false); - element.dispatchEvent(acEvent); -} - -function spinEventLoop() { - return Promise.resolve(); -} - -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({"set": [["security.insecure_field_warning.contextual.enabled", false], - ["signon.autofillForms.http", true]]}); - listenForUnexpectedPopupShown(); -}); - -add_task(function* test_form1_initial_empty() { - yield SimpleTest.promiseFocus(window); - - // Make sure initial form is empty. - checkACForm("", ""); - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is initially closed"); -}); - -add_task(function* test_form1_menuitems() { - yield SimpleTest.promiseFocus(window); - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - let results = yield shownPromise; - - let popupState = yield getPopupState(); - is(popupState.selectedIndex, -1, "Check no entries are selected upon opening"); - - let expectedMenuItems = ["tempuser1", - "testuser2", - "testuser3", - "zzzuser4"]; - checkArrayValues(results, expectedMenuItems, "Check all menuitems are displayed correctly."); - - checkACForm("", ""); // value shouldn't update just by selecting - doKey("return"); // not "enter"! - yield spinEventLoop(); // let focus happen - checkACForm("", ""); -}); - -add_task(function* test_form1_first_entry() { - yield SimpleTest.promiseFocus(window); - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - let popupState = yield getPopupState(); - is(popupState.selectedIndex, -1, "Check no entries are selected upon opening"); - - doKey("down"); // first - checkACForm("", ""); // value shouldn't update just by selecting - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("tempuser1", "temppass1"); -}); - -add_task(function* test_form1_second_entry() { - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // first - doKey("down"); // second - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_third_entry() { - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // first - doKey("down"); // second - doKey("down"); // third - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser3", "testpass3"); -}); - -add_task(function* test_form1_fourth_entry() { - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // first - doKey("down"); // second - doKey("down"); // third - doKey("down"); // fourth - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_wraparound_first_entry() { - // Trigger autocomplete popup - restoreForm(); - yield spinEventLoop(); // let focus happen - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // first - doKey("down"); // second - doKey("down"); // third - doKey("down"); // fourth - doKey("down"); // deselects - doKey("down"); // first - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("tempuser1", "temppass1"); -}); - -add_task(function* test_form1_wraparound_up_last_entry() { - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("up"); // last (fourth) - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_wraparound_down_up_up() { - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // select first entry - doKey("up"); // selects nothing! - doKey("up"); // select last entry - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_wraparound_up_last() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); - doKey("up"); // deselects - doKey("up"); // last entry - doKey("up"); - doKey("up"); - doKey("up"); // first entry - doKey("up"); // deselects - doKey("up"); // last entry - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_fill_username_without_autofill_right() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Set first entry w/o triggering autocomplete - doKey("down"); // first - doKey("right"); - yield spinEventLoop(); - checkACForm("tempuser1", ""); // empty password -}); - -add_task(function* test_form1_fill_username_without_autofill_left() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Set first entry w/o triggering autocomplete - doKey("down"); // first - doKey("left"); - checkACForm("tempuser1", ""); // empty password -}); - -add_task(function* test_form1_pageup_first() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Check first entry (page up) - doKey("down"); // first - doKey("down"); // second - doKey("page_up"); // first - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("tempuser1", "temppass1"); -}); - -add_task(function* test_form1_pagedown_last() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - /* test 13 */ - // Check last entry (page down) - doKey("down"); // first - doKey("page_down"); // last - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_untrusted_event() { - restoreForm(); - yield spinEventLoop(); - - // Send a fake (untrusted) event. - checkACForm("", ""); - uname.value = "zzzuser4"; - sendFakeAutocompleteEvent(uname); - yield spinEventLoop(); - checkACForm("zzzuser4", ""); -}); - -add_task(function* test_form1_delete() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // XXX tried sending character "t" before/during dropdown to test - // filtering, but had no luck. Seemed like the character was getting lost. - // Setting uname.value didn't seem to work either. This works with a human - // driver, so I'm not sure what's up. - - // Delete the first entry (of 4), "tempuser1" - doKey("down"); - var numLogins; - numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); - is(numLogins, 5, "Correct number of logins before deleting one"); - - let countChangedPromise = notifyMenuChanged(3); - var deletionPromise = promiseStorageChanged(["removeLogin"]); - // On OS X, shift-backspace and shift-delete work, just delete does not. - // On Win/Linux, shift-backspace does not work, delete and shift-delete do. - doKey("delete", shiftModifier); - yield deletionPromise; - - checkACForm("", ""); - numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); - is(numLogins, 4, "Correct number of logins after deleting one"); - yield countChangedPromise; - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_first_after_deletion() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Check the new first entry (of 3) - doKey("down"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_delete_second() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Delete the second entry (of 3), "testuser3" - doKey("down"); - doKey("down"); - doKey("delete", shiftModifier); - checkACForm("", ""); - numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); - is(numLogins, 3, "Correct number of logins after deleting one"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_first_after_deletion2() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Check the new first entry (of 2) - doKey("down"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_delete_last() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - /* test 54 */ - // Delete the last entry (of 2), "zzzuser4" - doKey("down"); - doKey("down"); - doKey("delete", shiftModifier); - checkACForm("", ""); - numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); - is(numLogins, 2, "Correct number of logins after deleting one"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_first_after_3_deletions() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Check the only remaining entry - doKey("down"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_check_only_entry_remaining() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - /* test 56 */ - // Delete the only remaining entry, "testuser2" - doKey("down"); - doKey("delete", shiftModifier); - checkACForm("", ""); - numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); - is(numLogins, 1, "Correct number of logins after deleting one"); - - // remove the login that's not shown in the list. - setupScript.sendSyncMessage("removeLogin", "login0"); -}); - -/* Tests for single-user forms for ignoring autocomplete=off */ -add_task(function* test_form2() { - // Turn our attention to form2 - uname = $_(2, "uname"); - pword = $_(2, "pword"); - checkACForm("singleuser5", "singlepass5"); - - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Check first entry - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("singleuser5", "singlepass5"); -}); - -add_task(function* test_form3() { - uname = $_(3, "uname"); - pword = $_(3, "pword"); - checkACForm("singleuser5", "singlepass5"); - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Check first entry - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("singleuser5", "singlepass5"); -}); - -add_task(function* test_form4() { - uname = $_(4, "uname"); - pword = $_(4, "pword"); - checkACForm("singleuser5", "singlepass5"); - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Check first entry - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("singleuser5", "singlepass5"); -}); - -add_task(function* test_form5() { - uname = $_(5, "uname"); - pword = $_(5, "pword"); - checkACForm("singleuser5", "singlepass5"); - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Check first entry - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("singleuser5", "singlepass5"); -}); - -add_task(function* test_form6() { - // (this is a control, w/o autocomplete=off, to ensure the login - // that was being suppressed would have been filled in otherwise) - uname = $_(6, "uname"); - pword = $_(6, "pword"); - checkACForm("singleuser5", "singlepass5"); -}); - -add_task(function* test_form6_changeUsername() { - // Test that the password field remains filled in after changing - // the username. - uname.focus(); - doKey("right"); - sendChar("X"); - // Trigger the 'blur' event on uname - pword.focus(); - yield spinEventLoop(); - checkACForm("singleuser5X", "singlepass5"); - - setupScript.sendSyncMessage("removeLogin", "login5"); -}); - -add_task(function* test_form7() { - uname = $_(7, "uname"); - pword = $_(7, "pword"); - checkACForm("", ""); - - // Insert a new username field into the form. We'll then make sure - // that invoking the autocomplete doesn't try to fill the form. - var newField = document.createElement("input"); - newField.setAttribute("type", "text"); - newField.setAttribute("name", "uname2"); - pword.parentNode.insertBefore(newField, pword); - is($_(7, "uname2").value, "", "Verifying empty uname2"); - - // Delete login6B. It was created just to prevent filling in a login - // automatically, removing it makes it more likely that we'll catch a - // future regression with form filling here. - setupScript.sendSyncMessage("removeLogin", "login6B"); -}); - -add_task(function* test_form7_2() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Check first entry - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - // The form changes, so we expect the old username field to get the - // selected autocomplete value, but neither the new username field nor - // the password field should have any values filled in. - yield spinEventLoop(); - checkACForm("form7user1", ""); - is($_(7, "uname2").value, "", "Verifying empty uname2"); - restoreForm(); // clear field, so reloading test doesn't fail - - setupScript.sendSyncMessage("removeLogin", "login6A"); -}); - -add_task(function* test_form8() { - uname = $_(8, "uname"); - pword = $_(8, "pword"); - checkACForm("form8user", "form8pass"); - restoreForm(); -}); - -add_task(function* test_form8_blur() { - checkACForm("", ""); - // Focus the previous form to trigger a blur. - $_(7, "uname").focus(); -}); - -add_task(function* test_form8_2() { - checkACForm("", ""); - restoreForm(); -}); - -add_task(function* test_form8_3() { - checkACForm("", ""); - setupScript.sendSyncMessage("removeLogin", "login7"); -}); - -add_task(function* test_form9_filtering() { - // Turn our attention to form9 to test the dropdown - bug 497541 - uname = $_(9, "uname"); - pword = $_(9, "pword"); - uname.focus(); - let shownPromise = promiseACShown(); - sendString("form9userAB"); - yield shownPromise; - - checkACForm("form9userAB", ""); - uname.focus(); - doKey("left"); - shownPromise = promiseACShown(); - sendChar("A"); - let results = yield shownPromise; - - checkACForm("form9userAAB", ""); - checkArrayValues(results, ["form9userAAB"], "Check dropdown is updated after inserting 'A'"); - doKey("down"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("form9userAAB", "form9pass"); -}); - -add_task(function* test_form9_autocomplete_cache() { - // Note that this addLogin call will only be seen by the autocomplete - // attempt for the sendChar if we do not successfully cache the - // autocomplete results. - setupScript.sendSyncMessage("addLogin", "login8C"); - uname.focus(); - let promise0 = notifyMenuChanged(0); - sendChar("z"); - yield promise0; - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup shouldn't open"); - - // check that empty results are cached - bug 496466 - promise0 = notifyMenuChanged(0); - sendChar("z"); - yield promise0; - popupState = yield getPopupState(); - is(popupState.open, false, "Check popup stays closed due to cached empty result"); -}); - -add_task(function* test_form11_recipes() { - yield loadRecipes({ - siteRecipes: [{ - "hosts": ["mochi.test:8888"], - "usernameSelector": "input[name='1']", - "passwordSelector": "input[name='2']" - }], - }); - uname = $_(11, "1"); - pword = $_(11, "2"); - - // First test DOMAutocomplete - // Switch the password field to type=password so _fillForm marks the username - // field for autocomplete. - pword.type = "password"; - yield promiseFormsProcessed(); - restoreForm(); - checkACForm("", ""); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("testuser10", "testpass10"); - - // Now test recipes with blur on the username field. - restoreForm(); - checkACForm("", ""); - uname.value = "testuser10"; - checkACForm("testuser10", ""); - doKey("tab"); - yield promiseFormsProcessed(); - checkACForm("testuser10", "testpass10"); - yield resetRecipes(); -}); - -add_task(function* test_form12_formless() { - // Test form-less autocomplete - uname = $_(12, "uname"); - pword = $_(12, "pword"); - restoreForm(); - checkACForm("", ""); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Trigger autocomplete - doKey("down"); - checkACForm("", ""); // value shouldn't update - let processedPromise = promiseFormsProcessed(); - doKey("return"); // not "enter"! - yield processedPromise; - checkACForm("testuser", "testpass"); -}); - -add_task(function* test_form12_open_on_trusted_focus() { - uname = $_(12, "uname"); - pword = $_(12, "pword"); - uname.value = ""; - pword.value = ""; - - // Move focus to the password field so we can test the first click on the - // username field. - pword.focus(); - checkACForm("", ""); - const firePrivEventPromise = new Promise((resolve) => { - uname.addEventListener("click", (e) => { - ok(e.isTrusted, "Ensure event is trusted"); - resolve(); - }); - }); - const shownPromise = promiseACShown(); - synthesizeMouseAtCenter(uname, {}); - yield firePrivEventPromise; - yield shownPromise; - doKey("down"); - const processedPromise = promiseFormsProcessed(); - doKey("return"); // not "enter"! - yield processedPromise; - checkACForm("testuser", "testpass"); -}); -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_html5.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_html5.html deleted file mode 100644 index 40e322afd..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_html5.html +++ /dev/null @@ -1,164 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test for html5 input types (email, tel, url, etc.)</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: html5 input types (email, tel, url, etc.) -<script> -runChecksAfterCommonInit(() => startTest()); - -runInParent(function setup() { - const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; - let pwmgr = Cc["@mozilla.org/login-manager;1"]. - getService(Ci.nsILoginManager); - - login1 = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2 = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login3 = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login4 = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - - login1.init("http://mochi.test:8888", "http://bug600551-1", null, - "testuser@example.com", "testpass1", "", ""); - login2.init("http://mochi.test:8888", "http://bug600551-2", null, - "555-555-5555", "testpass2", "", ""); - login3.init("http://mochi.test:8888", "http://bug600551-3", null, - "http://mozilla.org", "testpass3", "", ""); - login4.init("http://mochi.test:8888", "http://bug600551-4", null, - "123456789", "testpass4", "", ""); - - pwmgr.addLogin(login1); - pwmgr.addLogin(login2); - pwmgr.addLogin(login3); - pwmgr.addLogin(login4); -}); -</script> - -<p id="display"></p> -<div id="content" style="display: none"> - - <form id="form1" action="http://bug600551-1"> - <input type="email" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form2" action="http://bug600551-2"> - <input type="tel" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form3" action="http://bug600551-3"> - <input type="url" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form4" action="http://bug600551-4"> - <input type="number" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- The following forms should not be filled with usernames --> - <form id="form5" action="formtest.js"> - <input type="search" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form6" action="formtest.js"> - <input type="datetime" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form7" action="formtest.js"> - <input type="date" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form8" action="formtest.js"> - <input type="month" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form9" action="formtest.js"> - <input type="week" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form10" action="formtest.js"> - <input type="time" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form11" action="formtest.js"> - <input type="datetime-local" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form12" action="formtest.js"> - <input type="range" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form13" action="formtest.js"> - <input type="color" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - -</div> -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/* Test for Login Manager: 600551 - (Password manager not working with input type=email) - */ -function startTest() { - checkForm(1, "testuser@example.com", "testpass1"); - checkForm(2, "555-555-5555", "testpass2"); - checkForm(3, "http://mozilla.org", "testpass3"); - checkForm(4, "123456789", "testpass4"); - - is($_(5, "uname").value, "", "type=search should not be considered a username"); - - is($_(6, "uname").value, "", "type=datetime should not be considered a username"); - - is($_(7, "uname").value, "", "type=date should not be considered a username"); - - is($_(8, "uname").value, "", "type=month should not be considered a username"); - - is($_(9, "uname").value, "", "type=week should not be considered a username"); - - is($_(10, "uname").value, "", "type=time should not be considered a username"); - - is($_(11, "uname").value, "", "type=datetime-local should not be considered a username"); - - is($_(12, "uname").value, "50", "type=range should not be considered a username"); - - is($_(13, "uname").value, "#000000", "type=color should not be considered a username"); - - SimpleTest.finish(); -} -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwevent.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwevent.html deleted file mode 100644 index e0a2883c8..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwevent.html +++ /dev/null @@ -1,55 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=355063 ---> -<head> - <meta charset="utf-8"/> - <title>Test for Bug 355063</title> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="text/javascript" src="pwmgr_common.js"></script> - <script type="application/javascript"> - /** Test for Bug 355063 **/ - - runChecksAfterCommonInit(function startTest() { - info("startTest"); - // Password Manager's own listener should always have been added first, so - // the test's listener should be called after the pwmgr's listener fills in - // a login. - // - SpecialPowers.addChromeEventListener("DOMFormHasPassword", function eventFired() { - SpecialPowers.removeChromeEventListener("DOMFormHasPassword", eventFired); - var passField = $("p1"); - passField.addEventListener("input", checkForm); - }); - addForm(); - }); - - function addForm() { - info("addForm"); - var c = document.getElementById("content"); - c.innerHTML = "<form id=form1>form1: <input id=u1><input type=password id=p1></form><br>"; - } - - function checkForm() { - info("checkForm"); - var userField = document.getElementById("u1"); - var passField = document.getElementById("p1"); - is(userField.value, "testuser", "checking filled username"); - is(passField.value, "testpass", "checking filled password"); - - SimpleTest.finish(); - } -</script> -</head> -<body> -<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=355063">Mozilla Bug 355063</a> -<p id="display"></p> -<div id="content"> -forms go here! -</div> -<pre id="test"> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwonly.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwonly.html deleted file mode 100644 index 40fec8c46..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwonly.html +++ /dev/null @@ -1,213 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test forms and logins without a username</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: forms and logins without a username. -<script> -runChecksAfterCommonInit(() => startTest()); -runInParent(() => { - const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; - var pwmgr = Cc["@mozilla.org/login-manager;1"] - .getService(Ci.nsILoginManager); - - var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo); - - // pwlogin1 uses a unique formSubmitURL, to check forms where no other logins - // will apply. pwlogin2 uses the normal formSubmitURL, so that we can test - // forms with a mix of username and non-username logins that might apply. - // - // Note: pwlogin2 is deleted at the end of the test. - - pwlogin1 = new nsLoginInfo(); - pwlogin2 = new nsLoginInfo(); - - pwlogin1.init("http://mochi.test:8888", "http://mochi.test:1111", null, - "", "1234", "uname", "pword"); - - pwlogin2.init("http://mochi.test:8888", "http://mochi.test:8888", null, - "", "1234", "uname", "pword"); - - - pwmgr.addLogin(pwlogin1); - pwmgr.addLogin(pwlogin2); -}); -</script> -<p id="display"></p> - -<div id="content" style="display: none"> - - -<!-- simple form: no username field, 1 password field --> -<form id='form1' action='http://mochi.test:1111/formtest.js'> 1 - <input type='password' name='pname' value=''> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - -<!-- simple form: no username field, 2 password fields --> -<form id='form2' action='http://mochi.test:1111/formtest.js'> 2 - <input type='password' name='pname1' value=''> - <input type='password' name='pname2' value=''> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - -<!-- simple form: no username field, 3 password fields --> -<form id='form3' action='http://mochi.test:1111/formtest.js'> 3 - <input type='password' name='pname1' value=''> - <input type='password' name='pname2' value=''> - <input type='password' name='pname3' value=''> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - -<!-- 4 password fields, should be ignored. --> -<form id='form4' action='http://mochi.test:1111/formtest.js'> 4 - <input type='password' name='pname1' value=''> - <input type='password' name='pname2' value=''> - <input type='password' name='pname3' value=''> - <input type='password' name='pname4' value=''> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - - - -<!-- 1 username field --> -<form id='form5' action='http://mochi.test:1111/formtest.js'> 5 - <input type='text' name='uname' value=''> - <input type='password' name='pname' value=''> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - - -<!-- 1 username field, with a value set --> -<form id='form6' action='http://mochi.test:1111/formtest.js'> 6 - <input type='text' name='uname' value='someuser'> - <input type='password' name='pname' value=''> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - - - -<!-- -(The following forms have 2 potentially-matching logins, on is -password-only, the other is username+password) ---> - - - -<!-- 1 username field, with value set. Fill in the matching U+P login --> -<form id='form7' action='formtest.js'> 7 - <input type='text' name='uname' value='testuser'> - <input type='password' name='pname' value=''> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - -<!-- 1 username field, with value set. Don't fill in U+P login--> -<form id='form8' action='formtest.js'> 8 - <input type='text' name='uname' value='someuser'> - <input type='password' name='pname' value=''> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - - - -<!-- 1 username field, too small for U+P login --> -<form id='form9' action='formtest.js'> 9 - <input type='text' name='uname' value='' maxlength="4"> - <input type='password' name='pname' value=''> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - -<!-- 1 username field, too small for U+P login --> -<form id='form10' action='formtest.js'> 10 - <input type='text' name='uname' value='' maxlength="0"> - <input type='password' name='pname' value=''> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - -<!-- 1 username field, too small for U+P login --> -<form id='form11' action='formtest.js'> 11 - <input type='text' name='uname' value=''> - <input type='password' name='pname' value='' maxlength="4"> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - -<!-- 1 username field, too small for either login --> -<form id='form12' action='formtest.js'> 12 - <input type='text' name='uname' value=''> - <input type='password' name='pname' value='' maxlength="1"> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - -<!-- 1 username field, too small for either login --> -<form id='form13' action='formtest.js'> 13 - <input type='text' name='uname' value=''> - <input type='password' name='pname' value='' maxlength="0"> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - - - -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: password-only logins **/ -function startTest() { - - checkForm(1, "1234"); - checkForm(2, "1234", ""); - checkForm(3, "1234", "", ""); - checkUnmodifiedForm(4); - - checkForm(5, "", "1234"); - checkForm(6, "someuser", ""); - - checkForm(7, "testuser", "testpass"); - checkForm(8, "someuser", ""); - - checkForm(9, "", "1234"); - checkForm(10, "", "1234"); - checkForm(11, "", "1234"); - - checkUnmodifiedForm(12); - checkUnmodifiedForm(13); - - SimpleTest.finish(); -} -</script> -</pre> -</body> -</html> - diff --git a/toolkit/components/passwordmgr/test/mochitest/test_bug_627616.html b/toolkit/components/passwordmgr/test/mochitest/test_bug_627616.html deleted file mode 100644 index ad4a41cdb..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_bug_627616.html +++ /dev/null @@ -1,145 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test bug 627616 related to proxy authentication</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<script class="testbody" type="text/javascript"> - SimpleTest.waitForExplicitFinish(); - - var Ci = SpecialPowers.Ci; - - function makeXHR(expectedStatus, expectedText, extra) { - var xhr = new XMLHttpRequest(); - xhr.open("GET", "authenticate.sjs?" + - "proxy_user=proxy_user&" + - "proxy_pass=proxy_pass&" + - "proxy_realm=proxy_realm&" + - "user=user1name&" + - "pass=user1pass&" + - "realm=mochirealm&" + - extra || ""); - xhr.onloadend = function() { - is(xhr.status, expectedStatus, "xhr.status"); - is(xhr.statusText, expectedText, "xhr.statusText"); - runNextTest(); - }; - return xhr; - } - - function testNonAnonymousCredentials() { - var xhr = makeXHR(200, "OK"); - xhr.send(); - } - - function testAnonymousCredentials() { - // Test that an anonymous request correctly performs proxy authentication - var xhr = makeXHR(401, "Authentication required"); - SpecialPowers.wrap(xhr).channel.loadFlags |= Ci.nsIChannel.LOAD_ANONYMOUS; - xhr.send(); - } - - function testAnonymousNoAuth() { - // Next, test that an anonymous request still does not include any non-proxy - // authentication headers. - var xhr = makeXHR(200, "Authorization header not found", "anonymous=1"); - SpecialPowers.wrap(xhr).channel.loadFlags |= Ci.nsIChannel.LOAD_ANONYMOUS; - xhr.send(); - } - - var gExpectedDialogs = 0; - var gCurrentTest; - function runNextTest() { - is(gExpectedDialogs, 0, "received expected number of auth dialogs"); - mm.sendAsyncMessage("prepareForNextTest"); - mm.addMessageListener("prepareForNextTestDone", function prepared(msg) { - mm.removeMessageListener("prepareForNextTestDone", prepared); - if (pendingTests.length > 0) { - ({expectedDialogs: gExpectedDialogs, - test: gCurrentTest} = pendingTests.shift()); - gCurrentTest.call(this); - } else { - mm.sendAsyncMessage("cleanup"); - mm.addMessageListener("cleanupDone", () => { - // mm.destroy() is called as a cleanup function by runInParent(), no - // need to do it here. - SimpleTest.finish(); - }); - } - }); - } - - var pendingTests = [{expectedDialogs: 2, test: testNonAnonymousCredentials}, - {expectedDialogs: 1, test: testAnonymousCredentials}, - {expectedDialogs: 0, test: testAnonymousNoAuth}]; - - let mm = runInParent(() => { - const { classes: parentCc, interfaces: parentCi, utils: parentCu } = Components; - - parentCu.import("resource://gre/modules/Services.jsm"); - parentCu.import("resource://gre/modules/NetUtil.jsm"); - parentCu.import("resource://gre/modules/Timer.jsm"); - parentCu.import("resource://gre/modules/XPCOMUtils.jsm"); - - let channel = NetUtil.newChannel({ - uri: "http://example.com", - loadUsingSystemPrincipal: true - }); - - let pps = parentCc["@mozilla.org/network/protocol-proxy-service;1"]. - getService(parentCi.nsIProtocolProxyService); - pps.asyncResolve(channel, 0, { - onProxyAvailable(req, uri, pi, status) { - let mozproxy = "moz-proxy://" + pi.host + ":" + pi.port; - let login = parentCc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(parentCi.nsILoginInfo); - login.init(mozproxy, null, "proxy_realm", "proxy_user", "proxy_pass", - "", ""); - Services.logins.addLogin(login); - - let login2 = parentCc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(parentCi.nsILoginInfo); - login2.init("http://mochi.test:8888", null, "mochirealm", "user1name", - "user1pass", "", ""); - Services.logins.addLogin(login2); - - sendAsyncMessage("setupDone"); - }, - QueryInterface: XPCOMUtils.generateQI([parentCi.nsIProtocolProxyCallback]), - }); - - addMessageListener("prepareForNextTest", message => { - parentCc["@mozilla.org/network/http-auth-manager;1"]. - getService(parentCi.nsIHttpAuthManager). - clearAll(); - sendAsyncMessage("prepareForNextTestDone"); - }); - - let dialogObserverTopic = "common-dialog-loaded"; - - function dialogObserver(subj, topic, data) { - subj.Dialog.ui.prompt.document.documentElement.acceptDialog(); - sendAsyncMessage("promptAccepted"); - } - - Services.obs.addObserver(dialogObserver, dialogObserverTopic, false); - - addMessageListener("cleanup", message => { - Services.obs.removeObserver(dialogObserver, dialogObserverTopic); - sendAsyncMessage("cleanupDone"); - }); - }); - - mm.addMessageListener("promptAccepted", msg => { - gExpectedDialogs--; - }); - mm.addMessageListener("setupDone", msg => { - runNextTest(); - }); -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_bug_776171.html b/toolkit/components/passwordmgr/test/mochitest/test_bug_776171.html deleted file mode 100644 index 4ad08bee2..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_bug_776171.html +++ /dev/null @@ -1,56 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=776171 ---> -<head> - <meta charset="utf-8"> - <title>Test for Bug 776171 related to HTTP auth</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body onload="startTest()"> -<script class="testbody" type="text/javascript"> - -/** - * This test checks we correctly ignore authentication entry - * for a subpath and use creds from the URL when provided when XHR - * is used with filled user name and password. - * - * 1. connect auth2/authenticate.sjs that expects user1:pass1 password - * 2. connect a dummy URL at the same path - * 3. connect authenticate.sjs that again expects user1:pass1 password - * in this case, however, we have an entry without an identity - * for this path (that is a parent for auth2 path in the first step) - */ - -SimpleTest.waitForExplicitFinish(); - -function doxhr(URL, user, pass, next) { - var xhr = new XMLHttpRequest(); - if (user && pass) - xhr.open("POST", URL, true, user, pass); - else - xhr.open("POST", URL, true); - xhr.onload = function() { - is(xhr.status, 200, "Got status 200"); - next(); - }; - xhr.onerror = function() { - ok(false, "request passed"); - finishTest(); - }; - xhr.send(); -} - -function startTest() { - doxhr("auth2/authenticate.sjs?user=user1&pass=pass1&realm=realm1", "user1", "pass1", function() { - doxhr("auth2", null, null, function() { - doxhr("authenticate.sjs?user=user1&pass=pass1&realm=realm1", "user1", "pass1", SimpleTest.finish); - }); - }); -} -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_case_differences.html b/toolkit/components/passwordmgr/test/mochitest/test_case_differences.html deleted file mode 100644 index 316f59da7..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_case_differences.html +++ /dev/null @@ -1,147 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test autocomplete due to multiple matching logins</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="satchel_common.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: autocomplete due to multiple matching logins - -<script> -runChecksAfterCommonInit(false); - -SpecialPowers.loadChromeScript(function addLogins() { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - Cu.import("resource://gre/modules/Services.jsm"); - - // Create some logins just for this form, since we'll be deleting them. - var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); - - var login0 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "name", "pass", "uname", "pword"); - - var login1 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "Name", "Pass", "uname", "pword"); - - var login2 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "USER", "PASS", "uname", "pword"); - - try { - Services.logins.addLogin(login0); - Services.logins.addLogin(login1); - Services.logins.addLogin(login2); - } catch (e) { - assert.ok(false, "addLogin threw: " + e); - } -}); -</script> -<p id="display"></p> - -<!-- we presumably can't hide the content for this test. --> -<div id="content"> - - <!-- form1 tests multiple matching logins --> - <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: autocomplete due to multiple matching logins **/ - -var uname = $_(1, "uname"); -var pword = $_(1, "pword"); - -// Restore the form to the default state. -function restoreForm() { - uname.value = ""; - pword.value = ""; - uname.focus(); -} - -// Check for expected username/password in form. -function checkACForm(expectedUsername, expectedPassword) { - var formID = uname.parentNode.id; - is(uname.value, expectedUsername, "Checking " + formID + " username"); - is(pword.value, expectedPassword, "Checking " + formID + " password"); -} - -add_task(function* test_empty_first_entry() { - /* test 1 */ - // Make sure initial form is empty. - checkACForm("", ""); - // Trigger autocomplete popup - restoreForm(); - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is initially closed"); - let shownPromise = promiseACShown(); - doKey("down"); - let results = yield shownPromise; - popupState = yield getPopupState(); - is(popupState.selectedIndex, -1, "Check no entries are selected"); - checkArrayValues(results, ["name", "Name", "USER"], "initial"); - - // Check first entry - let index0Promise = notifySelectedIndex(0); - doKey("down"); - yield index0Promise; - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("name", "pass"); -}); - -add_task(function* test_empty_second_entry() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - doKey("down"); // first - doKey("down"); // second - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("Name", "Pass"); -}); - -add_task(function* test_empty_third_entry() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - doKey("down"); // first - doKey("down"); // second - doKey("down"); // third - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("USER", "PASS"); -}); - -add_task(function* test_preserve_matching_username_case() { - restoreForm(); - uname.value = "user"; - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Check that we don't clobber user-entered text when tabbing away - // (even with no autocomplete entry selected) - doKey("tab"); - yield promiseFormsProcessed(); - checkACForm("user", "PASS"); -}); -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_form_action_1.html b/toolkit/components/passwordmgr/test/mochitest/test_form_action_1.html deleted file mode 100644 index 430081b3a..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_form_action_1.html +++ /dev/null @@ -1,137 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test for considering form action</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: Bug 360493 -<script> -runChecksAfterCommonInit(() => startTest()); -</script> -<p id="display"></p> -<div id="content" style="display: none"> - - <!-- normal form with normal relative action. --> - <form id="form1" action="formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- fully specify the action URL --> - <form id="form2" action="http://mochi.test:8888/tests/toolkit/components/passwordmgr/test/formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- fully specify the action URL, and change the path --> - <form id="form3" action="http://mochi.test:8888/zomg/wtf/bbq/passwordmgr/test/formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- fully specify the action URL, and change the path and filename --> - <form id="form4" action="http://mochi.test:8888/zomg/wtf/bbq/passwordmgr/test/not_a_test.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- specify the action URL relative to the current document--> - <form id="form5" action="./formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- specify the action URL relative to the current server --> - <form id="form6" action="/tests/toolkit/components/passwordmgr/test/formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Change the method from get to post --> - <form id="form7" action="formtest.js" method="POST"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Blank action URL specified --> - <form id="form8" action=""> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- |action| attribute entirely missing --> - <form id="form9" > - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- action url as javascript --> - <form id="form10" action="javascript:alert('this form is not submitted so this alert should not be invoked');"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- TODO: action=IP.ADDRESS instead of HOSTNAME? --> - <!-- TODO: test with |base href="http://othersite//"| ? --> -</div> -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: 360493 (Cross-Site Forms + Password - Manager = Security Failure) **/ - -// This test is designed to make sure variations on the form's |action| -// and |method| continue to work with the fix for 360493. - -function startTest() { - for (var i = 1; i <= 9; i++) { - // Check form i - is($_(i, "uname").value, "testuser", "Checking for filled username " + i); - is($_(i, "pword").value, "testpass", "Checking for filled password " + i); - } - - // The login's formSubmitURL isn't "javascript:", so don't fill it in. - isnot($_(10, "uname"), "testuser", "Checking username w/ JS action URL"); - isnot($_(10, "pword"), "testpass", "Checking password w/ JS action URL"); - - SimpleTest.finish(); -} -</script> -</pre> -</body> -</html> - diff --git a/toolkit/components/passwordmgr/test/mochitest/test_form_action_2.html b/toolkit/components/passwordmgr/test/mochitest/test_form_action_2.html deleted file mode 100644 index 0f0056de0..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_form_action_2.html +++ /dev/null @@ -1,170 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test for considering form action</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: Bug 360493 -<script> -runChecksAfterCommonInit(() => startTest()); -</script> -<p id="display"></p> -<div id="content" style="display: none"> - - <!-- The tests in this page exercise things that shouldn't work. --> - - <!-- Change port # of action URL from 8888 to 7777 --> - <form id="form1" action="http://localhost:7777/tests/toolkit/components/passwordmgr/test/formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- No port # in action URL --> - <form id="form2" action="http://localhost/tests/toolkit/components/passwordmgr/test/formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Change protocol from http:// to ftp://, include the expected 8888 port # --> - <form id="form3" action="ftp://localhost:8888/tests/toolkit/components/passwordmgr/test/formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Change protocol from http:// to ftp://, no port # specified --> - <form id="form4" action="ftp://localhost/tests/toolkit/components/passwordmgr/test/formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Try a weird URL. --> - <form id="form5" action="about:blank"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Try a weird URL. (If the normal embedded action URL doesn't work, that should mean other URLs won't either) --> - <form id="form6" action="view-source:http://localhost:8888/tests/toolkit/components/passwordmgr/test/formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Try a weird URL. --> - <form id="form7" action="view-source:formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Action URL points to a different host (this is the archetypical exploit) --> - <form id="form8" action="http://www.cnn.com/"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Action URL points to a different host, user field prefilled --> - <form id="form9" action="http://www.cnn.com/"> - <input type="text" name="uname" value="testuser"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- Try wrapping a evil form around a good form, to see if we can confuse the parser. --> - <form id="form10-A" action="http://www.cnn.com/"> - <form id="form10-B" action="formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit (inner)</button> - <button type="reset"> Reset (inner)</button> - </form> - <button type="submit" id="neutered_submit10">Submit (outer)</button> - <button type="reset">Reset (outer)</button> - </form> - - <!-- Try wrapping a good form around an evil form, to see if we can confuse the parser. --> - <form id="form11-A" action="formtest.js"> - <form id="form11-B" action="http://www.cnn.com/"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit (inner)</button> - <button type="reset"> Reset (inner)</button> - </form> - <button type="submit" id="neutered_submit11">Submit (outer)</button> - <button type="reset">Reset (outer)</button> - </form> - -<!-- TODO: probably should have some accounts which have no port # in the action url. JS too. And different host/proto. --> -<!-- TODO: www.site.com vs. site.com? --> -<!-- TODO: foo.site.com vs. bar.site.com? --> - -</div> -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: 360493 (Cross-Site Forms + Password Manager = Security Failure) **/ - -function startTest() { - for (var i = 1; i <= 8; i++) { - // Check form i - is($_(i, "uname").value, "", "Checking for unfilled username " + i); - is($_(i, "pword").value, "", "Checking for unfilled password " + i); - } - - is($_(9, "uname").value, "testuser", "Checking for unmodified username 9"); - is($_(9, "pword").value, "", "Checking for unfilled password 9"); - - is($_("10-A", "uname").value, "", "Checking for unfilled username 10A"); - is($_("10-A", "pword").value, "", "Checking for unfilled password 10A"); - - // The DOM indicates this form could be filled, as the evil inner form - // is discarded. And yet pwmgr seems not to fill it. Not sure why. - todo(false, "Mangled form combo not being filled when maybe it could be?"); - is($_("11-A", "uname").value, "testuser", "Checking filled username 11A"); - is($_("11-A", "pword").value, "testpass", "Checking filled password 11A"); - - // Verify this by making sure there are no extra forms in the document, and - // that the submit button for the neutered forms don't do anything. - // If the test finds extra forms the submit() causes the test to timeout, then - // there may be a security issue. - is(document.forms.length, 11, "Checking for unexpected forms"); - $("neutered_submit10").click(); - $("neutered_submit11").click(); - - SimpleTest.finish(); -} -</script> -</pre> -</body> -</html> - diff --git a/toolkit/components/passwordmgr/test/mochitest/test_form_action_javascript.html b/toolkit/components/passwordmgr/test/mochitest/test_form_action_javascript.html deleted file mode 100644 index d37e92c40..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_form_action_javascript.html +++ /dev/null @@ -1,52 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test forms with a JS submit action</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: form with JS submit action -<script> -runChecksAfterCommonInit(() => startTest()); - -runInParent(function setup() { - const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; - Cu.import("resource://gre/modules/Services.jsm"); - - let jslogin = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance(Ci.nsILoginInfo); - jslogin.init("http://mochi.test:8888", "javascript:", null, - "jsuser", "jspass123", "uname", "pword"); - Services.logins.addLogin(jslogin); -}); - -/** Test for Login Manager: JS action URL **/ - -function startTest() { - checkForm(1, "jsuser", "jspass123"); - - SimpleTest.finish(); -} -</script> - -<p id="display"></p> - -<div id="content" style="display: none"> - - -<form id='form1' action='javascript:alert("never shows")'> 1 - <input name="uname"> - <input name="pword" type="password"> - - <button type='submit'>Submit</button> - <button type='reset'> Reset </button> -</form> - -</div> - -<pre id="test"></pre> -</body> -</html> - diff --git a/toolkit/components/passwordmgr/test/mochitest/test_formless_autofill.html b/toolkit/components/passwordmgr/test/mochitest/test_formless_autofill.html deleted file mode 100644 index 6263c818d..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_formless_autofill.html +++ /dev/null @@ -1,147 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Test autofilling of fields outside of a form</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<script type="application/javascript;version=1.8"> -let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js")); - -document.addEventListener("DOMContentLoaded", () => { - document.getElementById("loginFrame").addEventListener("load", (evt) => { - // Tell the parent to setup test logins. - chromeScript.sendAsyncMessage("setupParent", { selfFilling: true }); - }); -}); - -let doneSetupPromise = new Promise(resolve => { - // When the setup is done, load a recipe for this test. - chromeScript.addMessageListener("doneSetup", function doneSetup() { - resolve(); - }); -}); - -add_task(function* setup() { - info("Waiting for loads and setup"); - yield doneSetupPromise; - - yield loadRecipes({ - siteRecipes: [{ - hosts: ["mochi.test:8888"], - usernameSelector: "input[name='recipeuname']", - passwordSelector: "input[name='recipepword']", - }], - }); -}); - - -const DEFAULT_ORIGIN = "http://mochi.test:8888"; -const TESTCASES = [ - { - // Inputs - document: `<input type=password>`, - - // Expected outputs - expectedInputValues: ["testpass"], - }, - { - document: `<input> - <input type=password>`, - expectedInputValues: ["testuser", "testpass"], - }, - { - document: `<input> - <input type=password> - <input type=password>`, - expectedInputValues: ["testuser", "testpass", ""], - }, - { - document: `<input> - <input type=password> - <input type=password> - <input type=password>`, - expectedInputValues: ["testuser", "testpass", "", ""], - }, - { - document: `<input> - <input type=password form="form1"> - <input type=password> - <form id="form1"> - <input> - <input type=password> - </form>`, - expectedFormCount: 2, - expectedInputValues: ["testuser", "testpass", "testpass", "", ""], - }, - { - document: `<!-- formless password field selector recipe test --> - <input> - <input type=password> - <input> - <input type=password name="recipepword">`, - expectedInputValues: ["", "", "testuser", "testpass"], - }, - { - document: `<!-- formless username and password field selector recipe test --> - <input name="recipeuname"> - <input> - <input type=password> - <input type=password name="recipepword">`, - expectedInputValues: ["testuser", "", "", "testpass"], - }, - { - document: `<!-- form and formless recipe field selector test --> - <input name="recipeuname"> - <input> - <input type=password form="form1"> <!-- not filled since recipe affects both FormLikes --> - <input type=password> - <input type=password name="recipepword"> - <form id="form1"> - <input> - <input type=password> - </form>`, - expectedFormCount: 2, - expectedInputValues: ["testuser", "", "", "", "testpass", "", ""], - }, -]; - -add_task(function* test() { - let loginFrame = document.getElementById("loginFrame"); - let frameDoc = loginFrame.contentWindow.document; - - for (let tc of TESTCASES) { - info("Starting testcase: " + JSON.stringify(tc)); - - let numFormLikesExpected = tc.expectedFormCount || 1; - - let processedFormPromise = promiseFormsProcessed(numFormLikesExpected); - - frameDoc.documentElement.innerHTML = tc.document; - info("waiting for " + numFormLikesExpected + " processed form(s)"); - yield processedFormPromise; - - let testInputs = frameDoc.documentElement.querySelectorAll("input"); - is(testInputs.length, tc.expectedInputValues.length, "Check number of inputs"); - for (let i = 0; i < tc.expectedInputValues.length; i++) { - let expectedValue = tc.expectedInputValues[i]; - is(testInputs[i].value, expectedValue, - "Check expected input value " + i + ": " + expectedValue); - } - } -}); - -</script> - -<p id="display"></p> - -<div id="content"> - <iframe id="loginFrame" src="http://mochi.test:8888/tests/toolkit/components/passwordmgr/test/blank.html"></iframe> -</div> -<pre id="test"></pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit.html b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit.html deleted file mode 100644 index 468da1e7f..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit.html +++ /dev/null @@ -1,183 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Test capturing of fields outside of a form</title> - <script src="/tests/SimpleTest/SimpleTest.js"></script> - <script src="/tests/SimpleTest/SpawnTask.js"></script> - <script src="pwmgr_common.js"></script> - <link rel="stylesheet" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<script type="application/javascript;version=1.8"> -const LMCBackstagePass = SpecialPowers.Cu.import("resource://gre/modules/LoginManagerContent.jsm"); -const { LoginManagerContent, LoginFormFactory } = LMCBackstagePass; - -let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js")); - -let loadPromise = new Promise(resolve => { - document.addEventListener("DOMContentLoaded", () => { - document.getElementById("loginFrame").addEventListener("load", (evt) => { - resolve(); - }); - }); -}); - -add_task(function* setup() { - info("Waiting for page and frame loads"); - yield loadPromise; - - yield loadRecipes({ - siteRecipes: [{ - hosts: ["mochi.test:8888"], - usernameSelector: "input[name='recipeuname']", - passwordSelector: "input[name='recipepword']", - }], - }); -}); - -const DEFAULT_ORIGIN = "http://mochi.test:8888"; -const TESTCASES = [ - { - // Inputs - document: `<input type=password value="pass1">`, - inputIndexForFormLike: 0, - - // Expected outputs similar to RemoteLogins:onFormSubmit - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: null, - newPasswordFieldValue: "pass1", - oldPasswordFieldValue: null, - }, - { - document: `<input value="user1"> - <input type=password value="pass1">`, - inputIndexForFormLike: 0, - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: "user1", - newPasswordFieldValue: "pass1", - oldPasswordFieldValue: null, - }, - { - document: `<input value="user1"> - <input type=password value="pass1">`, - inputIndexForFormLike: 1, - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: "user1", - newPasswordFieldValue: "pass1", - oldPasswordFieldValue: null, - }, - { - document: `<input value="user1"> - <input type=password value="pass1"> - <input type=password value="pass2">`, - inputIndexForFormLike: 2, - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: "user1", - newPasswordFieldValue: "pass2", - oldPasswordFieldValue: "pass1", - }, - { - document: `<input value="user1"> - <input type=password value="pass1"> - <input type=password value="pass2"> - <input type=password value="pass2">`, - inputIndexForFormLike: 3, - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: "user1", - newPasswordFieldValue: "pass2", - oldPasswordFieldValue: "pass1", - }, - { - document: `<input value="user1"> - <input type=password value="user2" form="form1"> - <input type=password value="pass1"> - <form id="form1"> - <input value="user3"> - <input type=password value="pass2"> - </form>`, - inputIndexForFormLike: 2, - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: "user1", - newPasswordFieldValue: "pass1", - oldPasswordFieldValue: null, - }, - { - document: `<!-- recipe field override --> - <input name="recipeuname" value="username from recipe"> - <input value="default field username"> - <input type=password value="pass1"> - <input name="recipepword" type=password value="pass2">`, - inputIndexForFormLike: 2, - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: "username from recipe", - newPasswordFieldValue: "pass2", - oldPasswordFieldValue: null, - }, -]; - -function getSubmitMessage() { - info("getSubmitMessage"); - return new Promise((resolve, reject) => { - chromeScript.addMessageListener("formSubmissionProcessed", function processed(...args) { - info("got formSubmissionProcessed"); - chromeScript.removeMessageListener("formSubmissionProcessed", processed); - resolve(...args); - }); - }); -} - -add_task(function* test() { - let loginFrame = document.getElementById("loginFrame"); - let frameDoc = loginFrame.contentWindow.document; - - for (let tc of TESTCASES) { - info("Starting testcase: " + JSON.stringify(tc)); - frameDoc.documentElement.innerHTML = tc.document; - let inputForFormLike = frameDoc.querySelectorAll("input")[tc.inputIndexForFormLike]; - - let formLike = LoginFormFactory.createFromField(inputForFormLike); - - info("Calling _onFormSubmit with FormLike"); - let processedPromise = getSubmitMessage(); - LoginManagerContent._onFormSubmit(formLike); - - let submittedResult = yield processedPromise; - - // Check data sent via RemoteLogins:onFormSubmit - is(submittedResult.hostname, tc.hostname, "Check hostname"); - is(submittedResult.formSubmitURL, tc.formSubmitURL, "Check formSubmitURL"); - - if (tc.usernameFieldValue === null) { - is(submittedResult.usernameField, tc.usernameFieldValue, "Check usernameField"); - } else { - is(submittedResult.usernameField.value, tc.usernameFieldValue, "Check usernameField"); - } - - is(submittedResult.newPasswordField.value, tc.newPasswordFieldValue, "Check newPasswordFieldValue"); - - if (tc.oldPasswordFieldValue === null) { - is(submittedResult.oldPasswordField, tc.oldPasswordFieldValue, "Check oldPasswordFieldValue"); - } else { - is(submittedResult.oldPasswordField.value, tc.oldPasswordFieldValue, "Check oldPasswordFieldValue"); - } - } -}); - -</script> - -<p id="display"></p> - -<div id="content"> - <iframe id="loginFrame" src="http://mochi.test:8888/tests/toolkit/components/passwordmgr/test/blank.html"></iframe> -</div> -<pre id="test"></pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation.html b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation.html deleted file mode 100644 index b07d0886c..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation.html +++ /dev/null @@ -1,191 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Test capturing of fields outside of a form due to navigation</title> - <script src="/tests/SimpleTest/SimpleTest.js"></script> - <script src="/tests/SimpleTest/SpawnTask.js"></script> - <script src="pwmgr_common.js"></script> - <link rel="stylesheet" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<script type="application/javascript;version=1.8"> -const LMCBackstagePass = SpecialPowers.Cu.import("resource://gre/modules/LoginManagerContent.jsm"); -const { LoginManagerContent, LoginFormFactory } = LMCBackstagePass; - -let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js")); - -let loadPromise = new Promise(resolve => { - document.addEventListener("DOMContentLoaded", () => { - document.getElementById("loginFrame").addEventListener("load", (evt) => { - resolve(); - }); - }); -}); - -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({ - set: [ - ["signon.formlessCapture.enabled", true], - ], - }); - - info("Waiting for page and frame loads"); - yield loadPromise; - - yield loadRecipes({ - siteRecipes: [{ - hosts: ["test1.mochi.test:8888"], - usernameSelector: "input[name='recipeuname']", - passwordSelector: "input[name='recipepword']", - }], - }); -}); - -const DEFAULT_ORIGIN = "http://test1.mochi.test:8888"; -const SCRIPTS = { - PUSHSTATE: `history.pushState({}, "Pushed state", "?pushed");`, - WINDOW_LOCATION: `window.location = "data:text/html;charset=utf-8,window.location";`, -}; -const TESTCASES = [ - { - // Inputs - document: `<input type=password value="pass1">`, - - // Expected outputs similar to RemoteLogins:onFormSubmit - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: null, - newPasswordFieldValue: "pass1", - oldPasswordFieldValue: null, - }, - { - document: `<input value="user1"> - <input type=password value="pass1">`, - - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: "user1", - newPasswordFieldValue: "pass1", - oldPasswordFieldValue: null, - }, - { - document: `<input value="user1"> - <input type=password value="pass1"> - <input type=password value="pass2">`, - - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: "user1", - newPasswordFieldValue: "pass2", - oldPasswordFieldValue: "pass1", - }, - { - document: `<input value="user1"> - <input type=password value="pass1"> - <input type=password value="pass2"> - <input type=password value="pass2">`, - - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: "user1", - newPasswordFieldValue: "pass2", - oldPasswordFieldValue: "pass1", - }, - { - document: `<input value="user1"> - <input type=password value="user2" form="form1"> - <input type=password value="pass1"> - <form id="form1"> - <input value="user3"> - <input type=password value="pass2"> - </form>`, - - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: "user1", - newPasswordFieldValue: "pass1", - oldPasswordFieldValue: null, - }, - { - document: `<!-- recipe field override --> - <input name="recipeuname" value="username from recipe"> - <input value="default field username"> - <input type=password value="pass1"> - <input name="recipepword" type=password value="pass2">`, - - hostname: DEFAULT_ORIGIN, - formSubmitURL: DEFAULT_ORIGIN, - usernameFieldValue: "username from recipe", - newPasswordFieldValue: "pass2", - oldPasswordFieldValue: null, - }, -]; - -function getSubmitMessage() { - info("getSubmitMessage"); - return new Promise((resolve, reject) => { - chromeScript.addMessageListener("formSubmissionProcessed", function processed(...args) { - info("got formSubmissionProcessed"); - chromeScript.removeMessageListener("formSubmissionProcessed", processed); - resolve(...args); - }); - }); -} - -add_task(function* test() { - let loginFrame = document.getElementById("loginFrame"); - - for (let tc of TESTCASES) { - for (let scriptName of Object.keys(SCRIPTS)) { - info("Starting testcase with script " + scriptName + ": " + JSON.stringify(tc)); - let loadedPromise = new Promise((resolve) => { - loginFrame.addEventListener("load", function frameLoaded() { - loginFrame.removeEventListener("load", frameLoaded); - resolve(); - }); - }); - loginFrame.src = DEFAULT_ORIGIN + "/tests/toolkit/components/passwordmgr/test/mochitest/blank.html"; - yield loadedPromise; - - let frameDoc = SpecialPowers.wrap(loginFrame.contentWindow).document; - frameDoc.documentElement.innerHTML = tc.document; - // Wait for the form to be processed before trying to submit. - yield promiseFormsProcessed(); - let processedPromise = getSubmitMessage(); - info("Running " + scriptName + " script to cause a submission"); - frameDoc.defaultView.eval(SCRIPTS[scriptName]); - - let submittedResult = yield processedPromise; - - // Check data sent via RemoteLogins:onFormSubmit - is(submittedResult.hostname, tc.hostname, "Check hostname"); - is(submittedResult.formSubmitURL, tc.formSubmitURL, "Check formSubmitURL"); - - if (tc.usernameFieldValue === null) { - is(submittedResult.usernameField, tc.usernameFieldValue, "Check usernameField"); - } else { - is(submittedResult.usernameField.value, tc.usernameFieldValue, "Check usernameField"); - } - - is(submittedResult.newPasswordField.value, tc.newPasswordFieldValue, "Check newPasswordFieldValue"); - - if (tc.oldPasswordFieldValue === null) { - is(submittedResult.oldPasswordField, tc.oldPasswordFieldValue, "Check oldPasswordFieldValue"); - } else { - is(submittedResult.oldPasswordField.value, tc.oldPasswordFieldValue, "Check oldPasswordFieldValue"); - } - } - } -}); - -</script> - -<p id="display"></p> - -<div id="content"> - <iframe id="loginFrame" src="http://test1.mochi.test:8888/tests/toolkit/components/passwordmgr/test/mochitest/blank.html"></iframe> -</div> -<pre id="test"></pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation_negative.html b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation_negative.html deleted file mode 100644 index 4283f128c..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation_negative.html +++ /dev/null @@ -1,121 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Test no capturing of fields outside of a form due to navigation</title> - <script src="/tests/SimpleTest/SimpleTest.js"></script> - <script src="/tests/SimpleTest/SpawnTask.js"></script> - <script src="pwmgr_common.js"></script> - <link rel="stylesheet" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<script type="application/javascript;version=1.8"> -const LMCBackstagePass = SpecialPowers.Cu.import("resource://gre/modules/LoginManagerContent.jsm"); -const { LoginManagerContent, LoginFormFactory } = LMCBackstagePass; - -SimpleTest.requestFlakyTimeout("Testing that a message doesn't arrive"); - -let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js")); - -let loadPromise = new Promise(resolve => { - document.addEventListener("DOMContentLoaded", () => { - document.getElementById("loginFrame").addEventListener("load", (evt) => { - resolve(); - }); - }); -}); - -function submissionProcessed(...args) { - ok(false, "No formSubmissionProcessed should occur in this test"); - info("got: " + JSON.stringify(args)); -} - -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({ - set: [ - ["signon.formlessCapture.enabled", true], - ], - }); - - info("Waiting for page and frame loads"); - yield loadPromise; - - chromeScript.addMessageListener("formSubmissionProcessed", submissionProcessed); - - SimpleTest.registerCleanupFunction(() => { - chromeScript.removeMessageListener("formSubmissionProcessed", submissionProcessed); - }); -}); - -const DEFAULT_ORIGIN = "http://test1.mochi.test:8888"; -const SCRIPTS = { - PUSHSTATE: `history.pushState({}, "Pushed state", "?pushed");`, - WINDOW_LOCATION: `window.location = "data:text/html;charset=utf-8,window.location";`, - WINDOW_LOCATION_RELOAD: `window.location.reload();`, - HISTORY_BACK: `history.back();`, - HISTORY_GO_MINUS1: `history.go(-1);`, -}; -const TESTCASES = [ - // Begin test cases that shouldn't trigger capture. - { - // For now we don't trigger upon navigation if <form> is used. - document: `<form><input type=password value="pass1"></form>`, - }, - { - // Empty password field - document: `<input type=password value="">`, - }, - { - // Test with an input that would normally be captured but with SCRIPTS that - // shouldn't trigger capture. - document: `<input type=password value="pass2">`, - wouldCapture: true, - }, -]; - -add_task(function* test() { - let loginFrame = document.getElementById("loginFrame"); - - for (let tc of TESTCASES) { - for (let scriptName of Object.keys(SCRIPTS)) { - if (tc.wouldCapture && ["PUSHSTATE", "WINDOW_LOCATION"].includes(scriptName)) { - // Don't run scripts that should actually capture for this testcase. - continue; - } - - info("Starting testcase with script " + scriptName + ": " + JSON.stringify(tc)); - let loadedPromise = new Promise((resolve) => { - loginFrame.addEventListener("load", function frameLoaded() { - loginFrame.removeEventListener("load", frameLoaded); - resolve(); - }); - }); - loginFrame.src = DEFAULT_ORIGIN + "/tests/toolkit/components/passwordmgr/test/mochitest/blank.html"; - yield loadedPromise; - - let frameDoc = SpecialPowers.wrap(loginFrame.contentWindow).document; - frameDoc.documentElement.innerHTML = tc.document; - - // Wait for the form to be processed before trying to submit. - yield promiseFormsProcessed(); - - info("Running " + scriptName + " script to check for a submission"); - frameDoc.defaultView.eval(SCRIPTS[scriptName]); - - // Wait for 5000ms to see if the promise above resolves. - yield new Promise(resolve => setTimeout(resolve, 5000)); - ok(true, "Done waiting for captures"); - } - } -}); - -</script> - -<p id="display"></p> - -<div id="content"> - <iframe id="loginFrame" src="http://test1.mochi.test:8888/tests/toolkit/components/passwordmgr/test/mochitest/blank.html"></iframe> -</div> -<pre id="test"></pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_input_events.html b/toolkit/components/passwordmgr/test/mochitest/test_input_events.html deleted file mode 100644 index 0e77956d8..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_input_events.html +++ /dev/null @@ -1,96 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test for input events in Login Manager</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body onload="onNewEvent(event)"> -Login Manager test: input events should fire. - -<script> -runChecksAfterCommonInit(); - -SimpleTest.requestFlakyTimeout("untriaged"); - -/** Test for Login Manager: form fill, should get input events. **/ - -var usernameInputFired = false; -var passwordInputFired = false; -var usernameChangeFired = false; -var passwordChangeFired = false; -var onloadFired = false; - -function onNewEvent(e) { - info("Got " + e.type + " event."); - if (e.type == "load") { - onloadFired = true; - } else if (e.type == "input") { - if (e.target.name == "uname") { - is(e.target.value, "testuser", "Should get 'testuser' as username"); - ok(!usernameInputFired, "Should not have gotten an input event for the username field yet."); - usernameInputFired = true; - } else if (e.target.name == "pword") { - is(e.target.value, "testpass", "Should get 'testpass' as password"); - ok(!passwordInputFired, "Should not have gotten an input event for the password field yet."); - passwordInputFired = true; - } - } else if (e.type == "change") { - if (e.target.name == "uname") { - is(e.target.value, "testuser", "Should get 'testuser' as username"); - ok(usernameInputFired, "Should get input event before change event for username field."); - ok(!usernameChangeFired, "Should not have gotten a change event for the username field yet."); - usernameChangeFired = true; - } else if (e.target.name == "pword") { - is(e.target.value, "testpass", "Should get 'testpass' as password"); - ok(passwordInputFired, "Should get input event before change event for password field."); - ok(!passwordChangeFired, "Should not have gotten a change event for the password field yet."); - passwordChangeFired = true; - } - } - if (onloadFired && usernameInputFired && passwordInputFired && usernameChangeFired && passwordChangeFired) { - ok(true, "All events fired as expected, we're done."); - SimpleTest.finish(); - } -} - -SimpleTest.registerCleanupFunction(function cleanup() { - clearTimeout(timeout); - $_(1, "uname").removeAttribute("oninput"); - $_(1, "pword").removeAttribute("oninput"); - $_(1, "uname").removeAttribute("onchange"); - $_(1, "pword").removeAttribute("onchange"); - document.body.removeAttribute("onload"); -}); - -var timeout = setTimeout(function() { - ok(usernameInputFired, "Username input event should have fired by now."); - ok(passwordInputFired, "Password input event should have fired by now."); - ok(usernameChangeFired, "Username change event should have fired by now."); - ok(passwordChangeFired, "Password change event should have fired by now."); - ok(onloadFired, "Window load event should have fired by now."); - ok(false, "Not all events fired yet."); - SimpleTest.finish(); -}, 10000); - -</script> - -<p id="display"></p> - -<div id="content" style="display: none"> - - <form id="form1" action="formtest.js"> - <p>This is form 1.</p> - <input type="text" name="uname" oninput="onNewEvent(event)" onchange="onNewEvent(event)"> - <input type="password" name="pword" oninput="onNewEvent(event)" onchange="onNewEvent(event)"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - -</div> -<pre id="test"></pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_input_events_for_identical_values.html b/toolkit/components/passwordmgr/test/mochitest/test_input_events_for_identical_values.html deleted file mode 100644 index d058a87f9..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_input_events_for_identical_values.html +++ /dev/null @@ -1,51 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test for input events in Login Manager when username/password are filled in already</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body onload="onNewEvent(event)"> -Login Manager test: input events should fire. - -<script> -runChecksAfterCommonInit(); - -SimpleTest.requestFlakyTimeout("untriaged"); - -/** Test for Login Manager: form fill when form is already filled, should not get input events. **/ - -var onloadFired = false; - -function onNewEvent(e) { - console.error("Got " + e.type + " event."); - if (e.type == "load") { - onloadFired = true; - $_(1, "uname").focus(); - sendKey("Tab"); - } else { - ok(false, "Got an input event for " + e.target.name + " field, which shouldn't happen."); - } -} -</script> - -<p id="display"></p> - -<div id="content"> - - <form id="form1" action="formtest.js"> - <p>This is form 1.</p> - <input type="text" name="uname" oninput="onNewEvent(event)" value="testuser"> - <input type="password" name="pword" oninput="onNewEvent(event)" onfocus="setTimeout(function() { SimpleTest.finish() }, 1000);" value="testpass"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - -</div> -<pre id="test"></pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_autocomplete.html b/toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_autocomplete.html deleted file mode 100644 index c5d0a44fa..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_autocomplete.html +++ /dev/null @@ -1,861 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test insecure form field autocomplete</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="satchel_common.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> - -<script> -var chromeScript = runChecksAfterCommonInit(); - -var setupScript = runInParent(function setup() { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - Cu.import("resource://gre/modules/Services.jsm"); - - // Create some logins just for this form, since we'll be deleting them. - var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); - assert.ok(nsLoginInfo != null, "nsLoginInfo constructor"); - - // login0 has no username, so should be filtered out from the autocomplete list. - var login0 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "", "user0pass", "", "pword"); - - var login1 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "tempuser1", "temppass1", "uname", "pword"); - - var login2 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "testuser2", "testpass2", "uname", "pword"); - - var login3 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "testuser3", "testpass3", "uname", "pword"); - - var login4 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "zzzuser4", "zzzpass4", "uname", "pword"); - - // login 5 only used in the single-user forms - var login5 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete2", null, - "singleuser5", "singlepass5", "uname", "pword"); - - var login6A = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete3", null, - "form7user1", "form7pass1", "uname", "pword"); - var login6B = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete3", null, - "form7user2", "form7pass2", "uname", "pword"); - - var login7 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete4", null, - "form8user", "form8pass", "uname", "pword"); - - var login8A = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null, - "form9userAB", "form9pass", "uname", "pword"); - var login8B = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null, - "form9userAAB", "form9pass", "uname", "pword"); - var login8C = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete5", null, - "form9userAABzz", "form9pass", "uname", "pword"); - - var login10 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete7", null, - "testuser10", "testpass10", "uname", "pword"); - - - // try/catch in case someone runs the tests manually, twice. - try { - Services.logins.addLogin(login0); - Services.logins.addLogin(login1); - Services.logins.addLogin(login2); - Services.logins.addLogin(login3); - Services.logins.addLogin(login4); - Services.logins.addLogin(login5); - Services.logins.addLogin(login6A); - Services.logins.addLogin(login6B); - Services.logins.addLogin(login7); - Services.logins.addLogin(login8A); - Services.logins.addLogin(login8B); - // login8C is added later - Services.logins.addLogin(login10); - } catch (e) { - assert.ok(false, "addLogin threw: " + e); - } - - addMessageListener("addLogin", loginVariableName => { - let login = eval(loginVariableName); - assert.ok(!!login, "Login to add is defined: " + loginVariableName); - Services.logins.addLogin(login); - }); - addMessageListener("removeLogin", loginVariableName => { - let login = eval(loginVariableName); - assert.ok(!!login, "Login to delete is defined: " + loginVariableName); - Services.logins.removeLogin(login); - }); -}); -</script> -<p id="display"></p> - -<!-- we presumably can't hide the content for this test. --> -<div id="content"> - - <!-- form1 tests multiple matching logins --> - <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- other forms test single logins, with autocomplete=off set --> - <form id="form2" action="http://autocomplete2" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword" autocomplete="off"> - <button type="submit">Submit</button> - </form> - - <form id="form3" action="http://autocomplete2" onsubmit="return false;"> - <input type="text" name="uname" autocomplete="off"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form4" action="http://autocomplete2" onsubmit="return false;" autocomplete="off"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form5" action="http://autocomplete2" onsubmit="return false;"> - <input type="text" name="uname" autocomplete="off"> - <input type="password" name="pword" autocomplete="off"> - <button type="submit">Submit</button> - </form> - - <!-- control --> - <form id="form6" action="http://autocomplete2" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- This form will be manipulated to insert a different username field. --> - <form id="form7" action="http://autocomplete3" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- test for no autofill after onblur with blank username --> - <form id="form8" action="http://autocomplete4" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- test autocomplete dropdown --> - <form id="form9" action="http://autocomplete5" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- test for onUsernameInput recipe testing --> - <form id="form11" action="http://autocomplete7" onsubmit="return false;"> - <input type="text" name="1"> - <input type="text" name="2"> - <button type="submit">Submit</button> - </form> - - <!-- tests <form>-less autocomplete --> - <div id="form12"> - <input type="text" name="uname" id="uname"> - <input type="password" name="pword" id="pword"> - <button type="submit">Submit</button> - </div> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: multiple login autocomplete. **/ - -var uname = $_(1, "uname"); -var pword = $_(1, "pword"); -const shiftModifier = SpecialPowers.Ci.nsIDOMEvent.SHIFT_MASK; - -// Restore the form to the default state. -function restoreForm() { - uname.value = ""; - pword.value = ""; - uname.focus(); -} - -// Check for expected username/password in form. -function checkACForm(expectedUsername, expectedPassword) { - var formID = uname.parentNode.id; - is(uname.value, expectedUsername, "Checking " + formID + " username is: " + expectedUsername); - is(pword.value, expectedPassword, "Checking " + formID + " password is: " + expectedPassword); -} - -function sendFakeAutocompleteEvent(element) { - var acEvent = document.createEvent("HTMLEvents"); - acEvent.initEvent("DOMAutoComplete", true, false); - element.dispatchEvent(acEvent); -} - -function spinEventLoop() { - return Promise.resolve(); -} - -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({"set": [["security.insecure_field_warning.contextual.enabled", true], - ["signon.autofillForms.http", true]]}); - listenForUnexpectedPopupShown(); -}); - -add_task(function* test_form1_initial_empty() { - yield SimpleTest.promiseFocus(window); - - // Make sure initial form is empty. - checkACForm("", ""); - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is initially closed"); -}); - -add_task(function* test_form1_warning_entry() { - yield SimpleTest.promiseFocus(window); - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - let results = yield shownPromise; - - let popupState = yield getPopupState(); - is(popupState.selectedIndex, -1, "Check no entries are selected upon opening"); - - let expectedMenuItems = ["This connection is not secure. Logins entered here could be compromised. Learn More", - "tempuser1", - "testuser2", - "testuser3", - "zzzuser4"]; - checkArrayValues(results, expectedMenuItems, "Check all menuitems are displayed correctly."); - - doKey("down"); // select insecure warning - checkACForm("", ""); // value shouldn't update just by selecting - doKey("return"); // not "enter"! - yield spinEventLoop(); // let focus happen - checkACForm("", ""); -}); - -add_task(function* test_form1_first_entry() { - yield SimpleTest.promiseFocus(window); - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - let popupState = yield getPopupState(); - is(popupState.selectedIndex, -1, "Check no entries are selected upon opening"); - - doKey("down"); // skip insecure warning - doKey("down"); // first - checkACForm("", ""); // value shouldn't update just by selecting - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("tempuser1", "temppass1"); -}); - -add_task(function* test_form1_second_entry() { - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - doKey("down"); // first - doKey("down"); // second - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_third_entry() { - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - doKey("down"); // first - doKey("down"); // second - doKey("down"); // third - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser3", "testpass3"); -}); - -add_task(function* test_form1_fourth_entry() { - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - doKey("down"); // first - doKey("down"); // second - doKey("down"); // third - doKey("down"); // fourth - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_wraparound_first_entry() { - // Trigger autocomplete popup - restoreForm(); - yield spinEventLoop(); // let focus happen - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - doKey("down"); // first - doKey("down"); // second - doKey("down"); // third - doKey("down"); // fourth - doKey("down"); // deselects - doKey("down"); // skip insecure warning - doKey("down"); // first - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("tempuser1", "temppass1"); -}); - -add_task(function* test_form1_wraparound_up_last_entry() { - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("up"); // last (fourth) - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_wraparound_down_up_up() { - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // select first entry - doKey("up"); // selects nothing! - doKey("up"); // select last entry - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_wraparound_up_last() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); - doKey("up"); // deselects - doKey("up"); // last entry - doKey("up"); - doKey("up"); - doKey("up"); // skip insecure warning - doKey("up"); // first entry - doKey("up"); // deselects - doKey("up"); // last entry - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_fill_username_without_autofill_right() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Set first entry w/o triggering autocomplete - doKey("down"); // skip insecure warning - doKey("down"); // first - doKey("right"); - yield spinEventLoop(); - checkACForm("tempuser1", ""); // empty password -}); - -add_task(function* test_form1_fill_username_without_autofill_left() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Set first entry w/o triggering autocomplete - doKey("down"); // skip insecure warning - doKey("down"); // first - doKey("left"); - checkACForm("tempuser1", ""); // empty password -}); - -add_task(function* test_form1_pageup_first() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // Check first entry (page up) - doKey("down"); // first - doKey("down"); // second - doKey("page_up"); // first - doKey("down"); // skip insecure warning - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("tempuser1", "temppass1"); -}); - -add_task(function* test_form1_pagedown_last() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // test 13 - // Check last entry (page down) - doKey("down"); // first - doKey("page_down"); // last - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_untrusted_event() { - restoreForm(); - yield spinEventLoop(); - - // Send a fake (untrusted) event. - checkACForm("", ""); - uname.value = "zzzuser4"; - sendFakeAutocompleteEvent(uname); - yield spinEventLoop(); - checkACForm("zzzuser4", ""); -}); - -add_task(function* test_form1_delete() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - // XXX tried sending character "t" before/during dropdown to test - // filtering, but had no luck. Seemed like the character was getting lost. - // Setting uname.value didn't seem to work either. This works with a human - // driver, so I'm not sure what's up. - - doKey("down"); // skip insecure warning - // Delete the first entry (of 4), "tempuser1" - doKey("down"); - var numLogins; - numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); - is(numLogins, 5, "Correct number of logins before deleting one"); - - let countChangedPromise = notifyMenuChanged(4); - var deletionPromise = promiseStorageChanged(["removeLogin"]); - // On OS X, shift-backspace and shift-delete work, just delete does not. - // On Win/Linux, shift-backspace does not work, delete and shift-delete do. - doKey("delete", shiftModifier); - yield deletionPromise; - - checkACForm("", ""); - numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); - is(numLogins, 4, "Correct number of logins after deleting one"); - yield countChangedPromise; - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_first_after_deletion() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // Check the new first entry (of 3) - doKey("down"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_delete_second() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // Delete the second entry (of 3), "testuser3" - doKey("down"); - doKey("down"); - doKey("delete", shiftModifier); - checkACForm("", ""); - numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); - is(numLogins, 3, "Correct number of logins after deleting one"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("zzzuser4", "zzzpass4"); -}); - -add_task(function* test_form1_first_after_deletion2() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // Check the new first entry (of 2) - doKey("down"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_delete_last() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // test 54 - // Delete the last entry (of 2), "zzzuser4" - doKey("down"); - doKey("down"); - doKey("delete", shiftModifier); - checkACForm("", ""); - numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); - is(numLogins, 2, "Correct number of logins after deleting one"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_first_after_3_deletions() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // Check the only remaining entry - doKey("down"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("testuser2", "testpass2"); -}); - -add_task(function* test_form1_check_only_entry_remaining() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // test 56 - // Delete the only remaining entry, "testuser2" - doKey("down"); - doKey("delete", shiftModifier); - checkACForm("", ""); - numLogins = LoginManager.countLogins("http://mochi.test:8888", "http://autocomplete:8888", null); - is(numLogins, 1, "Correct number of logins after deleting one"); - - // remove the login that's not shown in the list. - setupScript.sendSyncMessage("removeLogin", "login0"); -}); - -// Tests for single-user forms for ignoring autocomplete=off -add_task(function* test_form2() { - // Turn our attention to form2 - uname = $_(2, "uname"); - pword = $_(2, "pword"); - checkACForm("singleuser5", "singlepass5"); - - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // Check first entry - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("singleuser5", "singlepass5"); -}); - -add_task(function* test_form3() { - uname = $_(3, "uname"); - pword = $_(3, "pword"); - checkACForm("singleuser5", "singlepass5"); - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // Check first entry - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("singleuser5", "singlepass5"); -}); - -add_task(function* test_form4() { - uname = $_(4, "uname"); - pword = $_(4, "pword"); - checkACForm("singleuser5", "singlepass5"); - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // Check first entry - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("singleuser5", "singlepass5"); -}); - -add_task(function* test_form5() { - uname = $_(5, "uname"); - pword = $_(5, "pword"); - checkACForm("singleuser5", "singlepass5"); - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // Check first entry - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("singleuser5", "singlepass5"); -}); - -add_task(function* test_form6() { - // (this is a control, w/o autocomplete=off, to ensure the login - // that was being suppressed would have been filled in otherwise) - uname = $_(6, "uname"); - pword = $_(6, "pword"); - checkACForm("singleuser5", "singlepass5"); -}); - -add_task(function* test_form6_changeUsername() { - // Test that the password field remains filled in after changing - // the username. - uname.focus(); - doKey("right"); - sendChar("X"); - // Trigger the 'blur' event on uname - pword.focus(); - yield spinEventLoop(); - checkACForm("singleuser5X", "singlepass5"); - - setupScript.sendSyncMessage("removeLogin", "login5"); -}); - -add_task(function* test_form7() { - uname = $_(7, "uname"); - pword = $_(7, "pword"); - checkACForm("", ""); - - // Insert a new username field into the form. We'll then make sure - // that invoking the autocomplete doesn't try to fill the form. - var newField = document.createElement("input"); - newField.setAttribute("type", "text"); - newField.setAttribute("name", "uname2"); - pword.parentNode.insertBefore(newField, pword); - is($_(7, "uname2").value, "", "Verifying empty uname2"); - - // Delete login6B. It was created just to prevent filling in a login - // automatically, removing it makes it more likely that we'll catch a - // future regression with form filling here. - setupScript.sendSyncMessage("removeLogin", "login6B"); -}); - -add_task(function* test_form7_2() { - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // Check first entry - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - // The form changes, so we expect the old username field to get the - // selected autocomplete value, but neither the new username field nor - // the password field should have any values filled in. - yield spinEventLoop(); - checkACForm("form7user1", ""); - is($_(7, "uname2").value, "", "Verifying empty uname2"); - restoreForm(); // clear field, so reloading test doesn't fail - - setupScript.sendSyncMessage("removeLogin", "login6A"); -}); - -add_task(function* test_form8() { - uname = $_(8, "uname"); - pword = $_(8, "pword"); - checkACForm("form8user", "form8pass"); - restoreForm(); -}); - -add_task(function* test_form8_blur() { - checkACForm("", ""); - // Focus the previous form to trigger a blur. - $_(7, "uname").focus(); -}); - -add_task(function* test_form8_2() { - checkACForm("", ""); - restoreForm(); -}); - -add_task(function* test_form8_3() { - checkACForm("", ""); - setupScript.sendSyncMessage("removeLogin", "login7"); -}); - -add_task(function* test_form9_filtering() { - // Turn our attention to form9 to test the dropdown - bug 497541 - uname = $_(9, "uname"); - pword = $_(9, "pword"); - uname.focus(); - let shownPromise = promiseACShown(); - sendString("form9userAB"); - yield shownPromise; - - checkACForm("form9userAB", ""); - uname.focus(); - doKey("left"); - shownPromise = promiseACShown(); - sendChar("A"); - let results = yield shownPromise; - - 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'"); - doKey("down"); // skip insecure warning - doKey("down"); - doKey("return"); - yield promiseFormsProcessed(); - checkACForm("form9userAAB", "form9pass"); -}); - -add_task(function* test_form9_autocomplete_cache() { - // Note that this addLogin call will only be seen by the autocomplete - // attempt for the sendChar if we do not successfully cache the - // autocomplete results. - setupScript.sendSyncMessage("addLogin", "login8C"); - uname.focus(); - let promise0 = notifyMenuChanged(1); - let shownPromise = promiseACShown(); - sendChar("z"); - yield promise0; - yield shownPromise; - let popupState = yield getPopupState(); - is(popupState.open, true, "Check popup should open"); - - // check that empty results are cached - bug 496466 - promise0 = notifyMenuChanged(1); - sendChar("z"); - yield promise0; - popupState = yield getPopupState(); - is(popupState.open, true, "Check popup stays opened due to cached empty result"); -}); - -add_task(function* test_form11_recipes() { - yield loadRecipes({ - siteRecipes: [{ - "hosts": ["mochi.test:8888"], - "usernameSelector": "input[name='1']", - "passwordSelector": "input[name='2']" - }], - }); - uname = $_(11, "1"); - pword = $_(11, "2"); - - // First test DOMAutocomplete - // Switch the password field to type=password so _fillForm marks the username - // field for autocomplete. - pword.type = "password"; - yield promiseFormsProcessed(); - restoreForm(); - checkACForm("", ""); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - doKey("down"); - checkACForm("", ""); // value shouldn't update - doKey("return"); // not "enter"! - yield promiseFormsProcessed(); - checkACForm("testuser10", "testpass10"); - - // Now test recipes with blur on the username field. - restoreForm(); - checkACForm("", ""); - uname.value = "testuser10"; - checkACForm("testuser10", ""); - doKey("tab"); - yield promiseFormsProcessed(); - checkACForm("testuser10", "testpass10"); - yield resetRecipes(); -}); - -add_task(function* test_form12_formless() { - // Test form-less autocomplete - uname = $_(12, "uname"); - pword = $_(12, "pword"); - restoreForm(); - checkACForm("", ""); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - doKey("down"); // skip insecure warning - // Trigger autocomplete - doKey("down"); - checkACForm("", ""); // value shouldn't update - let processedPromise = promiseFormsProcessed(); - doKey("return"); // not "enter"! - yield processedPromise; - checkACForm("testuser", "testpass"); -}); -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_no_saved_login.html b/toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_no_saved_login.html deleted file mode 100644 index c3a894958..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_no_saved_login.html +++ /dev/null @@ -1,103 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test basic login, contextual inscure password warning without saved logins</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="satchel_common.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: contextual inscure password warning without saved logins - -<script> -let chromeScript = runChecksAfterCommonInit(); -</script> -<p id="display"></p> - -<!-- we presumably can't hide the content for this test. --> -<div id="content"> - - <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: contextual inscure password warning without saved logins. **/ - -// Set to pref before the document loads. -SpecialPowers.setBoolPref( - "security.insecure_field_warning.contextual.enabled", true); - -SimpleTest.registerCleanupFunction(() => { - SpecialPowers.clearUserPref( - "security.insecure_field_warning.contextual.enabled"); -}); - -let uname = $_(1, "uname"); -let pword = $_(1, "pword"); -const shiftModifier = SpecialPowers.Ci.nsIDOMEvent.SHIFT_MASK; - -// Restore the form to the default state. -function restoreForm() { - uname.value = ""; - pword.value = ""; - uname.focus(); -} - -// Check for expected username/password in form. -function checkACForm(expectedUsername, expectedPassword) { - let formID = uname.parentNode.id; - is(uname.value, expectedUsername, "Checking " + formID + " username is: " + expectedUsername); - is(pword.value, expectedPassword, "Checking " + formID + " password is: " + expectedPassword); -} - -function spinEventLoop() { - return Promise.resolve(); -} - -add_task(function* setup() { - listenForUnexpectedPopupShown(); -}); - -add_task(function* test_form1_initial_empty() { - yield SimpleTest.promiseFocus(window); - - // Make sure initial form is empty. - checkACForm("", ""); - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is initially closed"); -}); - -add_task(function* test_form1_warning_entry() { - yield SimpleTest.promiseFocus(window); - // Trigger autocomplete popup - restoreForm(); - let shownPromise = promiseACShown(); - doKey("down"); // open - yield shownPromise; - - let popupState = yield getPopupState(); - is(popupState.open, true, "Check popup is opened"); - is(popupState.selectedIndex, -1, "Check no entries are selected upon opening"); - - doKey("down"); // select insecure warning - checkACForm("", ""); // value shouldn't update just by selecting - doKey("return"); // not "enter"! - yield spinEventLoop(); // let focus happen - checkACForm("", ""); -}); - -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_maxlength.html b/toolkit/components/passwordmgr/test/mochitest/test_maxlength.html deleted file mode 100644 index 2b6da33ec..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_maxlength.html +++ /dev/null @@ -1,137 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test for maxlength attributes</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: Bug 391514 -<script> -runChecksAfterCommonInit(() => startTest()); -</script> -<p id="display"></p> -<div id="content" style="display: none"> - <!-- normal form. --> - <form id="form1" action="formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- limited username --> - <form id="form2" action="formtest.js"> - <input type="text" name="uname" maxlength="4"> - <input type="password" name="pword"> - </form> - - <!-- limited password --> - <form id="form3" action="formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword" maxlength="4"> - </form> - - <!-- limited username and password --> - <form id="form4" action="formtest.js"> - <input type="text" name="uname" maxlength="4"> - <input type="password" name="pword" maxlength="4"> - </form> - - - <!-- limited username --> - <form id="form5" action="formtest.js"> - <input type="text" name="uname" maxlength="0"> - <input type="password" name="pword"> - </form> - - <!-- limited password --> - <form id="form6" action="formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword" maxlength="0"> - </form> - - <!-- limited username and password --> - <form id="form7" action="formtest.js"> - <input type="text" name="uname" maxlength="0"> - <input type="password" name="pword" maxlength="0"> - </form> - - - <!-- limited, but ok, username --> - <form id="form8" action="formtest.js"> - <input type="text" name="uname" maxlength="999"> - <input type="password" name="pword"> - </form> - - <!-- limited, but ok, password --> - <form id="form9" action="formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword" maxlength="999"> - </form> - - <!-- limited, but ok, username and password --> - <form id="form10" action="formtest.js"> - <input type="text" name="uname" maxlength="999"> - <input type="password" name="pword" maxlength="999"> - </form> - - - <!-- limited, but ok, username --> - <!-- (note that filled values are exactly 8 characters) --> - <form id="form11" action="formtest.js"> - <input type="text" name="uname" maxlength="8"> - <input type="password" name="pword"> - </form> - - <!-- limited, but ok, password --> - <!-- (note that filled values are exactly 8 characters) --> - <form id="form12" action="formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword" maxlength="8"> - </form> - - <!-- limited, but ok, username and password --> - <!-- (note that filled values are exactly 8 characters) --> - <form id="form13" action="formtest.js"> - <input type="text" name="uname" maxlength="8"> - <input type="password" name="pword" maxlength="8"> - </form> - -</div> -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/* Test for Login Manager: 391514 (Login Manager gets confused with - * password/PIN on usaa.com) - */ - -function startTest() { - var i; - - is($_(1, "uname").value, "testuser", "Checking for filled username 1"); - is($_(1, "pword").value, "testpass", "Checking for filled password 1"); - - for (i = 2; i < 8; i++) { - is($_(i, "uname").value, "", "Checking for unfilled username " + i); - is($_(i, "pword").value, "", "Checking for unfilled password " + i); - } - - for (i = 8; i < 14; i++) { - is($_(i, "uname").value, "testuser", "Checking for filled username " + i); - is($_(i, "pword").value, "testpass", "Checking for filled password " + i); - } - - // Note that tests 11-13 are limited to exactly the expected value. - // Assert this lest someone change the login we're testing with. - is($_(11, "uname").value.length, 8, "asserting test assumption is valid."); - - SimpleTest.finish(); -} -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html b/toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html deleted file mode 100644 index 443c8a5e9..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html +++ /dev/null @@ -1,291 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test basic login autocomplete</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="satchel_common.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: multiple login autocomplete - -<script> -var chromeScript = runChecksAfterCommonInit(); - -var setupScript = runInParent(function setup() { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - Cu.import("resource://gre/modules/Services.jsm"); - - // Create some logins just for this form, since we'll be deleting them. - var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); - assert.ok(nsLoginInfo != null, "nsLoginInfo constructor"); - - // login0 has no username, so should be filtered out from the autocomplete list. - var login0 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "", "user0pass", "", "pword"); - - var login1 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "tempuser1", "temppass1", "uname", "pword"); - - var login2 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "testuser2", "testpass2", "uname", "pword"); - - var login3 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "testuser3", "testpass3", "uname", "pword"); - - var login4 = new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "zzzuser4", "zzzpass4", "uname", "pword"); - - - // try/catch in case someone runs the tests manually, twice. - try { - Services.logins.addLogin(login0); - Services.logins.addLogin(login1); - Services.logins.addLogin(login2); - Services.logins.addLogin(login3); - Services.logins.addLogin(login4); - } catch (e) { - assert.ok(false, "addLogin threw: " + e); - } - - addMessageListener("addLogin", loginVariableName => { - let login = eval(loginVariableName); - assert.ok(!!login, "Login to add is defined: " + loginVariableName); - Services.logins.addLogin(login); - }); - addMessageListener("removeLogin", loginVariableName => { - let login = eval(loginVariableName); - assert.ok(!!login, "Login to delete is defined: " + loginVariableName); - Services.logins.removeLogin(login); - }); -}); -</script> -<p id="display"></p> - -<!-- we presumably can't hide the content for this test. --> -<div id="content"> - - <!-- form1 tests multiple matching logins --> - <form id="form1" action="http://autocomplete:8888/formtest.js" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <form id="form2" action="http://autocomplete:8888/formtest.js" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword" readonly="true"> - <button type="submit">Submit</button> - </form> - - <form id="form3" action="http://autocomplete:8888/formtest.js" onsubmit="return false;"> - <input type="text" name="uname"> - <input type="password" name="pword" disabled="true"> - <button type="submit">Submit</button> - </form> - -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: multiple login autocomplete. **/ - -var uname = $_(1, "uname"); -var pword = $_(1, "pword"); -const shiftModifier = SpecialPowers.Ci.nsIDOMEvent.SHIFT_MASK; - -// Restore the form to the default state. -function* reinitializeForm(index) { - // Using innerHTML is for creating the autocomplete popup again, so the - // preference value will be applied to the constructor of - // UserAutoCompleteResult. - let form = document.getElementById("form" + index); - let temp = form.innerHTML; - form.innerHTML = ""; - form.innerHTML = temp; - - yield new Promise(resolve => { - let observer = SpecialPowers.wrapCallback(() => { - SpecialPowers.removeObserver(observer, "passwordmgr-processed-form"); - resolve(); - }); - SpecialPowers.addObserver(observer, "passwordmgr-processed-form", false); - }); - - yield SimpleTest.promiseFocus(window); - - uname = $_(index, "uname"); - pword = $_(index, "pword"); - uname.value = ""; - pword.value = ""; - pword.focus(); -} - -function generateDateString(date) { - let dateAndTimeFormatter = new Intl.DateTimeFormat(undefined, - { day: "numeric", month: "short", year: "numeric" }); - return dateAndTimeFormatter.format(date); -} - -const DATE_NOW_STRING = generateDateString(new Date()); - -// Check for expected username/password in form. -function checkACFormPasswordField(expectedPassword) { - var formID = uname.parentNode.id; - is(pword.value, expectedPassword, "Checking " + formID + " password is: " + expectedPassword); -} - -function spinEventLoop() { - return Promise.resolve(); -} - -add_task(function* setup() { - listenForUnexpectedPopupShown(); -}); - -add_task(function* test_form1_initial_empty() { - yield SimpleTest.promiseFocus(window); - - // Make sure initial form is empty. - checkACFormPasswordField(""); - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is initially closed"); -}); - -add_task(function* test_form2_password_readonly() { - yield SpecialPowers.pushPrefEnv({"set": [ - ["security.insecure_field_warning.contextual.enabled", true], - ["signon.autofillForms.http", true] - ]}); - yield reinitializeForm(2); - - // Trigger autocomplete popup - doKey("down"); // open - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is closed for a readonly field."); -}); - -add_task(function* test_form3_password_disabled() { - yield SpecialPowers.pushPrefEnv({"set": [ - ["security.insecure_field_warning.contextual.enabled", true], - ["signon.autofillForms.http", true] - ]}); - yield reinitializeForm(3); - - // Trigger autocomplete popup - doKey("down"); // open - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is closed for a disabled field."); -}); - -add_task(function* test_form1_enabledInsecureFieldWarning_enabledInsecureAutoFillForm() { - yield SpecialPowers.pushPrefEnv({"set": [ - ["security.insecure_field_warning.contextual.enabled", true], - ["signon.autofillForms.http", true] - ]}); - yield reinitializeForm(1); - // Trigger autocomplete popup - let shownPromise = promiseACShown(); - doKey("down"); // open - let results = yield shownPromise; - - let popupState = yield getPopupState(); - is(popupState.selectedIndex, -1, "Check no entries are selected upon opening"); - - let expectedMenuItems = ["This connection is not secure. Logins entered here could be compromised. Learn More", - "No username (" + DATE_NOW_STRING + ")", - "tempuser1", - "testuser2", - "testuser3", - "zzzuser4"]; - checkArrayValues(results, expectedMenuItems, "Check all menuitems are displayed correctly."); - - doKey("down"); // select insecure warning - checkACFormPasswordField(""); // value shouldn't update just by selecting - doKey("return"); // not "enter"! - yield spinEventLoop(); // let focus happen - checkACFormPasswordField(""); -}); - -add_task(function* test_form1_disabledInsecureFieldWarning_enabledInsecureAutoFillForm() { - yield SpecialPowers.pushPrefEnv({"set": [ - ["security.insecure_field_warning.contextual.enabled", false], - ["signon.autofillForms.http", true] - ]}); - yield reinitializeForm(1); - - // Trigger autocomplete popup - let shownPromise = promiseACShown(); - doKey("down"); // open - let results = yield shownPromise; - - let popupState = yield getPopupState(); - is(popupState.selectedIndex, -1, "Check no entries are selected upon opening"); - - let expectedMenuItems = ["No username (" + DATE_NOW_STRING + ")", - "tempuser1", - "testuser2", - "testuser3", - "zzzuser4"]; - checkArrayValues(results, expectedMenuItems, "Check all menuitems are displayed correctly."); - - doKey("down"); // select first item - checkACFormPasswordField(""); // value shouldn't update just by selecting - doKey("return"); // not "enter"! - yield spinEventLoop(); // let focus happen - checkACFormPasswordField("user0pass"); -}); - -add_task(function* test_form1_enabledInsecureFieldWarning_disabledInsecureAutoFillForm() { - yield SpecialPowers.pushPrefEnv({"set": [ - ["security.insecure_field_warning.contextual.enabled", true], - ["signon.autofillForms.http", false] - ]}); - yield reinitializeForm(1); - - // Trigger autocomplete popup - let shownPromise = promiseACShown(); - doKey("down"); // open - let results = yield shownPromise; - - let popupState = yield getPopupState(); - is(popupState.selectedIndex, -1, "Check no entries are selected upon opening"); - - let expectedMenuItems = ["This connection is not secure. Logins entered here could be compromised. Learn More", - "No username (" + DATE_NOW_STRING + ")", - "tempuser1", - "testuser2", - "testuser3", - "zzzuser4"]; - checkArrayValues(results, expectedMenuItems, "Check all menuitems are displayed correctly."); - - doKey("down"); // select insecure warning - checkACFormPasswordField(""); // value shouldn't update just by selecting - doKey("return"); // not "enter"! - yield spinEventLoop(); // let focus happen - checkACFormPasswordField(""); -}); - -add_task(function* test_form1_disabledInsecureFieldWarning_disabledInsecureAutoFillForm() { - yield SpecialPowers.pushPrefEnv({"set": [ - ["security.insecure_field_warning.contextual.enabled", false], - ["signon.autofillForms.http", false] - ]}); - yield reinitializeForm(1); - - // Trigger autocomplete popup - doKey("down"); // open - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is closed with no AutoFillForms."); -}); - -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_passwords_in_type_password.html b/toolkit/components/passwordmgr/test/mochitest/test_passwords_in_type_password.html deleted file mode 100644 index e107cebe6..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_passwords_in_type_password.html +++ /dev/null @@ -1,122 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test that passwords only get filled in type=password</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: Bug 242956 -<script> -runChecksAfterCommonInit(() => startTest()); -</script> -<p id="display"></p> -<div id="content" style="display: none"> - <!-- pword is not a type=password input --> - <form id="form1" action="formtest.js"> - <input type="text" name="uname"> - <input type="text" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- uname is not a type=text input --> - <form id="form2" action="formtest.js"> - <input type="password" name="uname"> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- two "pword" inputs, (text + password) --> - <form id="form3" action="formtest.js"> - <input type="text" name="uname"> - <input type="text" name="pword"> - <input type="password" name="qword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- same thing, different order --> - <form id="form4" action="formtest.js"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <input type="text" name="qword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- uname is not a type=text input (try a checkbox just for variety) --> - <form id="form5" action="formtest.js"> - <input type="checkbox" name="uname" value=""> - <input type="password" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- pword is not a type=password input (try a checkbox just for variety) --> - <form id="form6" action="formtest.js"> - <input type="text" name="uname"> - <input type="checkbox" name="pword" value=""> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - <!-- pword is not a type=password input --> - <form id="form7" action="formtest.js"> - <input type="text" name="uname" value="testuser"> - <input type="text" name="pword"> - - <button type="submit">Submit</button> - <button type="reset"> Reset </button> - </form> - - -</div> -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: 242956 (Stored password is inserted into a - readable text input on a second page) **/ - -// Make sure that pwmgr only puts passwords into type=password <input>s. -// Might as well test the converse, too (username in password field). - -function startTest() { - is($_(1, "uname").value, "", "Checking for unfilled username 1"); - is($_(1, "pword").value, "", "Checking for unfilled password 1"); - - is($_(2, "uname").value, "testpass", "Checking for password not username 2"); - is($_(2, "pword").value, "", "Checking for unfilled password 2"); - - is($_(3, "uname").value, "", "Checking for unfilled username 3"); - is($_(3, "pword").value, "testuser", "Checking for unfilled password 3"); - is($_(3, "qword").value, "testpass", "Checking for unfilled qassword 3"); - - is($_(4, "uname").value, "testuser", "Checking for password not username 4"); - is($_(4, "pword").value, "testpass", "Checking for unfilled password 4"); - is($_(4, "qword").value, "", "Checking for unfilled qassword 4"); - - is($_(5, "uname").value, "", "Checking for unfilled username 5"); - is($_(5, "pword").value, "testpass", "Checking for filled password 5"); - - is($_(6, "uname").value, "", "Checking for unfilled username 6"); - is($_(6, "pword").value, "", "Checking for unfilled password 6"); - - is($_(7, "uname").value, "testuser", "Checking for unmodified username 7"); - is($_(7, "pword").value, "", "Checking for unfilled password 7"); - - SimpleTest.finish(); -} -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt.html deleted file mode 100644 index 1050ab66b..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_prompt.html +++ /dev/null @@ -1,705 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test prompter.{prompt,promptPassword,promptUsernameAndPassword}</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <script type="text/javascript" src="prompt_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<p id="display"></p> - -<div id="content" style="display: none"> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> -var state, action; -var uname = { value: null }; -var pword = { value: null }; -var result = { value: null }; -var isOk; - -// Force parent to not look for tab-modal prompts, as they're not used for auth prompts. -isTabModal = false; - -let prompterParent = runInParent(() => { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - const promptFac = Cc["@mozilla.org/passwordmanager/authpromptfactory;1"]. - getService(Ci.nsIPromptFactory); - - Cu.import("resource://gre/modules/Services.jsm"); - let chromeWin = Services.wm.getMostRecentWindow("navigator:browser"); - let prompter1 = promptFac.getPrompt(chromeWin, Ci.nsIAuthPrompt); - - addMessageListener("proxyPrompter", function onMessage(msg) { - let rv = prompter1[msg.methodName](...msg.args); - return { - rv, - // Send the args back to content so out/inout args can be checked. - args: msg.args, - }; - }); -}); - -let prompter1 = new PrompterProxy(prompterParent); - -const defaultTitle = "the title"; -const defaultMsg = "the message"; - -function initLogins() { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - var login1, login2A, login2B, login2C, login2D, login2E; - var pwmgr = Cc["@mozilla.org/login-manager;1"]. - getService(Ci.nsILoginManager); - - login1 = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2A = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2B = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2C = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2D = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2E = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - - login1.init("http://example.com", null, "http://example.com", - "", "examplepass", "", ""); - login2A.init("http://example2.com", null, "http://example2.com", - "user1name", "user1pass", "", ""); - login2B.init("http://example2.com", null, "http://example2.com", - "user2name", "user2pass", "", ""); - login2C.init("http://example2.com", null, "http://example2.com", - "user3.name@host", "user3pass", "", ""); - login2D.init("http://example2.com", null, "http://example2.com", - "100@beef", "user3pass", "", ""); - login2E.init("http://example2.com", null, "http://example2.com", - "100%beef", "user3pass", "", ""); - - pwmgr.addLogin(login1); - pwmgr.addLogin(login2A); - pwmgr.addLogin(login2B); - pwmgr.addLogin(login2C); - pwmgr.addLogin(login2D); - pwmgr.addLogin(login2E); -} - -add_task(function* setup() { - runInParent(initLogins); -}); - -add_task(function* test_prompt_accept() { - state = { - msg : "the message", - title : "the title", - textValue : "abc", - passValue : "", - iconClass : "question-icon", - titleHidden : true, - textHidden : false, - passHidden : true, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - textField : "xyz", - }; - promptDone = handlePrompt(state, action); - isOk = prompter1.prompt(defaultTitle, defaultMsg, "http://example.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, "abc", result); - yield promptDone; - - ok(isOk, "Checking dialog return value (accept)"); - is(result.value, "xyz", "Checking prompt() returned value"); -}); - -add_task(function* test_prompt_cancel() { - state = { - msg : "the message", - title : "the title", - textValue : "abc", - passValue : "", - iconClass : "question-icon", - titleHidden : true, - textHidden : false, - passHidden : true, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "cancel", - }; - promptDone = handlePrompt(state, action); - isOk = prompter1.prompt(defaultTitle, defaultMsg, "http://example.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, "abc", result); - yield promptDone; - ok(!isOk, "Checking dialog return value (cancel)"); -}); - -add_task(function* test_promptPassword_defaultAccept() { - // Default password provided, existing logins are ignored. - state = { - msg : "the message", - title : "the title", - textValue : "", - passValue : "inputpw", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : true, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "passField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - passField : "secret", - }; - pword.value = "inputpw"; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://example.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(pword.value, "secret", "Checking returned password"); -}); - -add_task(function* test_promptPassword_defaultCancel() { - // Default password provided, existing logins are ignored. - state = { - msg : "the message", - title : "the title", - textValue : "", - passValue : "inputpw", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : true, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "passField", - defButton : "button0", - }; - action = { - buttonClick : "cancel", - }; - pword.value = "inputpw"; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://example.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword); - yield promptDone; - ok(!isOk, "Checking dialog return value (cancel)"); -}); - -add_task(function* test_promptPassword_emptyAccept() { - // No default password provided, realm does not match existing login. - state = { - msg : "the message", - title : "the title", - textValue : "", - passValue : "", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : true, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "passField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - passField : "secret", - }; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://nonexample.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(pword.value, "secret", "Checking returned password"); -}); - -add_task(function* test_promptPassword_saved() { - // No default password provided, matching login is returned w/o prompting. - pword.value = null; - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://example.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword); - ok(isOk, "Checking dialog return value (accept)"); - is(pword.value, "examplepass", "Checking returned password"); -}); - -add_task(function* test_promptPassword_noMatchingPasswordForEmptyUN() { - // No default password provided, none of the logins from this host are - // password-only so the user is prompted. - state = { - msg : "the message", - title : "the title", - textValue : "", - passValue : "", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : true, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "passField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - passField : "secret", - }; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://example2.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(pword.value, "secret", "Checking returned password"); -}); - -add_task(function* test_promptPassword_matchingPWForUN() { - // No default password provided, matching login is returned w/o prompting. - pword.value = null; - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://user1name@example2.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword); - ok(isOk, "Checking dialog return value (accept)"); - is(pword.value, "user1pass", "Checking returned password"); -}); - -add_task(function* test_promptPassword_matchingPWForUN2() { - // No default password provided, matching login is returned w/o prompting. - pword.value = null; - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://user2name@example2.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword); - ok(isOk, "Checking dialog return value (accept)"); - is(pword.value, "user2pass", "Checking returned password"); -}); - -add_task(function* test_promptPassword_matchingPWForUN3() { - // No default password provided, matching login is returned w/o prompting. - pword.value = null; - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://user3%2Ename%40host@example2.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword); - ok(isOk, "Checking dialog return value (accept)"); - is(pword.value, "user3pass", "Checking returned password"); -}); - -add_task(function* test_promptPassword_extraAt() { - // No default password provided, matching login is returned w/o prompting. - pword.value = null; - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://100@beef@example2.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword); - ok(isOk, "Checking dialog return value (accept)"); - is(pword.value, "user3pass", "Checking returned password"); -}); - -add_task(function* test_promptPassword_usernameEncoding() { - // No default password provided, matching login is returned w/o prompting. - pword.value = null; - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "http://100%25beef@example2.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword); - ok(isOk, "Checking dialog return value (accept)"); - is(pword.value, "user3pass", "Checking returned password"); - - // XXX test saving a password with Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY -}); - -add_task(function* test_promptPassword_realm() { - // We don't pre-fill or save for NS_GetAuthKey-generated realms, but we should still prompt - state = { - msg : "the message", - title : "the title", - textValue : "", - passValue : "", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : true, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "passField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - passField : "fill2pass", - }; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(pword.value, "fill2pass", "Checking returned password"); -}); - -add_task(function* test_promptPassword_realm2() { - // We don't pre-fill or save for NS_GetAuthKey-generated realms, but we should still prompt - state = { - msg : "the message", - title : "the title", - textValue : "", - passValue : "", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : true, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "passField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - passField : "fill2pass", - }; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)", - Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(pword.value, "fill2pass", "Checking returned password"); -}); - -add_task(function* test_promptUsernameAndPassword_accept() { - state = { - msg : "the message", - title : "the title", - textValue : "inuser", - passValue : "inpass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - textField : "outuser", - passField : "outpass", - }; - uname.value = "inuser"; - pword.value = "inpass"; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://nonexample.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, uname, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(uname.value, "outuser", "Checking returned username"); - is(pword.value, "outpass", "Checking returned password"); -}); - -add_task(function* test_promptUsernameAndPassword_cancel() { - state = { - msg : "the message", - title : "the title", - textValue : "inuser", - passValue : "inpass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "cancel", - }; - uname.value = "inuser"; - pword.value = "inpass"; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://nonexample.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, uname, pword); - yield promptDone; - ok(!isOk, "Checking dialog return value (cancel)"); -}); - -add_task(function* test_promptUsernameAndPassword_autofill() { - // test filling in existing password-only login - state = { - msg : "the message", - title : "the title", - textValue : "", - passValue : "examplepass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : false, - checkMsg : "Use Password Manager to remember this password.", - checked : true, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - }; - uname.value = null; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(uname.value, "", "Checking returned username"); - is(pword.value, "examplepass", "Checking returned password"); -}); - -add_task(function* test_promptUsernameAndPassword_multipleExisting() { - // test filling in existing login (undetermined from multiple selection) - // user2name/user2pass would also be valid to fill here. - state = { - msg : "the message", - title : "the title", - textValue : "user1name", - passValue : "user1pass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : false, - checkMsg : "Use Password Manager to remember this password.", - checked : true, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - }; - uname.value = null; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - ok(uname.value == "user1name" || uname.value == "user2name", "Checking returned username"); - ok(pword.value == "user1pass" || uname.value == "user2pass", "Checking returned password"); -}); - -add_task(function* test_promptUsernameAndPassword_multipleExisting1() { - // test filling in existing login (user1 from multiple selection) - state = { - msg : "the message", - title : "the title", - textValue : "user1name", - passValue : "user1pass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : false, - checkMsg : "Use Password Manager to remember this password.", - checked : true, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - }; - uname.value = "user1name"; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(uname.value, "user1name", "Checking returned username"); - is(pword.value, "user1pass", "Checking returned password"); -}); - -add_task(function* test_promptUsernameAndPassword_multipleExisting2() { - // test filling in existing login (user2 from multiple selection) - state = { - msg : "the message", - title : "the title", - textValue : "user2name", - passValue : "user2pass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : false, - checkMsg : "Use Password Manager to remember this password.", - checked : true, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - }; - uname.value = "user2name"; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(uname.value, "user2name", "Checking returned username"); - is(pword.value, "user2pass", "Checking returned password"); -}); - -add_task(function* test_promptUsernameAndPassword_passwordChange() { - // test changing password - state = { - msg : "the message", - title : "the title", - textValue : "user2name", - passValue : "user2pass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : false, - checkMsg : "Use Password Manager to remember this password.", - checked : true, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - passField : "NEWuser2pass", - }; - uname.value = "user2name"; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(uname.value, "user2name", "Checking returned username"); - is(pword.value, "NEWuser2pass", "Checking returned password"); -}); - -add_task(function* test_promptUsernameAndPassword_changePasswordBack() { - // test changing password (back to original value) - state = { - msg : "the message", - title : "the title", - textValue : "user2name", - passValue : "NEWuser2pass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : false, - checkMsg : "Use Password Manager to remember this password.", - checked : true, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - passField : "user2pass", - }; - uname.value = "user2name"; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "http://example2.com", - Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(uname.value, "user2name", "Checking returned username"); - is(pword.value, "user2pass", "Checking returned password"); -}); - -add_task(function* test_promptUsernameAndPassword_realm() { - // We don't pre-fill or save for NS_GetAuthKey-generated realms, but we should still prompt - state = { - msg : "the message", - title : "the title", - textValue : "", - passValue : "", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - textField : "fill2user", - passField : "fill2pass", - }; - uname.value = null; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)", - Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, uname, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(uname.value, "fill2user", "Checking returned username"); - is(pword.value, "fill2pass", "Checking returned password"); -}); - -add_task(function* test_promptUsernameAndPassword_realm2() { - // We don't pre-fill or save for NS_GetAuthKey-generated realms, but we should still prompt - state = { - msg : "the message", - title : "the title", - textValue : "", - passValue : "", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - textField : "fill2user", - passField : "fill2pass", - }; - uname.value = null; - pword.value = null; - promptDone = handlePrompt(state, action); - isOk = prompter1.promptUsernameAndPassword(defaultTitle, defaultMsg, "example2.com:80 (somerealm)", - Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword); - yield promptDone; - ok(isOk, "Checking dialog return value (accept)"); - is(uname.value, "fill2user", "Checking returned username"); - is(pword.value, "fill2pass", "Checking returned password"); -}); - -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html deleted file mode 100644 index 0dc8fdf9c..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html +++ /dev/null @@ -1,362 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test HTTP auth prompts by loading authenticate.sjs</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <script type="text/javascript" src="prompt_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<p id="display"></p> - -<div id="content" style="display: none"> - <iframe id="iframe"></iframe> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> -var iframe = document.getElementById("iframe"); - -// Force parent to not look for tab-modal prompts, as they're not used for auth prompts. -isTabModal = false; - -const AUTHENTICATE_PATH = new URL("authenticate.sjs", window.location.href).pathname; - -let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js")); - -runInParent(() => { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - Cu.import("resource://gre/modules/Services.jsm"); - - let pwmgr = Cc["@mozilla.org/login-manager;1"]. - getService(Ci.nsILoginManager); - - let login3A, login3B, login4; - login3A = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login3B = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login4 = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let httpUpgradeLogin = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let httpsDowngradeLogin = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let dedupeHttpUpgradeLogin = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let dedupeHttpsUpgradeLogin = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - - - login3A.init("http://mochi.test:8888", null, "mochitest", - "mochiuser1", "mochipass1", "", ""); - login3B.init("http://mochi.test:8888", null, "mochitest2", - "mochiuser2", "mochipass2", "", ""); - login4.init("http://mochi.test:8888", null, "mochitest3", - "mochiuser3", "mochipass3-old", "", ""); - // Logins to test scheme upgrades (allowed) and downgrades (disallowed) - httpUpgradeLogin.init("http://example.com", null, "schemeUpgrade", - "httpUser", "httpPass", "", ""); - httpsDowngradeLogin.init("https://example.com", null, "schemeDowngrade", - "httpsUser", "httpsPass", "", ""); - // HTTP and HTTPS version of the same domain and realm but with different passwords. - dedupeHttpUpgradeLogin.init("http://example.org", null, "schemeUpgradeDedupe", - "dedupeUser", "httpPass", "", ""); - dedupeHttpsUpgradeLogin.init("https://example.org", null, "schemeUpgradeDedupe", - "dedupeUser", "httpsPass", "", ""); - - - pwmgr.addLogin(login3A); - pwmgr.addLogin(login3B); - pwmgr.addLogin(login4); - pwmgr.addLogin(httpUpgradeLogin); - pwmgr.addLogin(httpsDowngradeLogin); - pwmgr.addLogin(dedupeHttpUpgradeLogin); - pwmgr.addLogin(dedupeHttpsUpgradeLogin); -}); - -add_task(function* test_iframe() { - let state = { - msg : "http://mochi.test:8888 is requesting your username and password. The site says: “mochitest”", - title : "Authentication Required", - textValue : "mochiuser1", - passValue : "mochipass1", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - let action = { - buttonClick : "ok", - }; - promptDone = handlePrompt(state, action); - - // The following tests are driven by iframe loads - - var iframeLoaded = onloadPromiseFor("iframe"); - iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1"; - yield promptDone; - yield iframeLoaded; - checkEchoedAuthInfo({user: "mochiuser1", pass: "mochipass1"}, - iframe.contentDocument); - - state = { - msg : "http://mochi.test:8888 is requesting your username and password. The site says: “mochitest2”", - title : "Authentication Required", - textValue : "mochiuser2", - passValue : "mochipass2", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - }; - promptDone = handlePrompt(state, action); - // We've already authenticated to this host:port. For this next - // request, the existing auth should be sent, we'll get a 401 reply, - // and we should prompt for new auth. - iframeLoaded = onloadPromiseFor("iframe"); - iframe.src = "authenticate.sjs?user=mochiuser2&pass=mochipass2&realm=mochitest2"; - yield promptDone; - yield iframeLoaded; - checkEchoedAuthInfo({user: "mochiuser2", pass: "mochipass2"}, - iframe.contentDocument); - - // Now make a load that requests the realm from test 1000. It was - // already provided there, so auth will *not* be prompted for -- the - // networking layer already knows it! - iframeLoaded = onloadPromiseFor("iframe"); - iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1"; - yield iframeLoaded; - checkEchoedAuthInfo({user: "mochiuser1", pass: "mochipass1"}, - iframe.contentDocument); - - // Same realm we've already authenticated to, but with a different - // expected password (to trigger an auth prompt, and change-password - // popup notification). - state = { - msg : "http://mochi.test:8888 is requesting your username and password. The site says: “mochitest”", - title : "Authentication Required", - textValue : "mochiuser1", - passValue : "mochipass1", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - passField : "mochipass1-new", - }; - promptDone = handlePrompt(state, action); - iframeLoaded = onloadPromiseFor("iframe"); - let promptShownPromise = promisePromptShown("passwordmgr-prompt-change"); - iframe.src = "authenticate.sjs?user=mochiuser1&pass=mochipass1-new"; - yield promptDone; - yield iframeLoaded; - checkEchoedAuthInfo({user: "mochiuser1", pass: "mochipass1-new"}, - iframe.contentDocument); - yield promptShownPromise; - - // Same as last test, but for a realm we haven't already authenticated - // to (but have an existing saved login for, so that we'll trigger - // a change-password popup notification. - state = { - msg : "http://mochi.test:8888 is requesting your username and password. The site says: “mochitest3”", - title : "Authentication Required", - textValue : "mochiuser3", - passValue : "mochipass3-old", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - passField : "mochipass3-new", - }; - promptDone = handlePrompt(state, action); - iframeLoaded = onloadPromiseFor("iframe"); - promptShownPromise = promisePromptShown("passwordmgr-prompt-change"); - iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-new&realm=mochitest3"; - yield promptDone; - yield iframeLoaded; - checkEchoedAuthInfo({user: "mochiuser3", pass: "mochipass3-new"}, - iframe.contentDocument); - yield promptShownPromise; - - // Housekeeping: Delete login4 to test the save prompt in the next test. - runInParent(() => { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - Cu.import("resource://gre/modules/Services.jsm"); - - var tmpLogin = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - tmpLogin.init("http://mochi.test:8888", null, "mochitest3", - "mochiuser3", "mochipass3-old", "", ""); - Services.logins.removeLogin(tmpLogin); - - // Clear cached auth from this subtest, and avoid leaking due to bug 459620. - var authMgr = Cc['@mozilla.org/network/http-auth-manager;1']. - getService(Ci.nsIHttpAuthManager); - authMgr.clearAll(); - }); - - state = { - msg : "http://mochi.test:8888 is requesting your username and password. The site says: “mochitest3”", - title : "Authentication Required", - textValue : "", - passValue : "", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - textField : "mochiuser3", - passField : "mochipass3-old", - }; - // Trigger a new prompt, so we can test adding a new login. - promptDone = handlePrompt(state, action); - - iframeLoaded = onloadPromiseFor("iframe"); - promptShownPromise = promisePromptShown("passwordmgr-prompt-save"); - iframe.src = "authenticate.sjs?user=mochiuser3&pass=mochipass3-old&realm=mochitest3"; - yield promptDone; - yield iframeLoaded; - checkEchoedAuthInfo({user: "mochiuser3", pass: "mochipass3-old"}, - iframe.contentDocument); - yield promptShownPromise; -}); - -add_task(function* test_schemeUpgrade() { - let state = { - msg : "https://example.com is requesting your username and password. " + - "WARNING: Your password will not be sent to the website you are currently visiting!", - title : "Authentication Required", - textValue : "httpUser", - passValue : "httpPass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - let action = { - buttonClick : "ok", - }; - let promptDone = handlePrompt(state, action); - - // The following tests are driven by iframe loads - - let iframeLoaded = onloadPromiseFor("iframe"); - iframe.src = "https://example.com" + AUTHENTICATE_PATH + - "?user=httpUser&pass=httpPass&realm=schemeUpgrade"; - yield promptDone; - yield iframeLoaded; - checkEchoedAuthInfo({user: "httpUser", pass: "httpPass"}, - SpecialPowers.wrap(iframe).contentDocument); -}); - -add_task(function* test_schemeDowngrade() { - let state = { - msg : "http://example.com is requesting your username and password. " + - "WARNING: Your password will not be sent to the website you are currently visiting!", - title : "Authentication Required", - textValue : "", // empty because we shouldn't downgrade - passValue : "", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - let action = { - buttonClick : "cancel", - }; - let promptDone = handlePrompt(state, action); - - // The following tests are driven by iframe loads - - let iframeLoaded = onloadPromiseFor("iframe"); - iframe.src = "http://example.com" + AUTHENTICATE_PATH + - "?user=unused&pass=unused&realm=schemeDowngrade"; - yield promptDone; - yield iframeLoaded; -}); - -add_task(function* test_schemeUpgrade_dedupe() { - let state = { - msg : "https://example.org is requesting your username and password. " + - "WARNING: Your password will not be sent to the website you are currently visiting!", - title : "Authentication Required", - textValue : "dedupeUser", - passValue : "httpsPass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - let action = { - buttonClick : "ok", - }; - let promptDone = handlePrompt(state, action); - - // The following tests are driven by iframe loads - - let iframeLoaded = onloadPromiseFor("iframe"); - iframe.src = "https://example.org" + AUTHENTICATE_PATH + - "?user=dedupeUser&pass=httpsPass&realm=schemeUpgradeDedupe"; - yield promptDone; - yield iframeLoaded; - checkEchoedAuthInfo({user: "dedupeUser", pass: "httpsPass"}, - SpecialPowers.wrap(iframe).contentDocument); -}); -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt_noWindow.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt_noWindow.html deleted file mode 100644 index 92af172ca..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_prompt_noWindow.html +++ /dev/null @@ -1,81 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test HTTP auth prompts by loading authenticate.sjs with no window</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <script type="text/javascript" src="prompt_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<p id="display"></p> - -<div id="content" style="display: none"> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -// Force parent to not look for tab-modal prompts, as they're not used for auth prompts. -isTabModal = false; - -let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js")); - -runInParent(() => { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - Cu.import("resource://gre/modules/Services.jsm"); - - let login = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login.init("http://mochi.test:8888", null, "mochitest", - "mochiuser1", "mochipass1", "", ""); - Services.logins.addLogin(login); -}); - -add_task(function* test_sandbox_xhr() { - let state = { - msg : "http://mochi.test:8888 is requesting your username and password. The site says: “mochitest”", - title : "Authentication Required", - textValue : "mochiuser1", - passValue : "mochipass1", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - let action = { - buttonClick : "ok", - }; - let promptDone = handlePrompt(state, action); - - let url = new URL("authenticate.sjs?user=mochiuser1&pass=mochipass1", window.location.href); - let sandboxConstructor = SpecialPowers.Cu.Sandbox; - let sandbox = new sandboxConstructor(this, {wantXrays: true}); - function sandboxedRequest(sandboxedUrl) { - let req = SpecialPowers.Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] - .createInstance(SpecialPowers.Ci.nsIXMLHttpRequest); - req.open("GET", sandboxedUrl, true); - req.send(null); - } - - let loginModifiedPromise = promiseStorageChanged(["modifyLogin"]); - sandbox.sandboxedRequest = sandboxedRequest(url); - info("send the XHR request in the sandbox"); - SpecialPowers.Cu.evalInSandbox("sandboxedRequest;", sandbox); - - yield promptDone; - info("prompt shown, waiting for metadata updates"); - // Ensure the timeLastUsed and timesUsed metadata are updated. - yield loginModifiedPromise; -}); -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth.html deleted file mode 100644 index 36f53a54a..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth.html +++ /dev/null @@ -1,406 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test promptAuth prompts</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <script type="text/javascript" src="prompt_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<p id="display"></p> - -<div id="content" style="display: none"> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> -var state, action; -var isOk; - -var level = Ci.nsIAuthPrompt2.LEVEL_NONE; -var authinfo = { - username : "", - password : "", - domain : "", - - flags : Ci.nsIAuthInformation.AUTH_HOST, - authenticationScheme : "basic", - realm : "" -}; - -// Force parent to not look for tab-modal prompts, as they're not used for auth prompts. -isTabModal = false; - -let chromeScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js")); - -let prompterParent = runInParent(() => { - const { classes: Cc, interfaces: Ci, utils: Cu } = Components; - const promptFac = Cc["@mozilla.org/passwordmanager/authpromptfactory;1"]. - getService(Ci.nsIPromptFactory); - - Cu.import("resource://gre/modules/Services.jsm"); - let chromeWin = Services.wm.getMostRecentWindow("navigator:browser"); - let prompter2 = promptFac.getPrompt(chromeWin, Ci.nsIAuthPrompt2); - - let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); - let channels = {}; - channels.channel1 = ioService.newChannel2("http://example.com", - null, - null, - null, // aLoadingNode - Services. - scriptSecurityManager.getSystemPrincipal(), - null, // aTriggeringPrincipal - Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - Ci.nsIContentPolicy.TYPE_OTHER); - - channels.channel2 = ioService.newChannel2("http://example2.com", - null, - null, - null, // aLoadingNode - Services. - scriptSecurityManager.getSystemPrincipal(), - null, // aTriggeringPrincipal - Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - Ci.nsIContentPolicy.TYPE_OTHER); - - addMessageListener("proxyPrompter", function onMessage(msg) { - let args = [...msg.args]; - let channelName = args.shift(); - // Replace the channel name string (arg. 0) with the channel by that name. - args.unshift(channels[channelName]); - - let rv = prompter2[msg.methodName](...args); - return { - rv, - // Send the args back to content so out/inout args can be checked. - args: msg.args, - }; - }); - - Cu.import("resource://gre/modules/Services.jsm"); - - let pwmgr = Cc["@mozilla.org/login-manager;1"]. - getService(Ci.nsILoginManager); - - let login1, login2A, login2B, login2C, login2D, login2E; - login1 = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2A = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2B = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2C = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2D = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2E = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - - login1.init("http://example.com", null, "http://example.com", - "", "examplepass", "", ""); - login2A.init("http://example2.com", null, "http://example2.com", - "user1name", "user1pass", "", ""); - login2B.init("http://example2.com", null, "http://example2.com", - "user2name", "user2pass", "", ""); - login2C.init("http://example2.com", null, "http://example2.com", - "user3.name@host", "user3pass", "", ""); - login2D.init("http://example2.com", null, "http://example2.com", - "100@beef", "user3pass", "", ""); - login2E.init("http://example2.com", null, "http://example2.com", - "100%beef", "user3pass", "", ""); - - pwmgr.addLogin(login1); - pwmgr.addLogin(login2A); - pwmgr.addLogin(login2B); - pwmgr.addLogin(login2C); - pwmgr.addLogin(login2D); - pwmgr.addLogin(login2E); -}); - -let prompter2 = new PrompterProxy(prompterParent); - -add_task(function* test_accept() { - state = { - msg : "http://example.com is requesting your username and password. The site says: “some realm”", - title : "Authentication Required", - textValue : "inuser", - passValue : "inpass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - textField : "outuser", - passField : "outpass", - }; - authinfo.username = "inuser"; - authinfo.password = "inpass"; - authinfo.realm = "some realm"; - - promptDone = handlePrompt(state, action); - // Since prompter2 is actually a proxy to send a message to a chrome script and - // we can't send a channel in a message, we instead send the channel name that - // already exists in the chromeScript. - isOk = prompter2.promptAuth("channel1", level, authinfo); - yield promptDone; - - ok(isOk, "Checking dialog return value (accept)"); - is(authinfo.username, "outuser", "Checking returned username"); - is(authinfo.password, "outpass", "Checking returned password"); -}); - -add_task(function* test_cancel() { - state = { - msg : "http://example.com is requesting your username and password. The site says: “some realm”", - title : "Authentication Required", - textValue : "outuser", - passValue : "outpass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "cancel", - }; - promptDone = handlePrompt(state, action); - isOk = prompter2.promptAuth("channel1", level, authinfo); - yield promptDone; - - ok(!isOk, "Checking dialog return value (cancel)"); -}); - -add_task(function* test_pwonly() { - // test filling in password-only login - state = { - msg : "http://example.com is requesting your username and password. The site says: “http://example.com”", - title : "Authentication Required", - textValue : "", - passValue : "examplepass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - }; - authinfo.username = ""; - authinfo.password = ""; - authinfo.realm = "http://example.com"; - - promptDone = handlePrompt(state, action); - isOk = prompter2.promptAuth("channel1", level, authinfo); - yield promptDone; - - ok(isOk, "Checking dialog return value (accept)"); - is(authinfo.username, "", "Checking returned username"); - is(authinfo.password, "examplepass", "Checking returned password"); -}); - -add_task(function* test_multipleExisting() { - // test filling in existing login (undetermined from multiple selection) - // user2name/user2pass would also be valid to fill here. - state = { - msg : "http://example2.com is requesting your username and password. The site says: “http://example2.com”", - title : "Authentication Required", - textValue : "user1name", - passValue : "user1pass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - }; - authinfo.username = ""; - authinfo.password = ""; - authinfo.realm = "http://example2.com"; - - promptDone = handlePrompt(state, action); - isOk = prompter2.promptAuth("channel2", level, authinfo); - yield promptDone; - - ok(isOk, "Checking dialog return value (accept)"); - ok(authinfo.username == "user1name" || authinfo.username == "user2name", "Checking returned username"); - ok(authinfo.password == "user1pass" || authinfo.password == "user2pass", "Checking returned password"); -}); - -add_task(function* test_multipleExisting2() { - // test filling in existing login (undetermined --> user1) - // user2name/user2pass would also be valid to fill here. - state = { - msg : "http://example2.com is requesting your username and password. The site says: “http://example2.com”", - title : "Authentication Required", - textValue : "user1name", - passValue : "user1pass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - // enter one of the known logins, test 504+505 exercise the two possible states. - action = { - buttonClick : "ok", - textField : "user1name", - passField : "user1pass", - }; - authinfo.username = ""; - authinfo.password = ""; - authinfo.realm = "http://example2.com"; - - promptDone = handlePrompt(state, action); - isOk = prompter2.promptAuth("channel2", level, authinfo); - yield promptDone; - - ok(isOk, "Checking dialog return value (accept)"); - is(authinfo.username, "user1name", "Checking returned username"); - is(authinfo.password, "user1pass", "Checking returned password"); -}); - -add_task(function* test_multipleExisting3() { - // test filling in existing login (undetermined --> user2) - // user2name/user2pass would also be valid to fill here. - state = { - msg : "http://example2.com is requesting your username and password. The site says: “http://example2.com”", - title : "Authentication Required", - textValue : "user1name", - passValue : "user1pass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - // enter one of the known logins, test 504+505 exercise the two possible states. - action = { - buttonClick : "ok", - textField : "user2name", - passField : "user2pass", - }; - authinfo.username = ""; - authinfo.password = ""; - authinfo.realm = "http://example2.com"; - - promptDone = handlePrompt(state, action); - isOk = prompter2.promptAuth("channel2", level, authinfo); - yield promptDone; - - ok(isOk, "Checking dialog return value (accept)"); - is(authinfo.username, "user2name", "Checking returned username"); - is(authinfo.password, "user2pass", "Checking returned password"); -}); - -add_task(function* test_changingMultiple() { - // test changing a password (undetermined --> user2 w/ newpass) - // user2name/user2pass would also be valid to fill here. - state = { - msg : "http://example2.com is requesting your username and password. The site says: “http://example2.com”", - title : "Authentication Required", - textValue : "user1name", - passValue : "user1pass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - // force to user2, and change the password - action = { - buttonClick : "ok", - textField : "user2name", - passField : "NEWuser2pass", - }; - authinfo.username = ""; - authinfo.password = ""; - authinfo.realm = "http://example2.com"; - - promptDone = handlePrompt(state, action); - isOk = prompter2.promptAuth("channel2", level, authinfo); - yield promptDone; - - ok(isOk, "Checking dialog return value (accept)"); - is(authinfo.username, "user2name", "Checking returned username"); - is(authinfo.password, "NEWuser2pass", "Checking returned password"); -}); - -add_task(function* test_changingMultiple2() { - // test changing a password (undetermined --> user2 w/ origpass) - // user2name/user2pass would also be valid to fill here. - state = { - msg : "http://example2.com is requesting your username and password. The site says: “http://example2.com”", - title : "Authentication Required", - textValue : "user1name", - passValue : "user1pass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - // force to user2, and change the password back - action = { - buttonClick : "ok", - textField : "user2name", - passField : "user2pass", - }; - authinfo.username = ""; - authinfo.password = ""; - authinfo.realm = "http://example2.com"; - - promptDone = handlePrompt(state, action); - isOk = prompter2.promptAuth("channel2", level, authinfo); - yield promptDone; - - ok(isOk, "Checking dialog return value (accept)"); - is(authinfo.username, "user2name", "Checking returned username"); - is(authinfo.password, "user2pass", "Checking returned password"); -}); -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html deleted file mode 100644 index 95dd4c7bc..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html +++ /dev/null @@ -1,264 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test promptAuth proxy prompts</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <script type="text/javascript" src="prompt_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<p id="display"></p> - -<div id="content" style="display: none"> - <iframe id="iframe"></iframe> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> -var state, action; -var pwmgr; -var proxyLogin; -var isOk; -var mozproxy, proxiedHost = "http://mochi.test:8888"; -var proxyChannel; -var systemPrincipal = SpecialPowers.Services.scriptSecurityManager.getSystemPrincipal(); -var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); - -var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch); - -var level = Ci.nsIAuthPrompt2.LEVEL_NONE; - -var proxyAuthinfo = { - username : "", - password : "", - domain : "", - - flags : Ci.nsIAuthInformation.AUTH_PROXY, - authenticationScheme : "basic", - realm : "" -}; - -// Force parent to not look for tab-modal prompts, as they're not used for auth prompts. -isTabModal = false; - -const Cc_promptFac = Cc["@mozilla.org/passwordmanager/authpromptfactory;1"]; -ok(Cc_promptFac != null, "Access Cc[@mozilla.org/passwordmanager/authpromptfactory;1]"); - -const Ci_promptFac = Ci.nsIPromptFactory; -ok(Ci_promptFac != null, "Access Ci.nsIPromptFactory"); - -const promptFac = Cc_promptFac.getService(Ci_promptFac); -ok(promptFac != null, "promptFac getService()"); - -var prompter2 = promptFac.getPrompt(window, Ci.nsIAuthPrompt2); - -function initLogins(pi) { - pwmgr = Cc["@mozilla.org/login-manager;1"]. - getService(Ci.nsILoginManager); - - mozproxy = "moz-proxy://" + SpecialPowers.wrap(pi).host + ":" + - SpecialPowers.wrap(pi).port; - - proxyLogin = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - - proxyLogin.init(mozproxy, null, "Proxy Realm", - "proxuser", "proxpass", "", ""); - - pwmgr.addLogin(proxyLogin); -} - -var startupCompleteResolver; -var startupComplete = new Promise(resolve => startupCompleteResolver = resolve); - -function proxyChannelListener() { } -proxyChannelListener.prototype = { - onStartRequest: function(request, context) { - startupCompleteResolver(); - }, - onStopRequest: function(request, context, status) { } -}; - -var resolveCallback = SpecialPowers.wrapCallbackObject({ - QueryInterface : function (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; - }, - - onProxyAvailable : function (req, uri, pi, status) { - initLogins(pi); - - // I'm cheating a bit here... We should probably do some magic foo to get - // something implementing nsIProxiedProtocolHandler and then call - // NewProxiedChannel(), so we have something that's definately a proxied - // channel. But Mochitests use a proxy for a number of hosts, so just - // requesting a normal channel will give us a channel that's proxied. - // The proxyChannel needs to move to at least on-modify-request to - // have valid ProxyInfo, but we use OnStartRequest during startup() - // for simplicity. - proxyChannel = ioService.newChannel2(proxiedHost, - null, - null, - null, // aLoadingNode - systemPrincipal, - null, // aTriggeringPrincipal - Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - Ci.nsIContentPolicy.TYPE_OTHER); - proxyChannel.asyncOpen2(SpecialPowers.wrapCallbackObject(new proxyChannelListener())); - } -}); - -function startup() { - // Need to allow for arbitrary network servers defined in PAC instead of a hardcoded moz-proxy. - var ios = SpecialPowers.Cc["@mozilla.org/network/io-service;1"]. - getService(SpecialPowers.Ci.nsIIOService); - - var pps = SpecialPowers.Cc["@mozilla.org/network/protocol-proxy-service;1"].getService(); - - var channel = ios.newChannel2("http://example.com", - null, - null, - null, // aLoadingNode - systemPrincipal, - null, // aTriggeringPrincipal - Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_DATA_IS_NULL, - Ci.nsIContentPolicy.TYPE_OTHER); - pps.asyncResolve(channel, 0, resolveCallback); -} - -startup(); - -add_task(function* setup() { - info("Waiting for startup to complete..."); - yield startupComplete; -}); - -add_task(function* test_noAutologin() { - // test proxy login (default = no autologin), make sure it prompts. - state = { - msg : "The proxy moz-proxy://127.0.0.1:8888 is requesting a username and password. The site says: “Proxy Realm”", - title : "Authentication Required", - textValue : "proxuser", - passValue : "proxpass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - }; - proxyAuthinfo.username = ""; - proxyAuthinfo.password = ""; - proxyAuthinfo.realm = "Proxy Realm"; - proxyAuthinfo.flags = Ci.nsIAuthInformation.AUTH_PROXY; - - var time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed; - promptDone = handlePrompt(state, action); - isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo); - yield promptDone; - var time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed; - - ok(isOk, "Checking dialog return value (accept)"); - isnot(time1, time2, "Checking that timeLastUsed was updated"); - is(proxyAuthinfo.username, "proxuser", "Checking returned username"); - is(proxyAuthinfo.password, "proxpass", "Checking returned password"); -}); - -add_task(function* test_autologin() { - // test proxy login (with autologin) - - // Enable the autologin pref. - prefs.setBoolPref("signon.autologin.proxy", true); - - proxyAuthinfo.username = ""; - proxyAuthinfo.password = ""; - proxyAuthinfo.realm = "Proxy Realm"; - proxyAuthinfo.flags = Ci.nsIAuthInformation.AUTH_PROXY; - - time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed; - isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo); - time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed; - - ok(isOk, "Checking dialog return value (accept)"); - isnot(time1, time2, "Checking that timeLastUsed was updated"); - is(proxyAuthinfo.username, "proxuser", "Checking returned username"); - is(proxyAuthinfo.password, "proxpass", "Checking returned password"); -}); - -add_task(function* test_autologin_incorrect() { - // test proxy login (with autologin), ensure it prompts after a failed auth. - state = { - msg : "The proxy moz-proxy://127.0.0.1:8888 is requesting a username and password. The site says: “Proxy Realm”", - title : "Authentication Required", - textValue : "proxuser", - passValue : "proxpass", - iconClass : "authentication-icon question-icon", - titleHidden : true, - textHidden : false, - passHidden : false, - checkHidden : true, - checkMsg : "", - checked : false, - focused : "textField", - defButton : "button0", - }; - action = { - buttonClick : "ok", - }; - - proxyAuthinfo.username = ""; - proxyAuthinfo.password = ""; - proxyAuthinfo.realm = "Proxy Realm"; - proxyAuthinfo.flags = (Ci.nsIAuthInformation.AUTH_PROXY | Ci.nsIAuthInformation.PREVIOUS_FAILED); - - time1 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed; - promptDone = handlePrompt(state, action); - isOk = prompter2.promptAuth(proxyChannel, level, proxyAuthinfo); - yield promptDone; - time2 = pwmgr.findLogins({}, mozproxy, null, "Proxy Realm")[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed; - - ok(isOk, "Checking dialog return value (accept)"); - isnot(time1, time2, "Checking that timeLastUsed was updated"); - is(proxyAuthinfo.username, "proxuser", "Checking returned username"); - is(proxyAuthinfo.password, "proxpass", "Checking returned password"); -}); - -add_task(function* test_autologin_private() { - // test proxy login (with autologin), ensure it prompts in Private Browsing mode. - state = { - msg : "the message", - title : "the title", - textValue : "proxuser", - passValue : "proxpass", - }; - action = { - buttonClick : "ok", - }; - - proxyAuthinfo.username = ""; - proxyAuthinfo.password = ""; - proxyAuthinfo.realm = "Proxy Realm"; - proxyAuthinfo.flags = Ci.nsIAuthInformation.AUTH_PROXY; - - prefs.clearUserPref("signon.autologin.proxy"); - - // XXX check for and kill popup notification?? - // XXX check for checkbox / checkstate on old prompts? - // XXX check NTLM domain stuff -}); -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_recipe_login_fields.html b/toolkit/components/passwordmgr/test/mochitest/test_recipe_login_fields.html deleted file mode 100644 index 943bffc52..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_recipe_login_fields.html +++ /dev/null @@ -1,145 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"> - <title>Test for recipes overriding login fields</title> - <script src="/tests/SimpleTest/SimpleTest.js"></script> - <script src="/tests/SimpleTest/SpawnTask.js"></script> - <script src="pwmgr_common.js"></script> - <link rel="stylesheet" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<script> -var chromeScript = runChecksAfterCommonInit(); - -let fillPromiseResolvers = []; - -function waitForFills(fillCount) { - let promises = []; - while (fillCount--) { - let promise = new Promise(resolve => fillPromiseResolvers.push(resolve)); - promises.push(promise); - } - - return Promise.all(promises); -} - -add_task(function* setup() { - if (document.readyState !== "complete") { - yield new Promise((resolve) => { - document.onreadystatechange = () => { - if (document.readyState !== "complete") { - return; - } - document.onreadystatechange = null; - resolve(); - }; - }); - } - - document.getElementById("content") - .addEventListener("input", function handleInputEvent(evt) { - let resolve = fillPromiseResolvers.shift(); - if (!resolve) { - ok(false, "Too many fills"); - return; - } - - resolve(evt.target); - }); -}); - -add_task(function* loadUsernamePasswordSelectorRecipes() { - yield loadRecipes({ - siteRecipes: [{ - hosts: ["mochi.test:8888"], - usernameSelector: "input[name='uname1']", - passwordSelector: "input[name='pword2']", - }], - }); -}); - -add_task(function* testOverriddingFields() { - // Insert the form dynamically so autofill is triggered after setup above. - document.getElementById("content").innerHTML = ` - <!-- form with recipe for the username and password --> - <form id="form1"> - <input type="text" name="uname1" data-expected="true"> - <input type="text" name="uname2" data-expected="false"> - <input type="password" name="pword1" data-expected="false"> - <input type="password" name="pword2" data-expected="true"> - </form>`; - - let elements = yield waitForFills(2); - for (let element of elements) { - is(element.dataset.expected, "true", `${element.name} was filled`); - } -}); - -add_task(function* testDefaultHeuristics() { - // Insert the form dynamically so autofill is triggered after setup above. - document.getElementById("content").innerHTML = ` - <!-- Fallback to the default heuristics since the selectors don't match --> - <form id="form2"> - <input type="text" name="uname3" data-expected="false"> - <input type="text" name="uname4" data-expected="true"> - <input type="password" name="pword3" data-expected="true"> - <input type="password" name="pword4" data-expected="false"> - </form>`; - - let elements = yield waitForFills(2); - for (let element of elements) { - is(element.dataset.expected, "true", `${element.name} was filled`); - } -}); - -add_task(function* loadNotUsernameSelectorRecipes() { - yield resetRecipes(); - yield loadRecipes({ - siteRecipes: [{ - hosts: ["mochi.test:8888"], - notUsernameSelector: "input[name='not_uname1']" - }], - }); -}); - -add_task(function* testNotUsernameField() { - document.getElementById("content").innerHTML = ` - <!-- The field matching notUsernameSelector should be skipped --> - <form id="form3"> - <input type="text" name="uname5" data-expected="true"> - <input type="text" name="not_uname1" data-expected="false"> - <input type="password" name="pword5" data-expected="true"> - </form>`; - - let elements = yield waitForFills(2); - for (let element of elements) { - is(element.dataset.expected, "true", `${element.name} was filled`); - } -}); - -add_task(function* testNotUsernameFieldNoUsername() { - document.getElementById("content").innerHTML = ` - <!-- The field matching notUsernameSelector should be skipped. - No username field should be found and filled in this case --> - <form id="form4"> - <input type="text" name="not_uname1" data-expected="false"> - <input type="password" name="pword6" data-expected="true"> - </form>`; - - let elements = yield waitForFills(1); - for (let element of elements) { - is(element.dataset.expected, "true", `${element.name} was filled`); - } -}); - -</script> - -<p id="display"></p> - -<div id="content"> - // Forms are inserted dynamically -</div> -<pre id="test"></pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_username_focus.html b/toolkit/components/passwordmgr/test/mochitest/test_username_focus.html deleted file mode 100644 index c93c1e9c9..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_username_focus.html +++ /dev/null @@ -1,263 +0,0 @@ - -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test interaction between autocomplete and focus on username fields</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SpawnTask.js"></script> - <script type="text/javascript" src="satchel_common.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -<script> -let pwmgrCommonScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js")); - -let readyPromise = registerRunTests(); -let chromeScript = runInParent(function chromeSetup() { - const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; - let pwmgr = Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager); - - let login1A = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let login1B = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let login2A = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let login2B = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - let login2C = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - - login1A.init("http://mochi.test:8888", "http://username-focus-1", null, - "testuser1A", "testpass1A", "", ""); - - login2A.init("http://mochi.test:8888", "http://username-focus-2", null, - "testuser2A", "testpass2A", "", ""); - login2B.init("http://mochi.test:8888", "http://username-focus-2", null, - "testuser2B", "testpass2B", "", ""); - - pwmgr.addLogin(login1A); - pwmgr.addLogin(login2A); - pwmgr.addLogin(login2B); -}); -</script> - -<p id="display"></p> -<div id="content"> - <!-- first 3 forms have a matching user+pass login --> - - <!-- user+pass form. --> - <form id="form-autofilled" action="http://username-focus-1"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit" name="submit">Submit</button> - </form> - - <!-- user+pass form, username prefilled --> - <form id="form-autofilled-prefilled-un" action="http://username-focus-1"> - <input type="text" name="uname" value="testuser1A"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- user+pass form. --> - <form id="form-autofilled-focused-dynamic" action="http://username-focus-1"> - <input type="text" name="uname"> - <input type="not-yet-password" name="pword"> - <button type="submit">Submit</button> - </form> - - - <!-- next 5 forms have matching user+pass (2x) logins --> - - <!-- user+pass form. --> - <form id="form-multiple" action="http://username-focus-2"> - <input type="text" name="uname"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- user+pass form dynamic with existing focus --> - <form id="form-multiple-dynamic" action="http://username-focus-2"> - <input type="text" name="uname"> - <input type="not-yet-password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- user+pass form, username prefilled --> - <form id="form-multiple-prefilled-un1" action="http://username-focus-2"> - <input type="text" name="uname" value="testuser2A"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- user+pass form, different username prefilled --> - <form id="form-multiple-prefilled-un2" action="http://username-focus-2"> - <input type="text" name="uname" value="testuser2B"> - <input type="password" name="pword"> - <button type="submit">Submit</button> - </form> - - <!-- user+pass form, username prefilled with existing focus --> - <form id="form-multiple-prefilled-focused-dynamic" action="http://username-focus-2"> - <input type="text" name="uname" value="testuser2B"> - <input type="not-yet-password" name="pword"> - <button type="submit">Submit</button> - </form> - -</div> -<pre id="test"> -<script class="testbody" type="text/javascript"> -function removeFocus() { - $_("-autofilled", "submit").focus(); -} - -add_task(function* setup() { - yield SpecialPowers.pushPrefEnv({"set": [ - ["security.insecure_field_warning.contextual.enabled", false], - ]}); - - ok(readyPromise, "check promise is available"); - yield readyPromise; -}); - -add_task(function* test_autofilled() { - let usernameField = $_("-autofilled", "uname"); - info("Username and password already filled so don't show autocomplete"); - let noPopupPromise = promiseNoUnexpectedPopupShown(); - usernameField.focus(); - yield noPopupPromise; - - removeFocus(); - usernameField.value = "testuser"; - info("Focus when we don't have an exact match"); - shownPromise = promiseACShown(); - usernameField.focus(); - yield shownPromise; -}); - -add_task(function* test_autofilled_prefilled_un() { - let usernameField = $_("-autofilled-prefilled-un", "uname"); - info("Username and password already filled so don't show autocomplete"); - let noPopupPromise = promiseNoUnexpectedPopupShown(); - usernameField.focus(); - yield noPopupPromise; - - removeFocus(); - usernameField.value = "testuser"; - info("Focus when we don't have an exact match"); - shownPromise = promiseACShown(); - usernameField.focus(); - yield shownPromise; -}); - -add_task(function* test_autofilled_focused_dynamic() { - let usernameField = $_("-autofilled-focused-dynamic", "uname"); - let passwordField = $_("-autofilled-focused-dynamic", "pword"); - info("Username and password will be filled while username focused"); - let noPopupPromise = promiseNoUnexpectedPopupShown(); - usernameField.focus(); - yield noPopupPromise; - info("triggering autofill"); - noPopupPromise = promiseNoUnexpectedPopupShown(); - passwordField.type = "password"; - yield noPopupPromise; - - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is closed"); - - removeFocus(); - passwordField.value = "test"; - info("Focus when we don't have an exact match"); - shownPromise = promiseACShown(); - usernameField.focus(); - yield shownPromise; -}); - -// Begin testing forms that have multiple saved logins - -add_task(function* test_multiple() { - let usernameField = $_("-multiple", "uname"); - info("Fields not filled due to multiple so autocomplete upon focus"); - shownPromise = promiseACShown(); - usernameField.focus(); - yield shownPromise; -}); - -add_task(function* test_multiple_dynamic() { - let usernameField = $_("-multiple-dynamic", "uname"); - let passwordField = $_("-multiple-dynamic", "pword"); - info("Fields not filled but username is focused upon marking so open"); - let noPopupPromise = promiseNoUnexpectedPopupShown(); - usernameField.focus(); - yield noPopupPromise; - - info("triggering _fillForm code"); - let shownPromise = promiseACShown(); - passwordField.type = "password"; - yield shownPromise; -}); - -add_task(function* test_multiple_prefilled_un1() { - let usernameField = $_("-multiple-prefilled-un1", "uname"); - info("Username and password already filled so don't show autocomplete"); - let noPopupPromise = promiseNoUnexpectedPopupShown(); - usernameField.focus(); - yield noPopupPromise; - - removeFocus(); - usernameField.value = "testuser"; - info("Focus when we don't have an exact match"); - shownPromise = promiseACShown(); - usernameField.focus(); - yield shownPromise; -}); - -add_task(function* test_multiple_prefilled_un2() { - let usernameField = $_("-multiple-prefilled-un2", "uname"); - info("Username and password already filled so don't show autocomplete"); - let noPopupPromise = promiseNoUnexpectedPopupShown(); - usernameField.focus(); - yield noPopupPromise; - - removeFocus(); - usernameField.value = "testuser"; - info("Focus when we don't have an exact match"); - shownPromise = promiseACShown(); - usernameField.focus(); - yield shownPromise; -}); - -add_task(function* test_multiple_prefilled_focused_dynamic() { - let usernameField = $_("-multiple-prefilled-focused-dynamic", "uname"); - let passwordField = $_("-multiple-prefilled-focused-dynamic", "pword"); - info("Username and password will be filled while username focused"); - let noPopupPromise = promiseNoUnexpectedPopupShown(); - usernameField.focus(); - yield noPopupPromise; - info("triggering autofill"); - noPopupPromise = promiseNoUnexpectedPopupShown(); - passwordField.type = "password"; - yield noPopupPromise; - - let popupState = yield getPopupState(); - is(popupState.open, false, "Check popup is closed"); - - removeFocus(); - passwordField.value = "test"; - info("Focus when we don't have an exact match"); - shownPromise = promiseACShown(); - usernameField.focus(); - yield shownPromise; -}); - -add_task(function* cleanup() { - removeFocus(); -}); -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/mochitest/test_xhr_2.html b/toolkit/components/passwordmgr/test/mochitest/test_xhr_2.html deleted file mode 100644 index fa8357792..000000000 --- a/toolkit/components/passwordmgr/test/mochitest/test_xhr_2.html +++ /dev/null @@ -1,55 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=654348 ---> -<head> - <meta charset="utf-8"> - <title>Test XHR auth with user and pass arguments</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body onload="startTest()"> -<script class="testbody" type="text/javascript"> - -/** - * This test checks we correctly ignore authentication entry - * for a subpath and use creds from the URL when provided when XHR - * is used with filled user name and password. - * - * 1. connect authenticate.sjs that excepts user1:pass1 password - * 2. connect authenticate.sjs that this time expects differentuser2:pass2 password - * we must use the creds that are provided to the xhr witch are different and expected - */ - -function doxhr(URL, user, pass, code, next) { - var xhr = new XMLHttpRequest(); - if (user && pass) - xhr.open("POST", URL, true, user, pass); - else - xhr.open("POST", URL, true); - xhr.onload = function() { - is(xhr.status, code, "expected response code " + code); - next(); - }; - xhr.onerror = function() { - ok(false, "request passed"); - finishTest(); - }; - xhr.send(); -} - -function startTest() { - doxhr("authenticate.sjs?user=dummy&pass=pass1&realm=realm1&formauth=1", "dummy", "dummy", 403, function() { - doxhr("authenticate.sjs?user=dummy&pass=pass1&realm=realm1&formauth=1", "dummy", "pass1", 200, finishTest); - }); -} - -function finishTest() { - SimpleTest.finish(); -} - -</script> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/prompt_common.js b/toolkit/components/passwordmgr/test/prompt_common.js deleted file mode 100644 index 267e697ae..000000000 --- a/toolkit/components/passwordmgr/test/prompt_common.js +++ /dev/null @@ -1,79 +0,0 @@ -/** - * NOTE: - * This file is currently only being used for tests which haven't been - * fixed to work with e10s. Favor using the `prompt_common.js` file that - * is in `toolkit/components/prompts/test/` instead. - */ - -var Ci = SpecialPowers.Ci; -ok(Ci != null, "Access Ci"); -var Cc = SpecialPowers.Cc; -ok(Cc != null, "Access Cc"); - -var didDialog; - -var timer; // keep in outer scope so it's not GC'd before firing -function startCallbackTimer() { - didDialog = false; - - // 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); -} - - -var observer = SpecialPowers.wrapCallbackObject({ - QueryInterface : function (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; - }, - - observe : function (subject, topic, data) { - var doc = getDialogDoc(); - if (doc) - handleDialog(doc, testNum); - else - startCallbackTimer(); // try again in a bit - } -}); - -function getDialogDoc() { - // Find the <browser> which contains notifyWindow, by looking - // through all the open windows and all the <browsers> in each. - var wm = Cc["@mozilla.org/appshell/window-mediator;1"]. - getService(Ci.nsIWindowMediator); - // var enumerator = wm.getEnumerator("navigator:browser"); - var enumerator = wm.getXULWindowEnumerator(null); - - while (enumerator.hasMoreElements()) { - var win = enumerator.getNext(); - var windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell; - - var containedDocShells = windowDocShell.getDocShellEnumerator( - Ci.nsIDocShellTreeItem.typeChrome, - Ci.nsIDocShell.ENUMERATE_FORWARDS); - while (containedDocShells.hasMoreElements()) { - // Get the corresponding document for this docshell - var childDocShell = containedDocShells.getNext(); - // We don't want it if it's not done loading. - if (childDocShell.busyFlags != Ci.nsIDocShell.BUSY_FLAGS_NONE) - continue; - var childDoc = childDocShell.QueryInterface(Ci.nsIDocShell) - .contentViewer - .DOMDocument; - - // ok(true, "Got window: " + childDoc.location.href); - if (childDoc.location.href == "chrome://global/content/commonDialog.xul") - return childDoc; - } - } - - return null; -} diff --git a/toolkit/components/passwordmgr/test/pwmgr_common.js b/toolkit/components/passwordmgr/test/pwmgr_common.js deleted file mode 100644 index fa7c4fd85..000000000 --- a/toolkit/components/passwordmgr/test/pwmgr_common.js +++ /dev/null @@ -1,509 +0,0 @@ -const TESTS_DIR = "/tests/toolkit/components/passwordmgr/test/"; - -/** - * Returns the element with the specified |name| attribute. - */ -function $_(formNum, name) { - var form = document.getElementById("form" + formNum); - if (!form) { - logWarning("$_ couldn't find requested form " + formNum); - return null; - } - - var element = form.children.namedItem(name); - if (!element) { - logWarning("$_ couldn't find requested element " + name); - return null; - } - - // Note that namedItem is a bit stupid, and will prefer an - // |id| attribute over a |name| attribute when looking for - // the element. Login Mananger happens to use .namedItem - // anyway, but let's rigorously check it here anyway so - // that we don't end up with tests that mistakenly pass. - - if (element.getAttribute("name") != name) { - logWarning("$_ got confused."); - return null; - } - - return element; -} - -/** - * Check a form for expected values. If an argument is null, a field's - * expected value will be the default value. - * - * <form id="form#"> - * checkForm(#, "foo"); - */ -function checkForm(formNum, val1, val2, val3) { - var e, form = document.getElementById("form" + formNum); - ok(form, "Locating form " + formNum); - - var numToCheck = arguments.length - 1; - - if (!numToCheck--) - return; - e = form.elements[0]; - if (val1 == null) - is(e.value, e.defaultValue, "Test default value of field " + e.name + - " in form " + formNum); - else - is(e.value, val1, "Test value of field " + e.name + - " in form " + formNum); - - - if (!numToCheck--) - return; - e = form.elements[1]; - if (val2 == null) - is(e.value, e.defaultValue, "Test default value of field " + e.name + - " in form " + formNum); - else - is(e.value, val2, "Test value of field " + e.name + - " in form " + formNum); - - - if (!numToCheck--) - return; - e = form.elements[2]; - if (val3 == null) - is(e.value, e.defaultValue, "Test default value of field " + e.name + - " in form " + formNum); - else - is(e.value, val3, "Test value of field " + e.name + - " in form " + formNum); -} - -/** - * Check a form for unmodified values from when page was loaded. - * - * <form id="form#"> - * checkUnmodifiedForm(#); - */ -function checkUnmodifiedForm(formNum) { - var form = document.getElementById("form" + formNum); - ok(form, "Locating form " + formNum); - - for (var i = 0; i < form.elements.length; i++) { - var ele = form.elements[i]; - - // No point in checking form submit/reset buttons. - if (ele.type == "submit" || ele.type == "reset") - continue; - - is(ele.value, ele.defaultValue, "Test to default value of field " + - ele.name + " in form " + formNum); - } -} - -/** - * Mochitest gives us a sendKey(), but it's targeted to a specific element. - * This basically sends an untargeted key event, to whatever's focused. - */ -function doKey(aKey, modifier) { - var keyName = "DOM_VK_" + aKey.toUpperCase(); - var key = KeyEvent[keyName]; - - // undefined --> null - if (!modifier) - modifier = null; - - // Window utils for sending fake sey events. - var wutils = SpecialPowers.wrap(window). - QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor). - getInterface(SpecialPowers.Ci.nsIDOMWindowUtils); - - if (wutils.sendKeyEvent("keydown", key, 0, modifier)) { - wutils.sendKeyEvent("keypress", key, 0, modifier); - } - wutils.sendKeyEvent("keyup", key, 0, modifier); -} - -/** - * Init with a common login - * If selfFilling is true or non-undefined, fires an event at the page so that - * the test can start checking filled-in values. Tests that check observer - * notifications might be confused by this. - */ -function commonInit(selfFilling) { - var pwmgr = SpecialPowers.Cc["@mozilla.org/login-manager;1"]. - getService(SpecialPowers.Ci.nsILoginManager); - ok(pwmgr != null, "Access LoginManager"); - - // Check that initial state has no logins - var logins = pwmgr.getAllLogins(); - is(logins.length, 0, "Not expecting logins to be present"); - var disabledHosts = pwmgr.getAllDisabledHosts(); - if (disabledHosts.length) { - ok(false, "Warning: wasn't expecting disabled hosts to be present."); - for (var host of disabledHosts) - pwmgr.setLoginSavingEnabled(host, true); - } - - // Add a login that's used in multiple tests - var login = SpecialPowers.Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(SpecialPowers.Ci.nsILoginInfo); - login.init("http://mochi.test:8888", "http://mochi.test:8888", null, - "testuser", "testpass", "uname", "pword"); - pwmgr.addLogin(login); - - // Last sanity check - logins = pwmgr.getAllLogins(); - is(logins.length, 1, "Checking for successful init login"); - disabledHosts = pwmgr.getAllDisabledHosts(); - is(disabledHosts.length, 0, "Checking for no disabled hosts"); - - if (selfFilling) - return; - - if (this.sendAsyncMessage) { - sendAsyncMessage("registerRunTests"); - } else { - registerRunTests(); - } -} - -function registerRunTests() { - return new Promise(resolve => { - // We provide a general mechanism for our tests to know when they can - // safely run: we add a final form that we know will be filled in, wait - // for the login manager to tell us that it's filled in and then continue - // with the rest of the tests. - window.addEventListener("DOMContentLoaded", (event) => { - var form = document.createElement('form'); - form.id = 'observerforcer'; - var username = document.createElement('input'); - username.name = 'testuser'; - form.appendChild(username); - var password = document.createElement('input'); - password.name = 'testpass'; - password.type = 'password'; - form.appendChild(password); - - var observer = SpecialPowers.wrapCallback(function(subject, topic, data) { - var formLikeRoot = subject.QueryInterface(SpecialPowers.Ci.nsIDOMNode); - if (formLikeRoot.id !== 'observerforcer') - return; - SpecialPowers.removeObserver(observer, "passwordmgr-processed-form"); - formLikeRoot.remove(); - SimpleTest.executeSoon(() => { - var runTestEvent = new Event("runTests"); - window.dispatchEvent(runTestEvent); - resolve(); - }); - }); - SpecialPowers.addObserver(observer, "passwordmgr-processed-form", false); - - document.body.appendChild(form); - }); - }); -} - -const masterPassword = "omgsecret!"; - -function enableMasterPassword() { - setMasterPassword(true); -} - -function disableMasterPassword() { - setMasterPassword(false); -} - -function setMasterPassword(enable) { - var oldPW, newPW; - if (enable) { - oldPW = ""; - newPW = masterPassword; - } else { - oldPW = masterPassword; - newPW = ""; - } - // Set master password. Note that this does not log you in, so the next - // invocation of pwmgr can trigger a MP prompt. - - var pk11db = Cc["@mozilla.org/security/pk11tokendb;1"].getService(Ci.nsIPK11TokenDB); - var token = pk11db.findTokenByName(""); - info("MP change from " + oldPW + " to " + newPW); - token.changePassword(oldPW, newPW); -} - -function logoutMasterPassword() { - var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing); - sdr.logoutAndTeardown(); -} - -function dumpLogins(pwmgr) { - var logins = pwmgr.getAllLogins(); - ok(true, "----- dumpLogins: have " + logins.length + " logins. -----"); - for (var i = 0; i < logins.length; i++) - dumpLogin("login #" + i + " --- ", logins[i]); -} - -function dumpLogin(label, login) { - var loginText = ""; - loginText += "host: "; - loginText += login.hostname; - loginText += " / formURL: "; - loginText += login.formSubmitURL; - loginText += " / realm: "; - loginText += login.httpRealm; - loginText += " / user: "; - loginText += login.username; - loginText += " / pass: "; - loginText += login.password; - loginText += " / ufield: "; - loginText += login.usernameField; - loginText += " / pfield: "; - loginText += login.passwordField; - ok(true, label + loginText); -} - -function getRecipeParent() { - var { LoginManagerParent } = SpecialPowers.Cu.import("resource://gre/modules/LoginManagerParent.jsm", {}); - if (!LoginManagerParent.recipeParentPromise) { - return null; - } - return LoginManagerParent.recipeParentPromise.then((recipeParent) => { - return SpecialPowers.wrap(recipeParent); - }); -} - -/** - * Resolves when a specified number of forms have been processed. - */ -function promiseFormsProcessed(expectedCount = 1) { - var processedCount = 0; - return new Promise((resolve, reject) => { - function onProcessedForm(subject, topic, data) { - processedCount++; - if (processedCount == expectedCount) { - SpecialPowers.removeObserver(onProcessedForm, "passwordmgr-processed-form"); - resolve(SpecialPowers.Cu.waiveXrays(subject), data); - } - } - SpecialPowers.addObserver(onProcessedForm, "passwordmgr-processed-form", false); - }); -} - -function loadRecipes(recipes) { - info("Loading recipes"); - return new Promise(resolve => { - chromeScript.addMessageListener("loadedRecipes", function loaded() { - chromeScript.removeMessageListener("loadedRecipes", loaded); - resolve(recipes); - }); - chromeScript.sendAsyncMessage("loadRecipes", recipes); - }); -} - -function resetRecipes() { - info("Resetting recipes"); - return new Promise(resolve => { - chromeScript.addMessageListener("recipesReset", function reset() { - chromeScript.removeMessageListener("recipesReset", reset); - resolve(); - }); - chromeScript.sendAsyncMessage("resetRecipes"); - }); -} - -function promiseStorageChanged(expectedChangeTypes) { - return new Promise((resolve, reject) => { - function onStorageChanged({ topic, data }) { - let changeType = expectedChangeTypes.shift(); - is(data, changeType, "Check expected passwordmgr-storage-changed type"); - if (expectedChangeTypes.length === 0) { - chromeScript.removeMessageListener("storageChanged", onStorageChanged); - resolve(); - } - } - chromeScript.addMessageListener("storageChanged", onStorageChanged); - }); -} - -function promisePromptShown(expectedTopic) { - return new Promise((resolve, reject) => { - function onPromptShown({ topic, data }) { - is(topic, expectedTopic, "Check expected prompt topic"); - chromeScript.removeMessageListener("promptShown", onPromptShown); - resolve(); - } - chromeScript.addMessageListener("promptShown", onPromptShown); - }); -} - -/** - * Run a function synchronously in the parent process and destroy it in the test cleanup function. - * @param {Function|String} aFunctionOrURL - either a function that will be stringified and run - * or the URL to a JS file. - * @return {Object} - the return value of loadChromeScript providing message-related methods. - * @see loadChromeScript in specialpowersAPI.js - */ -function runInParent(aFunctionOrURL) { - let chromeScript = SpecialPowers.loadChromeScript(aFunctionOrURL); - SimpleTest.registerCleanupFunction(() => { - chromeScript.destroy(); - }); - return chromeScript; -} - -/** - * Run commonInit synchronously in the parent then run the test function after the runTests event. - * - * @param {Function} aFunction The test function to run - */ -function runChecksAfterCommonInit(aFunction = null) { - SimpleTest.waitForExplicitFinish(); - let pwmgrCommonScript = runInParent(SimpleTest.getTestFileURL("pwmgr_common.js")); - if (aFunction) { - window.addEventListener("runTests", aFunction); - pwmgrCommonScript.addMessageListener("registerRunTests", () => registerRunTests()); - } - pwmgrCommonScript.sendSyncMessage("setupParent"); - return pwmgrCommonScript; -} - -// Code to run when loaded as a chrome script in tests via loadChromeScript -if (this.addMessageListener) { - const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; - var SpecialPowers = { Cc, Ci, Cr, Cu, }; - var ok, is; - // Ignore ok/is in commonInit since they aren't defined in a chrome script. - ok = is = () => {}; // eslint-disable-line no-native-reassign - - Cu.import("resource://gre/modules/LoginHelper.jsm"); - Cu.import("resource://gre/modules/LoginManagerParent.jsm"); - Cu.import("resource://gre/modules/Services.jsm"); - Cu.import("resource://gre/modules/Task.jsm"); - - function onStorageChanged(subject, topic, data) { - sendAsyncMessage("storageChanged", { - topic, - data, - }); - } - Services.obs.addObserver(onStorageChanged, "passwordmgr-storage-changed", false); - - function onPrompt(subject, topic, data) { - sendAsyncMessage("promptShown", { - topic, - data, - }); - } - Services.obs.addObserver(onPrompt, "passwordmgr-prompt-change", false); - Services.obs.addObserver(onPrompt, "passwordmgr-prompt-save", false); - - addMessageListener("setupParent", ({selfFilling = false} = {selfFilling: false}) => { - // Force LoginManagerParent to init for the tests since it's normally delayed - // by apps such as on Android. - LoginManagerParent.init(); - - commonInit(selfFilling); - sendAsyncMessage("doneSetup"); - }); - - addMessageListener("loadRecipes", Task.async(function*(recipes) { - var recipeParent = yield LoginManagerParent.recipeParentPromise; - yield recipeParent.load(recipes); - sendAsyncMessage("loadedRecipes", recipes); - })); - - addMessageListener("resetRecipes", Task.async(function*() { - let recipeParent = yield LoginManagerParent.recipeParentPromise; - yield recipeParent.reset(); - sendAsyncMessage("recipesReset"); - })); - - addMessageListener("proxyLoginManager", msg => { - // Recreate nsILoginInfo objects from vanilla JS objects. - let recreatedArgs = msg.args.map((arg, index) => { - if (msg.loginInfoIndices.includes(index)) { - return LoginHelper.vanillaObjectToLogin(arg); - } - - return arg; - }); - - let rv = Services.logins[msg.methodName](...recreatedArgs); - if (rv instanceof Ci.nsILoginInfo) { - rv = LoginHelper.loginToVanillaObject(rv); - } - return rv; - }); - - var globalMM = Cc["@mozilla.org/globalmessagemanager;1"].getService(Ci.nsIMessageListenerManager); - globalMM.addMessageListener("RemoteLogins:onFormSubmit", function onFormSubmit(message) { - sendAsyncMessage("formSubmissionProcessed", message.data, message.objects); - }); -} else { - // Code to only run in the mochitest pages (not in the chrome script). - SpecialPowers.pushPrefEnv({"set": [["signon.autofillForms.http", true], - ["security.insecure_field_warning.contextual.enabled", false]] - }); - - SimpleTest.registerCleanupFunction(() => { - SpecialPowers.popPrefEnv(); - runInParent(function cleanupParent() { - const { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components; - Cu.import("resource://gre/modules/Services.jsm"); - Cu.import("resource://gre/modules/LoginManagerParent.jsm"); - - // Remove all logins and disabled hosts - Services.logins.removeAllLogins(); - - let disabledHosts = Services.logins.getAllDisabledHosts(); - disabledHosts.forEach(host => Services.logins.setLoginSavingEnabled(host, true)); - - let authMgr = Cc["@mozilla.org/network/http-auth-manager;1"]. - getService(Ci.nsIHttpAuthManager); - authMgr.clearAll(); - - if (LoginManagerParent._recipeManager) { - LoginManagerParent._recipeManager.reset(); - } - - // Cleanup PopupNotifications (if on a relevant platform) - let chromeWin = Services.wm.getMostRecentWindow("navigator:browser"); - if (chromeWin && chromeWin.PopupNotifications) { - let notes = chromeWin.PopupNotifications._currentNotifications; - if (notes.length > 0) { - dump("Removing " + notes.length + " popup notifications.\n"); - } - for (let note of notes) { - note.remove(); - } - } - }); - }); - - - let { LoginHelper } = SpecialPowers.Cu.import("resource://gre/modules/LoginHelper.jsm", {}); - /** - * Proxy for Services.logins (nsILoginManager). - * Only supports arguments which support structured clone plus {nsILoginInfo} - * Assumes properties are methods. - */ - this.LoginManager = new Proxy({}, { - get(target, prop, receiver) { - return (...args) => { - let loginInfoIndices = []; - let cloneableArgs = args.map((val, index) => { - if (SpecialPowers.call_Instanceof(val, SpecialPowers.Ci.nsILoginInfo)) { - loginInfoIndices.push(index); - return LoginHelper.loginToVanillaObject(val); - } - - return val; - }); - - return chromeScript.sendSyncMessage("proxyLoginManager", { - args: cloneableArgs, - loginInfoIndices, - methodName: prop, - })[0][0]; - }; - }, - }); -} diff --git a/toolkit/components/passwordmgr/test/subtst_master_pass.html b/toolkit/components/passwordmgr/test/subtst_master_pass.html deleted file mode 100644 index 20211866a..000000000 --- a/toolkit/components/passwordmgr/test/subtst_master_pass.html +++ /dev/null @@ -1,12 +0,0 @@ -<h2>MP subtest</h2> -This form triggers a MP and gets filled in.<br> -<form> -Username: <input type="text" id="userfield" name="u"><br> -Password: <input type="password" id="passfield" name="p"><br> -<script> - // Only notify when we fill in the password field. - document.getElementById("passfield").addEventListener("input", function() { - parent.postMessage("filled", "*"); - }); -</script> -</form> diff --git a/toolkit/components/passwordmgr/test/subtst_prompt_async.html b/toolkit/components/passwordmgr/test/subtst_prompt_async.html deleted file mode 100644 index f60f63814..000000000 --- a/toolkit/components/passwordmgr/test/subtst_prompt_async.html +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Multiple auth request</title> -</head> -<body> - <iframe id="iframe1" src="http://example.com/tests/toolkit/components/passwordmgr/test/authenticate.sjs?r=1&user=user3name&pass=user3pass&realm=mochirealm3&proxy_user=proxy_user2&proxy_pass=proxy_pass2&proxy_realm=proxy_realm2"></iframe> - <iframe id="iframe2" src="http://example.com/tests/toolkit/components/passwordmgr/test/authenticate.sjs?r=2&user=user3name&pass=user3pass&realm=mochirealm3&proxy_user=proxy_user2&proxy_pass=proxy_pass2&proxy_realm=proxy_realm2"></iframe> - <iframe id="iframe3" src="http://example.com/tests/toolkit/components/passwordmgr/test/authenticate.sjs?r=3&user=user3name&pass=user3pass&realm=mochirealm3&proxy_user=proxy_user2&proxy_pass=proxy_pass2&proxy_realm=proxy_realm2"></iframe> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/test_master_password.html b/toolkit/components/passwordmgr/test/test_master_password.html deleted file mode 100644 index c8884811f..000000000 --- a/toolkit/components/passwordmgr/test/test_master_password.html +++ /dev/null @@ -1,308 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test for master password</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <script type="text/javascript" src="prompt_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: master password. -<script> -"use strict"; - -commonInit(); -SimpleTest.waitForExplicitFinish(); -SimpleTest.requestFlakyTimeout("untriaged"); - -var pwmgr = SpecialPowers.Cc["@mozilla.org/login-manager;1"] - .getService(SpecialPowers.Ci.nsILoginManager); -var pwcrypt = SpecialPowers.Cc["@mozilla.org/login-manager/crypto/SDR;1"] - .getService(Ci.nsILoginManagerCrypto); - -var nsLoginInfo = new SpecialPowers.wrap(SpecialPowers.Components).Constructor("@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo); - -var exampleCom = "http://example.com/tests/toolkit/components/passwordmgr/test/"; -var exampleOrg = "http://example.org/tests/toolkit/components/passwordmgr/test/"; - -var login1 = new nsLoginInfo(); -var login2 = new nsLoginInfo(); - -login1.init("http://example.com", "http://example.com", null, - "user1", "pass1", "uname", "pword"); -login2.init("http://example.org", "http://example.org", null, - "user2", "pass2", "uname", "pword"); - -pwmgr.addLogin(login1); -pwmgr.addLogin(login2); -</script> - -<p id="display"></p> - -<div id="content" style="display: none"> -<iframe id="iframe1"></iframe> -<iframe id="iframe2"></iframe> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> -var testNum = 1; -var iframe1 = document.getElementById("iframe1"); -var iframe2 = document.getElementById("iframe2"); - -// A couple of tests have to wait until the password manager gets around to -// filling in the password in the subtest (after we dismiss the master -// password dialog). In order to accomplish this, the test waits for an event -// 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(); - } -}); - -/* - * handleDialog - * - * Invoked a short period of time after calling startCallbackTimer(), and - * allows testing the actual auth dialog while it's being displayed. Tests - * should call startCallbackTimer() each time the auth dialog is expected (the - * timer is a one-shot). - */ -function handleDialog(doc, testNumber) { - ok(true, "handleDialog running for test " + testNumber); - - var clickOK = true; - var doNothing = false; - 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; - - case 2: - clickOK = false; - break; - - case 3: - is(passfield.getAttribute("value"), "", "Checking empty prompt"); - passfield.setAttribute("value", masterPassword); - break; - - case 4: - doNothing = true; - 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; - } - - didDialog = true; - - if (!doNothing) { - SpecialPowers.addObserver(outerWindowObserver, "outer-window-destroyed", false); - if (clickOK) - dialog.acceptDialog(); - else - dialog.cancelDialog(); - } - - ok(true, "handleDialog done for test " + testNumber); - - if (testNumber == 4) - checkTest4A(); -} - -var outerWindowObserver = { - observe: function(id) { - SpecialPowers.removeObserver(outerWindowObserver, "outer-window-destroyed"); - var func; - if (testNum == 1) - func = startTest2; - else if (testNum == 2) - func = startTest3; - - // For tests 3 and 4C, we use the 'continuation' mechanism, described - // above. - if (func) - 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"); - - // --- 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"); -} - -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"); -} - -function startTest3() { - // 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"); - - // 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"); - - - // --- 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"); - - // 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"); - - // 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"; -} - -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); -} - -function checkTest4B() { - 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"); - - // XXX check that there's 1 MP window open - ok(!pwcrypt.isLoggedIn, "should be logged out"); - - continuation = checkTest4C; - - // 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"); - - // 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 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(); -} - -// XXX do a test5ABC with clicking cancel? - -SimpleTest.registerCleanupFunction(function finishTest() { - disableMasterPassword(); - - pwmgr.removeLogin(login1); - pwmgr.removeLogin(login2); -}); - -window.addEventListener("runTests", startTest1); -</script> -</pre> -</body> -</html> - diff --git a/toolkit/components/passwordmgr/test/test_prompt_async.html b/toolkit/components/passwordmgr/test/test_prompt_async.html deleted file mode 100644 index 38b34679a..000000000 --- a/toolkit/components/passwordmgr/test/test_prompt_async.html +++ /dev/null @@ -1,540 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test for Async Auth Prompt</title> - <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="prompt_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> - - <script class="testbody" type="text/javascript"> - SimpleTest.waitForExplicitFinish(); - SimpleTest.requestFlakyTimeout("untriaged"); - - const { NetUtil } = SpecialPowers.Cu.import('resource://gre/modules/NetUtil.jsm'); - - var prefs = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefBranch); - prefs.setIntPref("network.auth.subresource-http-auth-allow", 2); - // Class monitoring number of open dialog windows - // It checks there is always open just a single dialog per application - function dialogMonitor() { - var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService); - observerService.addObserver(this, "domwindowopened", false); - observerService.addObserver(this, "domwindowclosed", false); - } - - /* - * As documented in Bug 718543, checking equality of objects pulled - * from SpecialPowers-wrapped objects is unreliable. Because of that, - * `dialogMonitor` now tracks the number of open windows rather than - * specific window objects. - * - * NB: Because the constructor (above) adds |this| directly as an observer, - * we need to do SpecialPowers.wrapCallbackObject directly on the prototype. - */ - dialogMonitor.prototype = SpecialPowers.wrapCallbackObject({ - windowsOpen : 0, - windowsRegistered : 0, - - QueryInterface : function (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; - }, - - observe: function(subject, topic, data) { - if (topic === "domwindowopened") { - this.windowsOpen++; - this.windowsRegistered++; - return; - } - if (topic === "domwindowclosed") { - this.windowsOpen--; - return; - } - }, - - shutdown: function() { - var observerService = SpecialPowers.Cc["@mozilla.org/observer-service;1"] - .getService(Ci.nsIObserverService); - observerService.removeObserver(this, "domwindowopened"); - observerService.removeObserver(this, "domwindowclosed"); - }, - - reset: function() { - this.windowsOpen = 0; - this.windowsRegistered = 0; - } - }); - - var monitor = new dialogMonitor(); - - var pwmgr, logins = []; - - function initLogins(pi) { - pwmgr = SpecialPowers.Cc["@mozilla.org/login-manager;1"] - .getService(Ci.nsILoginManager); - - 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; - - 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]); - - var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1'] - .getService(Ci.nsIHttpAuthManager); - authMgr.clearAll(); - - monitor.shutdown(); - SimpleTest.finish(); - } - - var resolveCallback = SpecialPowers.wrapCallbackObject({ - QueryInterface : function (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; - }, - - onProxyAvailable : function (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 - }); - - var pps = SpecialPowers.Cc["@mozilla.org/network/protocol-proxy-service;1"] - .getService(); - - pps.asyncResolve(channel, 0, resolveCallback); - } - - // --------------- Test loop spin ---------------- - var testNum = 1; - var iframe1; - 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; - - 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"); - - doCheck(testNum); - monitor.reset(); - - 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/"; - - 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; - - 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; - - 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; - - 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"; - - - 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; - - 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; - - 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; - - 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; - - case 9: - finishTest(); - return; - } - - startCallbackTimer(); - } - - function handleDialog(doc, testNumber) - { - var dialog = doc.getElementById("commonDialog"); - - 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 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 6: - if (expectedDialogs == 2) - dialog.acceptDialog(); - else - dialog.cancelDialog(); - break; - - case 7: - dialog.acceptDialog(); - break; - - case 8: - if (expectedDialogs == 3 || expectedDialogs == 1) - dialog.acceptDialog(); - else - dialog.cancelDialog(); - break; - - default: - ok(false, "Unhandled testNum " + testNumber + " in handleDialog"); - } - - 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"); - - authok1 = iframe1Doc.getElementById("ok").textContent; - proxyok1 = iframe1Doc.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; - - 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"); - - function checkIframe(frame) { - var doc = SpecialPowers.wrap(frame).contentDocument; - - 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); - } - - 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"); - - // 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; - - 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"); - - // 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; - - 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; - - 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; - - 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"); - } - } - - </script> -</head> -<body> - <iframe id="iframe1"></iframe> - <iframe id="iframe2a"></iframe> - <iframe id="iframe2b"></iframe> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/test_xhr.html b/toolkit/components/passwordmgr/test/test_xhr.html deleted file mode 100644 index 296371685..000000000 --- a/toolkit/components/passwordmgr/test/test_xhr.html +++ /dev/null @@ -1,201 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test for XHR prompts</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <script type="text/javascript" src="prompt_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: XHR prompt -<p id="display"></p> - -<div id="content" style="display: none"> - <iframe id="iframe"></iframe> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: XHR prompts. **/ -var pwmgr, login1, login2; - -function initLogins() { - pwmgr = Cc["@mozilla.org/login-manager;1"]. - getService(Ci.nsILoginManager); - - login1 = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - login2 = Cc["@mozilla.org/login-manager/loginInfo;1"]. - createInstance(Ci.nsILoginInfo); - - login1.init("http://mochi.test:8888", null, "xhr", - "xhruser1", "xhrpass1", "", ""); - login2.init("http://mochi.test:8888", null, "xhr2", - "xhruser2", "xhrpass2", "", ""); - - pwmgr.addLogin(login1); - pwmgr.addLogin(login2); -} - -function finishTest() { - ok(true, "finishTest removing testing logins..."); - pwmgr.removeLogin(login1); - pwmgr.removeLogin(login2); - - SimpleTest.finish(); -} - -function handleDialog(doc, testNum) { - ok(true, "handleDialog running for test " + testNum); - - var clickOK = true; - var userfield = doc.getElementById("loginTextbox"); - var passfield = doc.getElementById("password1Textbox"); - var username = userfield.getAttribute("value"); - var password = passfield.getAttribute("value"); - var dialog = doc.getElementById("commonDialog"); - - switch (testNum) { - case 1: - 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"); - - // 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.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation). - QueryInterface(Ci.nsIDocShellTreeItem).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 + ")"); - - - break; - - default: - 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; - } - - if (clickOK) - dialog.acceptDialog(); - else - dialog.cancelDialog(); - - ok(true, "handleDialog done"); - didDialog = true; -} - -var newWin; -function xhrLoad(xmlDoc) { - ok(true, "xhrLoad running for test " + testNum); - - // The server echos back the user/pass it received. - var username = xmlDoc.getElementById("user").textContent; - var password = xmlDoc.getElementById("pass").textContent; - var authok = xmlDoc.getElementById("ok").textContent; - - - switch (testNum) { - case 1: - 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"); - - newWin.close(); - break; - - default: - ok(false, "Uhh, unhandled switch for testNum #" + testNum); - break; - } - - doTest(); -} - -function doTest() { - switch (++testNum) { - case 1: - 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; - - default: - finishTest(); - } -} - -function makeRequest(uri) { - var request = new XMLHttpRequest(); - request.open("GET", uri, true); - request.onreadystatechange = function () { - if (request.readyState == 4) - xhrLoad(request.responseXML); - }; - request.send(null); -} - - -initLogins(); - -// clear plain HTTP auth sessions before the test, to allow -// running them more than once. -var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1'] - .getService(SpecialPowers.Ci.nsIHttpAuthManager); -authMgr.clearAll(); - -// start the tests -testNum = 0; -doTest(); - -SimpleTest.waitForExplicitFinish(); -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/test_xml_load.html b/toolkit/components/passwordmgr/test/test_xml_load.html deleted file mode 100644 index 5672c7117..000000000 --- a/toolkit/components/passwordmgr/test/test_xml_load.html +++ /dev/null @@ -1,191 +0,0 @@ -<!DOCTYPE HTML> -<html> -<head> - <meta charset="utf-8"> - <title>Test XML document prompts</title> - <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <script type="text/javascript" src="pwmgr_common.js"></script> - <script type="text/javascript" src="prompt_common.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> -</head> -<body> -Login Manager test: XML prompt -<p id="display"></p> - -<div id="content" style="display: none"> - <iframe id="iframe"></iframe> -</div> - -<pre id="test"> -<script class="testbody" type="text/javascript"> - -/** Test for Login Manager: XML prompts. **/ -var pwmgr, login1, login2; - -function initLogins() { - pwmgr = SpecialPowers.Cc["@mozilla.org/login-manager;1"] - .getService(Ci.nsILoginManager); - - login1 = SpecialPowers.Cc["@mozilla.org/login-manager/loginInfo;1"] - .createInstance(Ci.nsILoginInfo); - login2 = SpecialPowers.Cc["@mozilla.org/login-manager/loginInfo;1"] - .createInstance(Ci.nsILoginInfo); - - login1.init("http://mochi.test:8888", null, "xml", - "xmluser1", "xmlpass1", "", ""); - login2.init("http://mochi.test:8888", null, "xml2", - "xmluser2", "xmlpass2", "", ""); - - pwmgr.addLogin(login1); - pwmgr.addLogin(login2); -} - -function handleDialog(doc, testNum) { - ok(true, "handleDialog running for test " + testNum); - - var clickOK = true; - var userfield = doc.getElementById("loginTextbox"); - var passfield = doc.getElementById("password1Textbox"); - var username = userfield.getAttribute("value"); - var password = passfield.getAttribute("value"); - var dialog = doc.getElementById("commonDialog"); - - switch (testNum) { - case 1: - 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"); - - // 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.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation). - QueryInterface(Ci.nsIDocShellTreeItem).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 + ")"); - - break; - - default: - 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; - } - - if (clickOK) - dialog.acceptDialog(); - else - dialog.cancelDialog(); - - ok(true, "handleDialog done"); - didDialog = true; -} - -var newWin; -function xmlLoad(responseDoc) { - ok(true, "xmlLoad running for test " + testNum); - - // The server echos back the user/pass it received. - var username = responseDoc.getElementById("user").textContent; - var password = responseDoc.getElementById("pass").textContent; - var authok = responseDoc.getElementById("ok").textContent; - - switch (testNum) { - case 1: - 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"); - - newWin.close(); - break; - - default: - ok(false, "Uhh, unhandled switch for testNum #" + testNum); - break; - } - - doTest(); -} - -function doTest() { - switch (++testNum) { - case 1: - 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; - - default: - SimpleTest.finish(); - } -} - -function makeRequest(uri) { - var xmlDoc = document.implementation.createDocument("", "test", null); - - function documentLoaded(e) { - xmlLoad(xmlDoc); - } - xmlDoc.addEventListener("load", documentLoaded, false); - xmlDoc.load(uri); -} - - -initLogins(); - -// clear plain HTTP auth sessions before the test, to allow -// running them more than once. -var authMgr = SpecialPowers.Cc['@mozilla.org/network/http-auth-manager;1'] - .getService(SpecialPowers.Ci.nsIHttpAuthManager); -authMgr.clearAll(); - -// start the tests -testNum = 0; -doTest(); - -SimpleTest.waitForExplicitFinish(); -</script> -</pre> -</body> -</html> diff --git a/toolkit/components/passwordmgr/test/unit/.eslintrc.js b/toolkit/components/passwordmgr/test/unit/.eslintrc.js deleted file mode 100644 index d35787cd2..000000000 --- a/toolkit/components/passwordmgr/test/unit/.eslintrc.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; - -module.exports = { - "extends": [ - "../../../../../testing/xpcshell/xpcshell.eslintrc.js" - ] -}; diff --git a/toolkit/components/passwordmgr/test/unit/data/corruptDB.sqlite b/toolkit/components/passwordmgr/test/unit/data/corruptDB.sqlite Binary files differdeleted file mode 100644 index b234246ca..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/corruptDB.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/key3.db b/toolkit/components/passwordmgr/test/unit/data/key3.db Binary files differdeleted file mode 100644 index a83a0a577..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/key3.db +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/signons-v1.sqlite b/toolkit/components/passwordmgr/test/unit/data/signons-v1.sqlite Binary files differdeleted file mode 100644 index fe030b61f..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/signons-v1.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/signons-v1v2.sqlite b/toolkit/components/passwordmgr/test/unit/data/signons-v1v2.sqlite Binary files differdeleted file mode 100644 index 729512a12..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/signons-v1v2.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/signons-v2.sqlite b/toolkit/components/passwordmgr/test/unit/data/signons-v2.sqlite Binary files differdeleted file mode 100644 index a6c72b31e..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/signons-v2.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/signons-v2v3.sqlite b/toolkit/components/passwordmgr/test/unit/data/signons-v2v3.sqlite Binary files differdeleted file mode 100644 index 359df5d31..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/signons-v2v3.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/signons-v3.sqlite b/toolkit/components/passwordmgr/test/unit/data/signons-v3.sqlite Binary files differdeleted file mode 100644 index 918f4142f..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/signons-v3.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/signons-v3v4.sqlite b/toolkit/components/passwordmgr/test/unit/data/signons-v3v4.sqlite Binary files differdeleted file mode 100644 index e06c33aae..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/signons-v3v4.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/signons-v4.sqlite b/toolkit/components/passwordmgr/test/unit/data/signons-v4.sqlite Binary files differdeleted file mode 100644 index 227c09c81..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/signons-v4.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/signons-v4v5.sqlite b/toolkit/components/passwordmgr/test/unit/data/signons-v4v5.sqlite Binary files differdeleted file mode 100644 index 4534cf255..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/signons-v4v5.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/signons-v5v6.sqlite b/toolkit/components/passwordmgr/test/unit/data/signons-v5v6.sqlite Binary files differdeleted file mode 100644 index eb4ee6d01..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/signons-v5v6.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/signons-v999-2.sqlite b/toolkit/components/passwordmgr/test/unit/data/signons-v999-2.sqlite Binary files differdeleted file mode 100644 index e09c4f710..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/signons-v999-2.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/data/signons-v999.sqlite b/toolkit/components/passwordmgr/test/unit/data/signons-v999.sqlite Binary files differdeleted file mode 100644 index 0328a1a02..000000000 --- a/toolkit/components/passwordmgr/test/unit/data/signons-v999.sqlite +++ /dev/null diff --git a/toolkit/components/passwordmgr/test/unit/head.js b/toolkit/components/passwordmgr/test/unit/head.js deleted file mode 100644 index baf958ab4..000000000 --- a/toolkit/components/passwordmgr/test/unit/head.js +++ /dev/null @@ -1,135 +0,0 @@ -/** - * Provides infrastructure for automated login components tests. - */ - -"use strict"; - -// Globals - -let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/LoginRecipes.jsm"); -Cu.import("resource://gre/modules/LoginHelper.jsm"); -Cu.import("resource://testing-common/MockDocument.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "DownloadPaths", - "resource://gre/modules/DownloadPaths.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", - "resource://gre/modules/FileUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "OS", - "resource://gre/modules/osfile.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Promise", - "resource://gre/modules/Promise.jsm"); - -const LoginInfo = - Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - "nsILoginInfo", "init"); - -// Import LoginTestUtils.jsm as LoginTestUtils. -XPCOMUtils.defineLazyModuleGetter(this, "LoginTestUtils", - "resource://testing-common/LoginTestUtils.jsm"); -LoginTestUtils.Assert = Assert; -const TestData = LoginTestUtils.testData; -const newPropertyBag = LoginHelper.newPropertyBag; - -/** - * All the tests are implemented with add_task, this starts them automatically. - */ -function run_test() -{ - do_get_profile(); - run_next_test(); -} - -// Global helpers - -// Some of these functions are already implemented in other parts of the source -// tree, see bug 946708 about sharing more code. - -// While the previous test file should have deleted all the temporary files it -// used, on Windows these might still be pending deletion on the physical file -// system. Thus, start from a new base number every time, to make a collision -// with a file that is still pending deletion highly unlikely. -let gFileCounter = Math.floor(Math.random() * 1000000); - -/** - * Returns a reference to a temporary file, that is guaranteed not to exist, and - * to have never been created before. - * - * @param aLeafName - * Suggested leaf name for the file to be created. - * - * @return nsIFile pointing to a non-existent file in a temporary directory. - * - * @note It is not enough to delete the file if it exists, or to delete the file - * after calling nsIFile.createUnique, because on Windows the delete - * operation in the file system may still be pending, preventing a new - * file with the same name to be created. - */ -function getTempFile(aLeafName) -{ - // Prepend a serial number to the extension in the suggested leaf name. - let [base, ext] = DownloadPaths.splitBaseNameAndExtension(aLeafName); - let leafName = base + "-" + gFileCounter + ext; - gFileCounter++; - - // Get a file reference under the temporary directory for this test file. - let file = FileUtils.getFile("TmpD", [leafName]); - do_check_false(file.exists()); - - do_register_cleanup(function () { - if (file.exists()) { - file.remove(false); - } - }); - - return file; -} - -const RecipeHelpers = { - initNewParent() { - return (new LoginRecipesParent({ defaults: null })).initializationPromise; - }, -}; - -// Initialization functions common to all tests - -add_task(function* test_common_initialize() -{ - // Before initializing the service for the first time, we should copy the key - // file required to decrypt the logins contained in the SQLite databases used - // by migration tests. This file is not required for the other tests. - yield OS.File.copy(do_get_file("data/key3.db").path, - OS.Path.join(OS.Constants.Path.profileDir, "key3.db")); - - // Ensure that the service and the storage module are initialized. - yield Services.logins.initializationPromise; - - // Ensure that every test file starts with an empty database. - LoginTestUtils.clearData(); - - // Clean up after every test. - do_register_cleanup(() => LoginTestUtils.clearData()); -}); - -/** - * Compare two FormLike to see if they represent the same information. Elements - * are compared using their @id attribute. - */ -function formLikeEqual(a, b) { - Assert.strictEqual(Object.keys(a).length, Object.keys(b).length, - "Check the formLikes have the same number of properties"); - - for (let propName of Object.keys(a)) { - if (propName == "elements") { - Assert.strictEqual(a.elements.length, b.elements.length, "Check element count"); - for (let i = 0; i < a.elements.length; i++) { - Assert.strictEqual(a.elements[i].id, b.elements[i].id, "Check element " + i + " id"); - } - continue; - } - Assert.strictEqual(a[propName], b[propName], "Compare formLike " + propName + " property"); - } -} diff --git a/toolkit/components/passwordmgr/test/unit/test_OSCrypto_win.js b/toolkit/components/passwordmgr/test/unit/test_OSCrypto_win.js deleted file mode 100644 index 94d2e50c0..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_OSCrypto_win.js +++ /dev/null @@ -1,75 +0,0 @@ -/** - * Tests the OSCrypto object. - */ - -"use strict"; - -// Globals - -XPCOMUtils.defineLazyModuleGetter(this, "OSCrypto", - "resource://gre/modules/OSCrypto.jsm"); - -var crypto = new OSCrypto(); - -// Tests - -add_task(function test_getIELoginHash() -{ - do_check_eq(crypto.getIELoginHash("https://bugzilla.mozilla.org/page.cgi"), - "4A66FE96607885790F8E67B56EEE52AB539BAFB47D"); - - do_check_eq(crypto.getIELoginHash("https://github.com/login"), - "0112F7DCE67B8579EA01367678AA44AB9868B5A143"); - - do_check_eq(crypto.getIELoginHash("https://login.live.com/login.srf"), - "FBF92E5D804C82717A57856533B779676D92903688"); - - do_check_eq(crypto.getIELoginHash("https://preview.c9.io/riadh/w1/pass.1.html"), - "6935CF27628830605927F86AB53831016FC8973D1A"); - - - do_check_eq(crypto.getIELoginHash("https://reviewboard.mozilla.org/account/login/"), - "09141FD287E2E59A8B1D3BB5671537FD3D6B61337A"); - - do_check_eq(crypto.getIELoginHash("https://www.facebook.com/"), - "EF44D3E034009CB0FD1B1D81A1FF3F3335213BD796"); - -}); - -add_task(function test_decryptData_encryptData() -{ - function decryptEncryptTest(key) { - do_check_eq(crypto.decryptData(crypto.encryptData("", key), key), - ""); - - do_check_eq(crypto.decryptData(crypto.encryptData("secret", key), key), - "secret"); - - do_check_eq(crypto.decryptData(crypto.encryptData("https://www.mozilla.org", key), - key), - "https://www.mozilla.org"); - - do_check_eq(crypto.decryptData(crypto.encryptData("https://reviewboard.mozilla.org", key), - key), - "https://reviewboard.mozilla.org"); - - do_check_eq(crypto.decryptData(crypto.encryptData("https://bugzilla.mozilla.org/page.cgi", - key), - key), - "https://bugzilla.mozilla.org/page.cgi"); - } - - let keys = [null, "a", "keys", "abcdedf", "pass", "https://bugzilla.mozilla.org/page.cgi", - "https://login.live.com/login.srf"]; - for (let key of keys) { - decryptEncryptTest(key); - } - let url = "https://twitter.com/"; - let value = [1, 0, 0, 0, 208, 140, 157, 223, 1, 21, 209, 17, 140, 122, 0, 192, 79, 194, 151, 235, 1, 0, 0, 0, 254, 58, 230, 75, 132, 228, 181, 79, 184, 160, 37, 106, 201, 29, 42, 152, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 16, 102, 0, 0, 0, 1, 0, 0, 32, 0, 0, 0, 90, 136, 17, 124, 122, 57, 178, 24, 34, 86, 209, 198, 184, 107, 58, 58, 32, 98, 61, 239, 129, 101, 56, 239, 114, 159, 139, 165, 183, 40, 183, 85, 0, 0, 0, 0, 14, 128, 0, 0, 0, 2, 0, 0, 32, 0, 0, 0, 147, 170, 34, 21, 53, 227, 191, 6, 201, 84, 106, 31, 57, 227, 46, 127, 219, 199, 80, 142, 37, 104, 112, 223, 26, 165, 223, 55, 176, 89, 55, 37, 112, 0, 0, 0, 98, 70, 221, 109, 5, 152, 46, 11, 190, 213, 226, 58, 244, 20, 180, 217, 63, 155, 227, 132, 7, 151, 235, 6, 37, 232, 176, 182, 141, 191, 251, 50, 20, 123, 53, 11, 247, 233, 112, 121, 130, 27, 168, 68, 92, 144, 192, 7, 12, 239, 53, 217, 253, 155, 54, 109, 236, 216, 225, 245, 79, 234, 165, 225, 104, 36, 77, 13, 195, 237, 143, 165, 100, 107, 230, 70, 54, 19, 179, 35, 8, 101, 93, 202, 121, 210, 222, 28, 93, 122, 36, 84, 185, 249, 238, 3, 102, 149, 248, 94, 137, 16, 192, 22, 251, 220, 22, 223, 16, 58, 104, 187, 64, 0, 0, 0, 70, 72, 15, 119, 144, 66, 117, 203, 190, 82, 131, 46, 111, 130, 238, 191, 170, 63, 186, 117, 46, 88, 171, 3, 94, 146, 75, 86, 243, 159, 63, 195, 149, 25, 105, 141, 42, 217, 108, 18, 63, 62, 98, 182, 241, 195, 12, 216, 152, 230, 176, 253, 202, 129, 41, 185, 135, 111, 226, 92, 27, 78, 27, 198]; - - let arr1 = crypto.arrayToString(value); - let arr2 = crypto.stringToArray(crypto.decryptData(crypto.encryptData(arr1, url), url)); - for (let i = 0; i < arr1.length; i++) { - do_check_eq(arr2[i], value[i]); - } -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_context_menu.js b/toolkit/components/passwordmgr/test/unit/test_context_menu.js deleted file mode 100644 index 722c13e15..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_context_menu.js +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Test the password manager context menu. - */ - -"use strict"; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/LoginManagerContextMenu.jsm"); - -XPCOMUtils.defineLazyGetter(this, "_stringBundle", function() { - return Services.strings. - createBundle("chrome://passwordmgr/locale/passwordmgr.properties"); -}); - -/** - * Prepare data for the following tests. - */ -add_task(function* test_initialize() { - for (let login of loginList()) { - Services.logins.addLogin(login); - } -}); - -/** - * Tests if the LoginManagerContextMenu returns the correct login items. - */ -add_task(function* test_contextMenuAddAndRemoveLogins() { - const DOCUMENT_CONTENT = "<form><input id='pw' type=password></form>"; - const INPUT_QUERY = "input[type='password']"; - - let testHostnames = [ - "http://www.example.com", - "http://www2.example.com", - "http://www3.example.com", - "http://empty.example.com", - ]; - - for (let hostname of testHostnames) { - do_print("test for hostname: " + hostname); - // Get expected logins for this test. - let logins = getExpectedLogins(hostname); - - // Create the logins menuitems fragment. - let {fragment, document} = createLoginsFragment(hostname, DOCUMENT_CONTENT, INPUT_QUERY); - - if (!logins.length) { - Assert.ok(fragment === null, "Null returned. No logins where found."); - continue; - } - let items = [...fragment.querySelectorAll("menuitem")]; - - // Check if the items are those expected to be listed. - Assert.ok(checkLoginItems(logins, items), "All expected logins found."); - document.body.appendChild(fragment); - - // Try to clear the fragment. - LoginManagerContextMenu.clearLoginsFromMenu(document); - Assert.equal(fragment.querySelectorAll("menuitem").length, 0, "All items correctly cleared."); - } - - Services.logins.removeAllLogins(); -}); - -/** - * Create a fragment with a menuitem for each login. - */ -function createLoginsFragment(url, content, elementQuery) { - const CHROME_URL = "chrome://mock-chrome"; - - // Create a mock document. - let document = MockDocument.createTestDocument(CHROME_URL, content); - let inputElement = document.querySelector(elementQuery); - MockDocument.mockOwnerDocumentProperty(inputElement, document, url); - - // We also need a simple mock Browser object for this test. - let browser = { - ownerDocument: document - }; - - let URI = Services.io.newURI(url, null, null); - return { - document, - fragment: LoginManagerContextMenu.addLoginsToMenu(inputElement, browser, URI), - }; -} - -/** - * Check if every login have it's corresponding menuitem. - * Duplicates and empty usernames have a date appended. - */ -function checkLoginItems(logins, items) { - function findDuplicates(unfilteredLoginList) { - var seen = new Set(); - var duplicates = new Set(); - for (let login of unfilteredLoginList) { - if (seen.has(login.username)) { - duplicates.add(login.username); - } - seen.add(login.username); - } - return duplicates; - } - let duplicates = findDuplicates(logins); - - let dateAndTimeFormatter = new Intl.DateTimeFormat(undefined, - { day: "numeric", month: "short", year: "numeric" }); - 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. - if (!items.find(item => item.label == login.username)) { - return false; - } - continue; - } - - let meta = login.QueryInterface(Ci.nsILoginMetaInfo); - let time = dateAndTimeFormatter.format(new Date(meta.timePasswordChanged)); - // If login is duplicate, check if we have a login item with appended date. - if (login.username && !items.find(item => item.label == login.username + " (" + time + ")")) { - return false; - } - // If login is empty, check if we have a login item with appended date. - if (!login.username && - !items.find(item => item.label == _stringBundle.GetStringFromName("noUsername") + " (" + time + ")")) { - return false; - } - } - return true; -} - -/** - * Gets the list of expected logins for a hostname. - */ -function getExpectedLogins(hostname) { - return Services.logins.getAllLogins().filter(entry => entry["hostname"] === 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, - "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://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"), - ]; -} diff --git a/toolkit/components/passwordmgr/test/unit/test_dedupeLogins.js b/toolkit/components/passwordmgr/test/unit/test_dedupeLogins.js deleted file mode 100644 index d688a6dbf..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_dedupeLogins.js +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Test LoginHelper.dedupeLogins - */ - -"use strict"; - -Cu.import("resource://gre/modules/LoginHelper.jsm"); - -const DOMAIN1_HTTP_TO_HTTP_U1_P1 = TestData.formLogin({ - timePasswordChanged: 3000, - timeLastUsed: 2000, -}); -const DOMAIN1_HTTP_TO_HTTP_U1_P2 = TestData.formLogin({ - password: "password two", -}); -const DOMAIN1_HTTP_TO_HTTP_U2_P2 = TestData.formLogin({ - password: "password two", - username: "username two", -}); -const DOMAIN1_HTTPS_TO_HTTPS_U1_P1 = TestData.formLogin({ - formSubmitURL: "http://www.example.com", - hostname: "https://www3.example.com", - timePasswordChanged: 4000, - timeLastUsed: 1000, -}); -const DOMAIN1_HTTPS_TO_EMPTY_U1_P1 = TestData.formLogin({ - formSubmitURL: "", - hostname: "https://www3.example.com", -}); -const DOMAIN1_HTTPS_TO_EMPTYU_P1 = TestData.formLogin({ - hostname: "https://www3.example.com", - username: "", -}); -const DOMAIN1_HTTP_AUTH = TestData.authLogin({ - hostname: "http://www3.example.com", -}); -const DOMAIN1_HTTPS_AUTH = TestData.authLogin({ - hostname: "https://www3.example.com", -}); - - -add_task(function test_dedupeLogins() { - // [description, expectedOutput, dedupe arg. 0, dedupe arg 1, ...] - let testcases = [ - [ - "exact dupes", - [DOMAIN1_HTTP_TO_HTTP_U1_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - undefined, - [], // force no resolveBy logic to test behavior of preferring the first.. - ], - [ - "default uniqueKeys is un + pw", - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P2], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P2], - undefined, - [], - ], - [ - "same usernames, different passwords, dedupe username only", - [DOMAIN1_HTTP_TO_HTTP_U1_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P2], - ["username"], - [], - ], - [ - "same un+pw, different scheme", - [DOMAIN1_HTTP_TO_HTTP_U1_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - undefined, - [], - ], - [ - "same un+pw, different scheme, reverse order", - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - undefined, - [], - ], - [ - "same un+pw, different scheme, include hostname", - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - ["hostname", "username", "password"], - [], - ], - [ - "empty username is not deduped with non-empty", - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTPS_TO_EMPTYU_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTPS_TO_EMPTYU_P1], - undefined, - [], - ], - [ - "empty username is deduped with same passwords", - [DOMAIN1_HTTPS_TO_EMPTYU_P1], - [DOMAIN1_HTTPS_TO_EMPTYU_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - ["password"], - [], - ], - [ - "mix of form and HTTP auth", - [DOMAIN1_HTTP_TO_HTTP_U1_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTP_AUTH], - undefined, - [], - ], - ]; - - for (let tc of testcases) { - let description = tc.shift(); - let expected = tc.shift(); - let actual = LoginHelper.dedupeLogins(...tc); - Assert.strictEqual(actual.length, expected.length, `Check: ${description}`); - for (let [i, login] of expected.entries()) { - Assert.strictEqual(actual[i], login, `Check index ${i}`); - } - } -}); - - -add_task(function* test_dedupeLogins_resolveBy() { - Assert.ok(DOMAIN1_HTTP_TO_HTTP_U1_P1.timeLastUsed > DOMAIN1_HTTPS_TO_HTTPS_U1_P1.timeLastUsed, - "Sanity check timeLastUsed difference"); - Assert.ok(DOMAIN1_HTTP_TO_HTTP_U1_P1.timePasswordChanged < DOMAIN1_HTTPS_TO_HTTPS_U1_P1.timePasswordChanged, - "Sanity check timePasswordChanged difference"); - - let testcases = [ - [ - "default resolveBy is timeLastUsed", - [DOMAIN1_HTTP_TO_HTTP_U1_P1], - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - ], - [ - "default resolveBy is timeLastUsed, reversed input", - [DOMAIN1_HTTP_TO_HTTP_U1_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - ], - [ - "resolveBy timeLastUsed + timePasswordChanged", - [DOMAIN1_HTTP_TO_HTTP_U1_P1], - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - undefined, - ["timeLastUsed", "timePasswordChanged"], - ], - [ - "resolveBy timeLastUsed + timePasswordChanged, reversed input", - [DOMAIN1_HTTP_TO_HTTP_U1_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - undefined, - ["timeLastUsed", "timePasswordChanged"], - ], - [ - "resolveBy timePasswordChanged", - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - undefined, - ["timePasswordChanged"], - ], - [ - "resolveBy timePasswordChanged, reversed", - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - undefined, - ["timePasswordChanged"], - ], - [ - "resolveBy timePasswordChanged + timeLastUsed", - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - undefined, - ["timePasswordChanged", "timeLastUsed"], - ], - [ - "resolveBy timePasswordChanged + timeLastUsed, reversed", - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - undefined, - ["timePasswordChanged", "timeLastUsed"], - ], - [ - "resolveBy scheme + timePasswordChanged, prefer HTTP", - [DOMAIN1_HTTP_TO_HTTP_U1_P1], - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - undefined, - ["scheme", "timePasswordChanged"], - DOMAIN1_HTTP_TO_HTTP_U1_P1.hostname, - ], - [ - "resolveBy scheme + timePasswordChanged, prefer HTTP, reversed input", - [DOMAIN1_HTTP_TO_HTTP_U1_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - undefined, - ["scheme", "timePasswordChanged"], - DOMAIN1_HTTP_TO_HTTP_U1_P1.hostname, - ], - [ - "resolveBy scheme + timePasswordChanged, prefer HTTPS", - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - undefined, - ["scheme", "timePasswordChanged"], - DOMAIN1_HTTPS_TO_HTTPS_U1_P1.hostname, - ], - [ - "resolveBy scheme + timePasswordChanged, prefer HTTPS, reversed input", - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - [DOMAIN1_HTTP_TO_HTTP_U1_P1, DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - undefined, - ["scheme", "timePasswordChanged"], - DOMAIN1_HTTPS_TO_HTTPS_U1_P1.hostname, - ], - [ - "resolveBy scheme HTTP auth", - [DOMAIN1_HTTPS_AUTH], - [DOMAIN1_HTTP_AUTH, DOMAIN1_HTTPS_AUTH], - undefined, - ["scheme"], - DOMAIN1_HTTPS_AUTH.hostname, - ], - [ - "resolveBy scheme HTTP auth, reversed input", - [DOMAIN1_HTTPS_AUTH], - [DOMAIN1_HTTPS_AUTH, DOMAIN1_HTTP_AUTH], - undefined, - ["scheme"], - DOMAIN1_HTTPS_AUTH.hostname, - ], - [ - "resolveBy scheme, empty form submit URL", - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1], - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTPS_TO_EMPTY_U1_P1], - undefined, - ["scheme"], - DOMAIN1_HTTPS_TO_HTTPS_U1_P1.hostname, - ], - ]; - - for (let tc of testcases) { - let description = tc.shift(); - let expected = tc.shift(); - let actual = LoginHelper.dedupeLogins(...tc); - Assert.strictEqual(actual.length, expected.length, `Check: ${description}`); - for (let [i, login] of expected.entries()) { - Assert.strictEqual(actual[i], login, `Check index ${i}`); - } - } - -}); - -add_task(function* test_dedupeLogins_preferredOriginMissing() { - let testcases = [ - [ - "resolveBy scheme + timePasswordChanged, missing preferredOrigin", - /preferredOrigin/, - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - undefined, - ["scheme", "timePasswordChanged"], - ], - [ - "resolveBy timePasswordChanged + scheme, missing preferredOrigin", - /preferredOrigin/, - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - undefined, - ["timePasswordChanged", "scheme"], - ], - [ - "resolveBy scheme + timePasswordChanged, empty preferredOrigin", - /preferredOrigin/, - [DOMAIN1_HTTPS_TO_HTTPS_U1_P1, DOMAIN1_HTTP_TO_HTTP_U1_P1], - undefined, - ["scheme", "timePasswordChanged"], - "", - ], - ]; - - for (let tc of testcases) { - let description = tc.shift(); - let expectedException = tc.shift(); - Assert.throws(() => { - LoginHelper.dedupeLogins(...tc); - }, expectedException, `Check: ${description}`); - } -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_disabled_hosts.js b/toolkit/components/passwordmgr/test/unit/test_disabled_hosts.js deleted file mode 100644 index ff3b7e868..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_disabled_hosts.js +++ /dev/null @@ -1,196 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests getLoginSavingEnabled, setLoginSavingEnabled, and getAllDisabledHosts. - */ - -"use strict"; - -// Tests - -/** - * Tests setLoginSavingEnabled and getAllDisabledHosts. - */ -add_task(function test_setLoginSavingEnabled_getAllDisabledHosts() -{ - // Add some disabled hosts, and verify that different schemes for the same - // domain are considered different hosts. - let hostname1 = "http://disabled1.example.com"; - let hostname2 = "http://disabled2.example.com"; - let hostname3 = "https://disabled2.example.com"; - Services.logins.setLoginSavingEnabled(hostname1, false); - Services.logins.setLoginSavingEnabled(hostname2, false); - Services.logins.setLoginSavingEnabled(hostname3, false); - - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), - [hostname1, hostname2, hostname3]); - - // Adding the same host twice should not result in an error. - Services.logins.setLoginSavingEnabled(hostname2, false); - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), - [hostname1, hostname2, hostname3]); - - // Removing a disabled host should work. - Services.logins.setLoginSavingEnabled(hostname2, true); - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), - [hostname1, hostname3]); - - // Removing the last disabled host should work. - Services.logins.setLoginSavingEnabled(hostname1, true); - Services.logins.setLoginSavingEnabled(hostname3, true); - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), - []); -}); - -/** - * Tests setLoginSavingEnabled and getLoginSavingEnabled. - */ -add_task(function test_setLoginSavingEnabled_getLoginSavingEnabled() -{ - let hostname1 = "http://disabled.example.com"; - let hostname2 = "https://disabled.example.com"; - - // Hosts should not be disabled by default. - do_check_true(Services.logins.getLoginSavingEnabled(hostname1)); - do_check_true(Services.logins.getLoginSavingEnabled(hostname2)); - - // Test setting initial values. - Services.logins.setLoginSavingEnabled(hostname1, false); - Services.logins.setLoginSavingEnabled(hostname2, true); - do_check_false(Services.logins.getLoginSavingEnabled(hostname1)); - do_check_true(Services.logins.getLoginSavingEnabled(hostname2)); - - // Test changing values. - Services.logins.setLoginSavingEnabled(hostname1, true); - Services.logins.setLoginSavingEnabled(hostname2, false); - do_check_true(Services.logins.getLoginSavingEnabled(hostname1)); - do_check_false(Services.logins.getLoginSavingEnabled(hostname2)); - - // Clean up. - Services.logins.setLoginSavingEnabled(hostname2, true); -}); - -/** - * Tests setLoginSavingEnabled with invalid NUL characters in the hostname. - */ -add_task(function test_setLoginSavingEnabled_invalid_characters() -{ - let hostname = "http://null\0X.example.com"; - Assert.throws(() => Services.logins.setLoginSavingEnabled(hostname, false), - /Invalid hostname/); - - // Verify that no data was stored by the previous call. - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), - []); -}); - -/** - * Tests different values of the "signon.rememberSignons" property. - */ -add_task(function test_rememberSignons() -{ - let hostname1 = "http://example.com"; - let hostname2 = "http://localhost"; - - // The default value for the preference should be true. - do_check_true(Services.prefs.getBoolPref("signon.rememberSignons")); - - // Hosts should not be disabled by default. - Services.logins.setLoginSavingEnabled(hostname1, false); - do_check_false(Services.logins.getLoginSavingEnabled(hostname1)); - do_check_true(Services.logins.getLoginSavingEnabled(hostname2)); - - // Disable storage of saved passwords globally. - Services.prefs.setBoolPref("signon.rememberSignons", false); - do_register_cleanup( - () => Services.prefs.clearUserPref("signon.rememberSignons")); - - // All hosts should now appear disabled. - do_check_false(Services.logins.getLoginSavingEnabled(hostname1)); - do_check_false(Services.logins.getLoginSavingEnabled(hostname2)); - - // The list of disabled hosts should be unaltered. - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), - [hostname1]); - - // Changing values with the preference set should work. - Services.logins.setLoginSavingEnabled(hostname1, true); - Services.logins.setLoginSavingEnabled(hostname2, false); - - // All hosts should still appear disabled. - do_check_false(Services.logins.getLoginSavingEnabled(hostname1)); - do_check_false(Services.logins.getLoginSavingEnabled(hostname2)); - - // The list of disabled hosts should have been changed. - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), - [hostname2]); - - // Enable storage of saved passwords again. - Services.prefs.setBoolPref("signon.rememberSignons", true); - - // Hosts should now appear enabled as requested. - do_check_true(Services.logins.getLoginSavingEnabled(hostname1)); - do_check_false(Services.logins.getLoginSavingEnabled(hostname2)); - - // Clean up. - Services.logins.setLoginSavingEnabled(hostname2, true); - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), - []); -}); - -/** - * Tests storing disabled hosts with non-ASCII characters where IDN is supported. - */ -add_task(function* test_storage_setLoginSavingEnabled_nonascii_IDN_is_supported() -{ - let hostname = "http://大.net"; - let encoding = "http://xn--pss.net"; - - // Test adding disabled host with nonascii URL (http://大.net). - Services.logins.setLoginSavingEnabled(hostname, false); - yield* LoginTestUtils.reloadData(); - Assert.equal(Services.logins.getLoginSavingEnabled(hostname), false); - Assert.equal(Services.logins.getLoginSavingEnabled(encoding), false); - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), [hostname]); - - LoginTestUtils.clearData(); - - // Test adding disabled host with IDN ("http://xn--pss.net"). - Services.logins.setLoginSavingEnabled(encoding, false); - yield* LoginTestUtils.reloadData(); - Assert.equal(Services.logins.getLoginSavingEnabled(hostname), false); - Assert.equal(Services.logins.getLoginSavingEnabled(encoding), false); - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), [hostname]); - - LoginTestUtils.clearData(); -}); - -/** - * Tests storing disabled hosts with non-ASCII characters where IDN is not supported. - */ -add_task(function* test_storage_setLoginSavingEnabled_nonascii_IDN_not_supported() -{ - let hostname = "http://√.com"; - let encoding = "http://xn--19g.com"; - - // Test adding disabled host with nonascii URL (http://√.com). - Services.logins.setLoginSavingEnabled(hostname, false); - yield* LoginTestUtils.reloadData(); - Assert.equal(Services.logins.getLoginSavingEnabled(hostname), false); - Assert.equal(Services.logins.getLoginSavingEnabled(encoding), false); - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), [encoding]); - - LoginTestUtils.clearData(); - - // Test adding disabled host with IDN ("http://xn--19g.com"). - Services.logins.setLoginSavingEnabled(encoding, false); - yield* LoginTestUtils.reloadData(); - Assert.equal(Services.logins.getLoginSavingEnabled(hostname), false); - Assert.equal(Services.logins.getLoginSavingEnabled(encoding), false); - LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), [encoding]); - - LoginTestUtils.clearData(); -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_getFormFields.js b/toolkit/components/passwordmgr/test/unit/test_getFormFields.js deleted file mode 100644 index 46912ab8f..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_getFormFields.js +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Test for LoginManagerContent._getFormFields. - */ - -"use strict"; - -// Services.prefs.setBoolPref("signon.debug", true); - -Cu.importGlobalProperties(["URL"]); - -const LMCBackstagePass = Cu.import("resource://gre/modules/LoginManagerContent.jsm"); -const { LoginManagerContent, LoginFormFactory } = LMCBackstagePass; -const TESTCASES = [ - { - description: "1 password field outside of a <form>", - document: `<input id="pw1" type=password>`, - returnedFieldIDs: [null, "pw1", null], - skipEmptyFields: undefined, - }, - { - description: "1 text field outside of a <form> without a password field", - document: `<input id="un1">`, - returnedFieldIDs: [null, null, null], - skipEmptyFields: undefined, - }, - { - description: "1 username & password field outside of a <form>", - document: `<input id="un1"> - <input id="pw1" type=password>`, - returnedFieldIDs: ["un1", "pw1", null], - skipEmptyFields: undefined, - }, - { - description: "1 username & password field in a <form>", - document: `<form> - <input id="un1"> - <input id="pw1" type=password> - </form>`, - returnedFieldIDs: ["un1", "pw1", null], - skipEmptyFields: undefined, - }, - { - description: "4 empty password fields outside of a <form>", - document: `<input id="pw1" type=password> - <input id="pw2" type=password> - <input id="pw3" type=password> - <input id="pw4" type=password>`, - returnedFieldIDs: [null, null, null], - skipEmptyFields: undefined, - }, - { - description: "4 password fields outside of a <form> (1 empty, 3 full) with skipEmpty", - document: `<input id="pw1" type=password> - <input id="pw2" type=password value="pass2"> - <input id="pw3" type=password value="pass3"> - <input id="pw4" type=password value="pass4">`, - returnedFieldIDs: [null, null, null], - skipEmptyFields: true, - }, - { - description: "Form with 1 password field", - document: `<form><input id="pw1" type=password></form>`, - returnedFieldIDs: [null, "pw1", null], - skipEmptyFields: undefined, - }, - { - description: "Form with 2 password fields", - document: `<form><input id="pw1" type=password><input id='pw2' type=password></form>`, - returnedFieldIDs: [null, "pw1", null], - skipEmptyFields: undefined, - }, - { - description: "1 password field in a form, 1 outside (not processed)", - document: `<form><input id="pw1" type=password></form><input id="pw2" type=password>`, - returnedFieldIDs: [null, "pw1", null], - skipEmptyFields: undefined, - }, - { - description: "1 password field in a form, 1 text field outside (not processed)", - document: `<form><input id="pw1" type=password></form><input>`, - returnedFieldIDs: [null, "pw1", null], - skipEmptyFields: undefined, - }, - { - description: "1 text field in a form, 1 password field outside (not processed)", - document: `<form><input></form><input id="pw1" type=password>`, - returnedFieldIDs: [null, null, null], - skipEmptyFields: undefined, - }, - { - description: "2 password fields outside of a <form> with 1 linked via @form", - document: `<input id="pw1" type=password><input id="pw2" type=password form='form1'> - <form id="form1"></form>`, - returnedFieldIDs: [null, "pw1", null], - skipEmptyFields: undefined, - }, - { - description: "2 password fields outside of a <form> with 1 linked via @form + skipEmpty", - document: `<input id="pw1" type=password><input id="pw2" type=password form="form1"> - <form id="form1"></form>`, - returnedFieldIDs: [null, null, null], - skipEmptyFields: true, - }, - { - description: "2 password fields outside of a <form> with 1 linked via @form + skipEmpty with 1 empty", - document: `<input id="pw1" type=password value="pass1"><input id="pw2" type=password form="form1"> - <form id="form1"></form>`, - returnedFieldIDs: [null, "pw1", null], - skipEmptyFields: true, - }, -]; - -for (let tc of TESTCASES) { - do_print("Sanity checking the testcase: " + tc.description); - - (function() { - let testcase = tc; - add_task(function*() { - do_print("Starting testcase: " + testcase.description); - let document = MockDocument.createTestDocument("http://localhost:8080/test/", - testcase.document); - - let input = document.querySelector("input"); - MockDocument.mockOwnerDocumentProperty(input, document, "http://localhost:8080/test/"); - - let formLike = LoginFormFactory.createFromField(input); - - let actual = LoginManagerContent._getFormFields(formLike, - testcase.skipEmptyFields, - new Set()); - - Assert.strictEqual(testcase.returnedFieldIDs.length, 3, - "_getFormFields returns 3 elements"); - - for (let i = 0; i < testcase.returnedFieldIDs.length; i++) { - let expectedID = testcase.returnedFieldIDs[i]; - if (expectedID === null) { - Assert.strictEqual(actual[i], expectedID, - "Check returned field " + i + " is null"); - } else { - Assert.strictEqual(actual[i].id, expectedID, - "Check returned field " + i + " ID"); - } - } - }); - })(); -} diff --git a/toolkit/components/passwordmgr/test/unit/test_getPasswordFields.js b/toolkit/components/passwordmgr/test/unit/test_getPasswordFields.js deleted file mode 100644 index 08fa422ab..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_getPasswordFields.js +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Test for LoginManagerContent._getPasswordFields using LoginFormFactory. - */ - -"use strict"; - -const LMCBackstagePass = Cu.import("resource://gre/modules/LoginManagerContent.jsm"); -const { LoginManagerContent, LoginFormFactory } = LMCBackstagePass; -const TESTCASES = [ - { - description: "Empty document", - document: ``, - returnedFieldIDsByFormLike: [], - skipEmptyFields: undefined, - }, - { - description: "Non-password input with no <form> present", - document: `<input>`, - // Only the IDs of password fields should be in this array - returnedFieldIDsByFormLike: [[]], - skipEmptyFields: undefined, - }, - { - description: "1 password field outside of a <form>", - document: `<input id="pw1" type=password>`, - returnedFieldIDsByFormLike: [["pw1"]], - skipEmptyFields: undefined, - }, - { - description: "4 empty password fields outside of a <form>", - document: `<input id="pw1" type=password> - <input id="pw2" type=password> - <input id="pw3" type=password> - <input id="pw4" type=password>`, - returnedFieldIDsByFormLike: [[]], - skipEmptyFields: undefined, - }, - { - description: "4 password fields outside of a <form> (1 empty, 3 full) with skipEmpty", - document: `<input id="pw1" type=password> - <input id="pw2" type=password value="pass2"> - <input id="pw3" type=password value="pass3"> - <input id="pw4" type=password value="pass4">`, - returnedFieldIDsByFormLike: [["pw2", "pw3", "pw4"]], - skipEmptyFields: true, - }, - { - description: "Form with 1 password field", - document: `<form><input id="pw1" type=password></form>`, - returnedFieldIDsByFormLike: [["pw1"]], - skipEmptyFields: undefined, - }, - { - description: "Form with 2 password fields", - document: `<form><input id="pw1" type=password><input id='pw2' type=password></form>`, - returnedFieldIDsByFormLike: [["pw1", "pw2"]], - skipEmptyFields: undefined, - }, - { - description: "1 password field in a form, 1 outside", - document: `<form><input id="pw1" type=password></form><input id="pw2" type=password>`, - returnedFieldIDsByFormLike: [["pw1"], ["pw2"]], - skipEmptyFields: undefined, - }, - { - description: "2 password fields outside of a <form> with 1 linked via @form", - document: `<input id="pw1" type=password><input id="pw2" type=password form='form1'> - <form id="form1"></form>`, - returnedFieldIDsByFormLike: [["pw1"], ["pw2"]], - skipEmptyFields: undefined, - }, - { - description: "2 password fields outside of a <form> with 1 linked via @form + skipEmpty", - document: `<input id="pw1" type=password><input id="pw2" type=password form="form1"> - <form id="form1"></form>`, - returnedFieldIDsByFormLike: [[], []], - skipEmptyFields: true, - }, - { - description: "skipEmptyFields should also skip white-space only fields", - document: `<input id="pw-space" type=password value=" "> - <input id="pw-tab" type=password value=" "> - <input id="pw-newline" type=password form="form1" value=" -"> - <form id="form1"></form>`, - returnedFieldIDsByFormLike: [[], []], - skipEmptyFields: true, - }, - { - description: "2 password fields outside of a <form> with 1 linked via @form + skipEmpty with 1 empty", - document: `<input id="pw1" type=password value=" pass1 "><input id="pw2" type=password form="form1"> - <form id="form1"></form>`, - returnedFieldIDsByFormLike: [["pw1"], []], - skipEmptyFields: true, - }, -]; - -for (let tc of TESTCASES) { - do_print("Sanity checking the testcase: " + tc.description); - - (function() { - let testcase = tc; - add_task(function*() { - do_print("Starting testcase: " + testcase.description); - let document = MockDocument.createTestDocument("http://localhost:8080/test/", - testcase.document); - - let mapRootElementToFormLike = new Map(); - for (let input of document.querySelectorAll("input")) { - let formLike = LoginFormFactory.createFromField(input); - let existingFormLike = mapRootElementToFormLike.get(formLike.rootElement); - if (!existingFormLike) { - mapRootElementToFormLike.set(formLike.rootElement, formLike); - continue; - } - - // If the formLike is already present, ensure that the properties are the same. - do_print("Checking if the new FormLike for the same root has the same properties"); - formLikeEqual(formLike, existingFormLike); - } - - Assert.strictEqual(mapRootElementToFormLike.size, testcase.returnedFieldIDsByFormLike.length, - "Check the correct number of different formLikes were returned"); - - let formLikeIndex = -1; - for (let formLikeFromInput of mapRootElementToFormLike.values()) { - formLikeIndex++; - let pwFields = LoginManagerContent._getPasswordFields(formLikeFromInput, - testcase.skipEmptyFields); - - if (formLikeFromInput.rootElement instanceof Ci.nsIDOMHTMLFormElement) { - let formLikeFromForm = LoginFormFactory.createFromForm(formLikeFromInput.rootElement); - do_print("Checking that the FormLike created for the <form> matches" + - " the one from a password field"); - formLikeEqual(formLikeFromInput, formLikeFromForm); - } - - - if (testcase.returnedFieldIDsByFormLike[formLikeIndex].length === 0) { - Assert.strictEqual(pwFields, null, - "If no password fields were found null should be returned"); - } else { - Assert.strictEqual(pwFields.length, - testcase.returnedFieldIDsByFormLike[formLikeIndex].length, - "Check the # of password fields for formLike #" + formLikeIndex); - } - - for (let i = 0; i < testcase.returnedFieldIDsByFormLike[formLikeIndex].length; i++) { - let expectedID = testcase.returnedFieldIDsByFormLike[formLikeIndex][i]; - Assert.strictEqual(pwFields[i].element.id, expectedID, - "Check password field " + i + " ID"); - } - } - }); - })(); -} diff --git a/toolkit/components/passwordmgr/test/unit/test_getPasswordOrigin.js b/toolkit/components/passwordmgr/test/unit/test_getPasswordOrigin.js deleted file mode 100644 index f2773ec62..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_getPasswordOrigin.js +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Test for LoginUtils._getPasswordOrigin - */ - -"use strict"; - -const LMCBackstagePass = Cu.import("resource://gre/modules/LoginManagerContent.jsm"); -const TESTCASES = [ - ["javascript:void(0);", null], - ["javascript:void(0);", "javascript:", true], - ["chrome://MyAccount", null], - ["data:text/html,example", null], - ["http://username:password@example.com:80/foo?bar=baz#fragment", "http://example.com", true], - ["http://127.0.0.1:80/foo", "http://127.0.0.1"], - ["http://[::1]:80/foo", "http://[::1]"], - ["http://example.com:8080/foo", "http://example.com:8080"], - ["http://127.0.0.1:8080/foo", "http://127.0.0.1:8080", true], - ["http://[::1]:8080/foo", "http://[::1]:8080"], - ["https://example.com:443/foo", "https://example.com"], - ["https://[::1]:443/foo", "https://[::1]"], - ["https://[::1]:8443/foo", "https://[::1]:8443"], - ["ftp://username:password@[::1]:2121/foo", "ftp://[::1]:2121"], -]; - -for (let [input, expected, allowJS] of TESTCASES) { - let actual = LMCBackstagePass.LoginUtils._getPasswordOrigin(input, allowJS); - Assert.strictEqual(actual, expected, "Checking: " + input); -} diff --git a/toolkit/components/passwordmgr/test/unit/test_isOriginMatching.js b/toolkit/components/passwordmgr/test/unit/test_isOriginMatching.js deleted file mode 100644 index 660910dff..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_isOriginMatching.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Test LoginHelper.isOriginMatching - */ - -"use strict"; - -Cu.import("resource://gre/modules/LoginHelper.jsm"); - -add_task(function test_isOriginMatching() { - let testcases = [ - // Index 0 holds the expected return value followed by arguments to isOriginMatching. - [true, "http://example.com", "http://example.com"], - [true, "http://example.com:8080", "http://example.com:8080"], - [true, "https://example.com", "https://example.com"], - [true, "https://example.com:8443", "https://example.com:8443"], - [false, "http://example.com", "http://mozilla.org"], - [false, "http://example.com", "http://example.com:8080"], - [false, "https://example.com", "http://example.com"], - [false, "https://example.com", "https://mozilla.org"], - [false, "http://example.com", "http://sub.example.com"], - [false, "https://example.com", "https://sub.example.com"], - [false, "http://example.com", "https://example.com:8443"], - [false, "http://example.com:8080", "http://example.com:8081"], - [false, "http://example.com", ""], - [false, "", "http://example.com"], - [true, "http://example.com", "https://example.com", { schemeUpgrades: true }], - [true, "https://example.com", "https://example.com", { schemeUpgrades: true }], - [true, "http://example.com:8080", "http://example.com:8080", { schemeUpgrades: true }], - [true, "https://example.com:8443", "https://example.com:8443", { schemeUpgrades: true }], - [false, "https://example.com", "http://example.com", { schemeUpgrades: true }], // downgrade - [false, "http://example.com:8080", "https://example.com", { schemeUpgrades: true }], // port mismatch - [false, "http://example.com", "https://example.com:8443", { schemeUpgrades: true }], // port mismatch - [false, "http://sub.example.com", "http://example.com", { schemeUpgrades: true }], - ]; - for (let tc of testcases) { - let expected = tc.shift(); - Assert.strictEqual(LoginHelper.isOriginMatching(...tc), expected, - "Check " + JSON.stringify(tc)); - } -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_legacy_empty_formSubmitURL.js b/toolkit/components/passwordmgr/test/unit/test_legacy_empty_formSubmitURL.js deleted file mode 100644 index 4e16aa267..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_legacy_empty_formSubmitURL.js +++ /dev/null @@ -1,107 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests the legacy case of a login store containing entries that have an empty - * string in the formSubmitURL field. - * - * In normal conditions, for the purpose of login autocomplete, HTML forms are - * identified using both the prePath of the URI on which they are located, and - * the prePath of the URI where the data will be submitted. This is represented - * by the hostname and formSubmitURL properties of the stored nsILoginInfo. - * - * When a new login for use in forms is saved (after the user replies to the - * password prompt), it is always stored with both the hostname and the - * formSubmitURL (that will be equal to the hostname when the form has no - * "action" attribute). - * - * When the same form is displayed again, the password is autocompleted. If - * there is another form on the same site that submits to a different site, it - * is considered a different form, so the password is not autocompleted, but a - * new password can be stored for the other form. - * - * However, the login database might contain data for an nsILoginInfo that has a - * valid hostname, but an empty formSubmitURL. This means that the login - * applies to all forms on the site, regardless of where they submit data to. - * - * A site can have at most one such login, and in case it is present, then it is - * not possible to store separate logins for forms on the same site that submit - * data to different sites. - * - * The only way to have such condition is to be using logins that were initially - * saved by a very old version of the browser, or because of data manually added - * by an extension in an old version. - */ - -"use strict"; - -// Tests - -/** - * Adds a login with an empty formSubmitURL, then it verifies that no other - * form logins can be added for the same host. - */ -add_task(function test_addLogin_wildcard() -{ - let loginInfo = TestData.formLogin({ hostname: "http://any.example.com", - formSubmitURL: "" }); - Services.logins.addLogin(loginInfo); - - // Normal form logins cannot be added anymore. - loginInfo = TestData.formLogin({ hostname: "http://any.example.com" }); - Assert.throws(() => Services.logins.addLogin(loginInfo), /already exists/); - - // Authentication logins can still be added. - loginInfo = TestData.authLogin({ hostname: "http://any.example.com" }); - Services.logins.addLogin(loginInfo); - - // Form logins can be added for other hosts. - loginInfo = TestData.formLogin({ hostname: "http://other.example.com" }); - Services.logins.addLogin(loginInfo); -}); - -/** - * Verifies that findLogins, searchLogins, and countLogins include all logins - * that have an empty formSubmitURL in the store, even when a formSubmitURL is - * specified. - */ -add_task(function test_search_all_wildcard() -{ - // Search a given formSubmitURL on any host. - let matchData = newPropertyBag({ formSubmitURL: "http://www.example.com" }); - do_check_eq(Services.logins.searchLogins({}, matchData).length, 2); - - do_check_eq(Services.logins.findLogins({}, "", "http://www.example.com", - null).length, 2); - - do_check_eq(Services.logins.countLogins("", "http://www.example.com", - null), 2); - - // Restrict the search to one host. - matchData.setProperty("hostname", "http://any.example.com"); - do_check_eq(Services.logins.searchLogins({}, matchData).length, 1); - - do_check_eq(Services.logins.findLogins({}, "http://any.example.com", - "http://www.example.com", - null).length, 1); - - do_check_eq(Services.logins.countLogins("http://any.example.com", - "http://www.example.com", - null), 1); -}); - -/** - * Verifies that specifying an empty string for formSubmitURL in searchLogins - * includes only logins that have an empty formSubmitURL in the store. - */ -add_task(function test_searchLogins_wildcard() -{ - let logins = Services.logins.searchLogins({}, - newPropertyBag({ formSubmitURL: "" })); - - let loginInfo = TestData.formLogin({ hostname: "http://any.example.com", - formSubmitURL: "" }); - LoginTestUtils.assertLoginListsEqual(logins, [loginInfo]); -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_legacy_validation.js b/toolkit/components/passwordmgr/test/unit/test_legacy_validation.js deleted file mode 100644 index 709bc9818..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_legacy_validation.js +++ /dev/null @@ -1,76 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests the legacy validation made when storing nsILoginInfo or disabled hosts. - * - * These rules exist because of limitations of the "signons.txt" storage file, - * that is not used anymore. They are still enforced by the Login Manager - * service, despite these values can now be safely stored in the back-end. - */ - -"use strict"; - -// Tests - -/** - * Tests legacy validation with addLogin. - */ -add_task(function test_addLogin_invalid_characters_legacy() -{ - // Test newlines and carriage returns in properties that contain URLs. - for (let testValue of ["http://newline\n.example.com", - "http://carriagereturn.example.com\r"]) { - let loginInfo = TestData.formLogin({ hostname: testValue }); - Assert.throws(() => Services.logins.addLogin(loginInfo), - /login values can't contain newlines/); - - loginInfo = TestData.formLogin({ formSubmitURL: testValue }); - Assert.throws(() => Services.logins.addLogin(loginInfo), - /login values can't contain newlines/); - - loginInfo = TestData.authLogin({ httpRealm: testValue }); - Assert.throws(() => Services.logins.addLogin(loginInfo), - /login values can't contain newlines/); - } - - // Test newlines and carriage returns in form field names. - for (let testValue of ["newline_field\n", "carriagereturn\r_field"]) { - let loginInfo = TestData.formLogin({ usernameField: testValue }); - Assert.throws(() => Services.logins.addLogin(loginInfo), - /login values can't contain newlines/); - - loginInfo = TestData.formLogin({ passwordField: testValue }); - Assert.throws(() => Services.logins.addLogin(loginInfo), - /login values can't contain newlines/); - } - - // Test a single dot as the value of usernameField and formSubmitURL. - let loginInfo = TestData.formLogin({ usernameField: "." }); - Assert.throws(() => Services.logins.addLogin(loginInfo), - /login values can't be periods/); - - loginInfo = TestData.formLogin({ formSubmitURL: "." }); - Assert.throws(() => Services.logins.addLogin(loginInfo), - /login values can't be periods/); - - // Test the sequence " (" inside the value of the "hostname" property. - loginInfo = TestData.formLogin({ hostname: "http://parens (.example.com" }); - Assert.throws(() => Services.logins.addLogin(loginInfo), - /bad parens in hostname/); -}); - -/** - * Tests legacy validation with setLoginSavingEnabled. - */ -add_task(function test_setLoginSavingEnabled_invalid_characters_legacy() -{ - for (let hostname of ["http://newline\n.example.com", - "http://carriagereturn.example.com\r", - "."]) { - Assert.throws(() => Services.logins.setLoginSavingEnabled(hostname, false), - /Invalid hostname/); - } -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_logins_change.js b/toolkit/components/passwordmgr/test/unit/test_logins_change.js deleted file mode 100644 index 79c6d2f54..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_logins_change.js +++ /dev/null @@ -1,384 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests methods that add, remove, and modify logins. - */ - -"use strict"; - -// Globals - -/** - * Verifies that the specified login is considered invalid by addLogin and by - * modifyLogin with both nsILoginInfo and nsIPropertyBag arguments. - * - * This test requires that the login store is empty. - * - * @param aLoginInfo - * nsILoginInfo corresponding to an invalid login. - * @param aExpectedError - * This argument is passed to the "Assert.throws" test to determine which - * error is expected from the modification functions. - */ -function checkLoginInvalid(aLoginInfo, aExpectedError) -{ - // Try to add the new login, and verify that no data is stored. - Assert.throws(() => Services.logins.addLogin(aLoginInfo), aExpectedError); - LoginTestUtils.checkLogins([]); - - // Add a login for the modification tests. - let testLogin = TestData.formLogin({ hostname: "http://modify.example.com" }); - Services.logins.addLogin(testLogin); - - // Try to modify the existing login using nsILoginInfo and nsIPropertyBag. - Assert.throws(() => Services.logins.modifyLogin(testLogin, aLoginInfo), - aExpectedError); - Assert.throws(() => Services.logins.modifyLogin(testLogin, newPropertyBag({ - hostname: aLoginInfo.hostname, - formSubmitURL: aLoginInfo.formSubmitURL, - httpRealm: aLoginInfo.httpRealm, - username: aLoginInfo.username, - password: aLoginInfo.password, - usernameField: aLoginInfo.usernameField, - passwordField: aLoginInfo.passwordField, - })), aExpectedError); - - // Verify that no data was stored by the previous calls. - LoginTestUtils.checkLogins([testLogin]); - Services.logins.removeLogin(testLogin); -} - -/** - * Verifies that two objects are not the same instance - * but have equal attributes. - * - * @param {Object} objectA - * An object to compare. - * - * @param {Object} objectB - * Another object to compare. - * - * @param {string[]} attributes - * Attributes to compare. - * - * @return true if all passed attributes are equal for both objects, false otherwise. - */ -function compareAttributes(objectA, objectB, attributes) { - // If it's the same object, we want to return false. - if (objectA == objectB) { - return false; - } - return attributes.every(attr => objectA[attr] == objectB[attr]); -} - -// Tests - -/** - * Tests that adding logins to the database works. - */ -add_task(function test_addLogin_removeLogin() -{ - // Each login from the test data should be valid and added to the list. - for (let loginInfo of TestData.loginList()) { - Services.logins.addLogin(loginInfo); - } - LoginTestUtils.checkLogins(TestData.loginList()); - - // Trying to add each login again should result in an error. - for (let loginInfo of TestData.loginList()) { - Assert.throws(() => Services.logins.addLogin(loginInfo), /already exists/); - } - - // Removing each login should succeed. - for (let loginInfo of TestData.loginList()) { - Services.logins.removeLogin(loginInfo); - } - - LoginTestUtils.checkLogins([]); -}); - -/** - * Tests invalid combinations of httpRealm and formSubmitURL. - * - * For an nsILoginInfo to be valid for storage, one of the two properties should - * be strictly equal to null, and the other must not be null or an empty string. - * - * The legacy case of an empty string in formSubmitURL and a null value in - * httpRealm is also supported for storage at the moment. - */ -add_task(function test_invalid_httpRealm_formSubmitURL() -{ - // httpRealm === null, formSubmitURL === null - checkLoginInvalid(TestData.formLogin({ formSubmitURL: null }), - /without a httpRealm or formSubmitURL/); - - // httpRealm === "", formSubmitURL === null - checkLoginInvalid(TestData.authLogin({ httpRealm: "" }), - /without a httpRealm or formSubmitURL/); - - // httpRealm === null, formSubmitURL === "" - // This is not enforced for now. - // checkLoginInvalid(TestData.formLogin({ formSubmitURL: "" }), - // /without a httpRealm or formSubmitURL/); - - // httpRealm === "", formSubmitURL === "" - checkLoginInvalid(TestData.formLogin({ formSubmitURL: "", httpRealm: "" }), - /both a httpRealm and formSubmitURL/); - - // !!httpRealm, !!formSubmitURL - checkLoginInvalid(TestData.formLogin({ httpRealm: "The HTTP Realm" }), - /both a httpRealm and formSubmitURL/); - - // httpRealm === "", !!formSubmitURL - checkLoginInvalid(TestData.formLogin({ httpRealm: "" }), - /both a httpRealm and formSubmitURL/); - - // !!httpRealm, formSubmitURL === "" - checkLoginInvalid(TestData.authLogin({ formSubmitURL: "" }), - /both a httpRealm and formSubmitURL/); -}); - -/** - * Tests null or empty values in required login properties. - */ -add_task(function test_missing_properties() -{ - checkLoginInvalid(TestData.formLogin({ hostname: null }), - /null or empty hostname/); - - checkLoginInvalid(TestData.formLogin({ hostname: "" }), - /null or empty hostname/); - - checkLoginInvalid(TestData.formLogin({ username: null }), - /null username/); - - checkLoginInvalid(TestData.formLogin({ password: null }), - /null or empty password/); - - checkLoginInvalid(TestData.formLogin({ password: "" }), - /null or empty password/); -}); - -/** - * Tests invalid NUL characters in nsILoginInfo properties. - */ -add_task(function test_invalid_characters() -{ - let loginList = [ - TestData.authLogin({ hostname: "http://null\0X.example.com" }), - TestData.authLogin({ httpRealm: "realm\0" }), - TestData.formLogin({ formSubmitURL: "http://null\0X.example.com" }), - TestData.formLogin({ usernameField: "field\0_null" }), - TestData.formLogin({ usernameField: ".\0" }), // Special single dot case - TestData.formLogin({ passwordField: "field\0_null" }), - TestData.formLogin({ username: "user\0name" }), - TestData.formLogin({ password: "pass\0word" }), - ]; - for (let loginInfo of loginList) { - checkLoginInvalid(loginInfo, /login values can't contain nulls/); - } -}); - -/** - * Tests removing a login that does not exists. - */ -add_task(function test_removeLogin_nonexisting() -{ - Assert.throws(() => Services.logins.removeLogin(TestData.formLogin()), - /No matching logins/); -}); - -/** - * Tests removing all logins at once. - */ -add_task(function test_removeAllLogins() -{ - for (let loginInfo of TestData.loginList()) { - Services.logins.addLogin(loginInfo); - } - Services.logins.removeAllLogins(); - LoginTestUtils.checkLogins([]); - - // The function should also work when there are no logins to delete. - Services.logins.removeAllLogins(); -}); - -/** - * Tests the modifyLogin function with an nsILoginInfo argument. - */ -add_task(function test_modifyLogin_nsILoginInfo() -{ - let loginInfo = TestData.formLogin(); - let updatedLoginInfo = TestData.formLogin({ - username: "new username", - password: "new password", - usernameField: "new_form_field_username", - passwordField: "new_form_field_password", - }); - let differentLoginInfo = TestData.authLogin(); - - // Trying to modify a login that does not exist should throw. - Assert.throws(() => Services.logins.modifyLogin(loginInfo, updatedLoginInfo), - /No matching logins/); - - // Add the first form login, then modify it to match the second. - Services.logins.addLogin(loginInfo); - Services.logins.modifyLogin(loginInfo, updatedLoginInfo); - - // The data should now match the second login. - LoginTestUtils.checkLogins([updatedLoginInfo]); - Assert.throws(() => Services.logins.modifyLogin(loginInfo, updatedLoginInfo), - /No matching logins/); - - // The login can be changed to have a different type and hostname. - Services.logins.modifyLogin(updatedLoginInfo, differentLoginInfo); - LoginTestUtils.checkLogins([differentLoginInfo]); - - // It is now possible to add a login with the old type and hostname. - Services.logins.addLogin(loginInfo); - LoginTestUtils.checkLogins([loginInfo, differentLoginInfo]); - - // Modifying a login to match an existing one should not be possible. - Assert.throws( - () => Services.logins.modifyLogin(loginInfo, differentLoginInfo), - /already exists/); - LoginTestUtils.checkLogins([loginInfo, differentLoginInfo]); - - LoginTestUtils.clearData(); -}); - -/** - * Tests the modifyLogin function with an nsIPropertyBag argument. - */ -add_task(function test_modifyLogin_nsIProperyBag() -{ - let loginInfo = TestData.formLogin(); - let updatedLoginInfo = TestData.formLogin({ - username: "new username", - password: "new password", - usernameField: "", - passwordField: "new_form_field_password", - }); - let differentLoginInfo = TestData.authLogin(); - let differentLoginProperties = newPropertyBag({ - hostname: differentLoginInfo.hostname, - formSubmitURL: differentLoginInfo.formSubmitURL, - httpRealm: differentLoginInfo.httpRealm, - username: differentLoginInfo.username, - password: differentLoginInfo.password, - usernameField: differentLoginInfo.usernameField, - passwordField: differentLoginInfo.passwordField, - }); - - // Trying to modify a login that does not exist should throw. - Assert.throws(() => Services.logins.modifyLogin(loginInfo, newPropertyBag()), - /No matching logins/); - - // Add the first form login, then modify it to match the second, changing - // only some of its properties and checking the behavior with an empty string. - Services.logins.addLogin(loginInfo); - Services.logins.modifyLogin(loginInfo, newPropertyBag({ - username: "new username", - password: "new password", - usernameField: "", - passwordField: "new_form_field_password", - })); - - // The data should now match the second login. - LoginTestUtils.checkLogins([updatedLoginInfo]); - Assert.throws(() => Services.logins.modifyLogin(loginInfo, newPropertyBag()), - /No matching logins/); - - // It is also possible to provide no properties to be modified. - Services.logins.modifyLogin(updatedLoginInfo, newPropertyBag()); - - // Specifying a null property for a required value should throw. - Assert.throws(() => Services.logins.modifyLogin(loginInfo, newPropertyBag({ - usernameField: null, - }))); - - // The login can be changed to have a different type and hostname. - Services.logins.modifyLogin(updatedLoginInfo, differentLoginProperties); - LoginTestUtils.checkLogins([differentLoginInfo]); - - // It is now possible to add a login with the old type and hostname. - Services.logins.addLogin(loginInfo); - LoginTestUtils.checkLogins([loginInfo, differentLoginInfo]); - - // Modifying a login to match an existing one should not be possible. - Assert.throws( - () => Services.logins.modifyLogin(loginInfo, differentLoginProperties), - /already exists/); - LoginTestUtils.checkLogins([loginInfo, differentLoginInfo]); - - LoginTestUtils.clearData(); -}); - -/** - * Tests the login deduplication function. - */ -add_task(function test_deduplicate_logins() { - // Different key attributes combinations and the amount of unique - // results expected for the TestData login list. - let keyCombinations = [ - { - keyset: ["username", "password"], - results: 13, - }, - { - keyset: ["hostname", "username"], - results: 17, - }, - { - keyset: ["hostname", "username", "password"], - results: 18, - }, - { - keyset: ["hostname", "username", "password", "formSubmitURL"], - results: 23, - }, - ]; - - let logins = TestData.loginList(); - - for (let testCase of keyCombinations) { - // Deduplicate the logins using the current testcase keyset. - let deduped = LoginHelper.dedupeLogins(logins, testCase.keyset); - Assert.equal(deduped.length, testCase.results, "Correct amount of results."); - - // Checks that every login after deduping is unique. - Assert.ok(deduped.every(loginA => - deduped.every(loginB => !compareAttributes(loginA, loginB, testCase.keyset)) - ), "Every login is unique."); - } -}); - -/** - * Ensure that the login deduplication function keeps the most recent login. - */ -add_task(function test_deduplicate_keeps_most_recent() { - // Logins to deduplicate. - let logins = [ - TestData.formLogin({timeLastUsed: Date.UTC(2004, 11, 4, 0, 0, 0)}), - TestData.formLogin({formSubmitURL: "http://example.com", timeLastUsed: Date.UTC(2015, 11, 4, 0, 0, 0)}), - ]; - - // Deduplicate the logins. - let deduped = LoginHelper.dedupeLogins(logins); - Assert.equal(deduped.length, 1, "Deduplicated the logins array."); - - // Verify that the remaining login have the most recent date. - let loginTimeLastUsed = deduped[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed; - Assert.equal(loginTimeLastUsed, Date.UTC(2015, 11, 4, 0, 0, 0), "Most recent login was kept."); - - // Deduplicate the reverse logins array. - deduped = LoginHelper.dedupeLogins(logins.reverse()); - Assert.equal(deduped.length, 1, "Deduplicated the reversed logins array."); - - // Verify that the remaining login have the most recent date. - loginTimeLastUsed = deduped[0].QueryInterface(Ci.nsILoginMetaInfo).timeLastUsed; - Assert.equal(loginTimeLastUsed, Date.UTC(2015, 11, 4, 0, 0, 0), "Most recent login was kept."); -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_logins_decrypt_failure.js b/toolkit/components/passwordmgr/test/unit/test_logins_decrypt_failure.js deleted file mode 100644 index ffbedb4de..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_logins_decrypt_failure.js +++ /dev/null @@ -1,77 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests the case where there are logins that cannot be decrypted. - */ - -"use strict"; - -// Globals - -/** - * Resets the token used to decrypt logins. This is equivalent to resetting the - * master password when it is not known. - */ -function resetMasterPassword() -{ - let token = Cc["@mozilla.org/security/pk11tokendb;1"] - .getService(Ci.nsIPK11TokenDB).getInternalKeyToken(); - token.reset(); - token.changePassword("", ""); -} - -// Tests - -/** - * Resets the master password after some logins were added to the database. - */ -add_task(function test_logins_decrypt_failure() -{ - let logins = TestData.loginList(); - for (let loginInfo of logins) { - Services.logins.addLogin(loginInfo); - } - - // This makes the existing logins non-decryptable. - resetMasterPassword(); - - // These functions don't see the non-decryptable entries anymore. - do_check_eq(Services.logins.getAllLogins().length, 0); - do_check_eq(Services.logins.findLogins({}, "", "", "").length, 0); - do_check_eq(Services.logins.searchLogins({}, newPropertyBag()).length, 0); - Assert.throws(() => Services.logins.modifyLogin(logins[0], newPropertyBag()), - /No matching logins/); - Assert.throws(() => Services.logins.removeLogin(logins[0]), - /No matching logins/); - - // The function that counts logins sees the non-decryptable entries also. - do_check_eq(Services.logins.countLogins("", "", ""), logins.length); - - // Equivalent logins can be added. - for (let loginInfo of logins) { - Services.logins.addLogin(loginInfo); - } - LoginTestUtils.checkLogins(logins); - do_check_eq(Services.logins.countLogins("", "", ""), logins.length * 2); - - // Finding logins doesn't return the non-decryptable duplicates. - do_check_eq(Services.logins.findLogins({}, "http://www.example.com", - "", "").length, 1); - let matchData = newPropertyBag({ hostname: "http://www.example.com" }); - do_check_eq(Services.logins.searchLogins({}, matchData).length, 1); - - // Removing single logins does not remove non-decryptable logins. - for (let loginInfo of TestData.loginList()) { - Services.logins.removeLogin(loginInfo); - } - do_check_eq(Services.logins.getAllLogins().length, 0); - do_check_eq(Services.logins.countLogins("", "", ""), logins.length); - - // Removing all logins removes the non-decryptable entries also. - Services.logins.removeAllLogins(); - do_check_eq(Services.logins.getAllLogins().length, 0); - do_check_eq(Services.logins.countLogins("", "", ""), 0); -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js b/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js deleted file mode 100644 index 38344aa7d..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_logins_metainfo.js +++ /dev/null @@ -1,284 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests the handling of nsILoginMetaInfo by methods that add, remove, modify, - * and find logins. - */ - -"use strict"; - -// Globals - -XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator", - "@mozilla.org/uuid-generator;1", - "nsIUUIDGenerator"); - -var gLooksLikeUUIDRegex = /^\{\w{8}-\w{4}-\w{4}-\w{4}-\w{12}\}$/; - -/** - * Retrieves the only login among the current data that matches the hostname of - * the given nsILoginInfo. In case there is more than one login for the - * hostname, the test fails. - */ -function retrieveLoginMatching(aLoginInfo) -{ - let logins = Services.logins.findLogins({}, aLoginInfo.hostname, "", ""); - do_check_eq(logins.length, 1); - return logins[0].QueryInterface(Ci.nsILoginMetaInfo); -} - -/** - * Checks that the nsILoginInfo and nsILoginMetaInfo properties of two different - * login instances are equal. - */ -function assertMetaInfoEqual(aActual, aExpected) -{ - do_check_neq(aActual, aExpected); - - // Check the nsILoginInfo properties. - do_check_true(aActual.equals(aExpected)); - - // Check the nsILoginMetaInfo properties. - do_check_eq(aActual.guid, aExpected.guid); - do_check_eq(aActual.timeCreated, aExpected.timeCreated); - do_check_eq(aActual.timeLastUsed, aExpected.timeLastUsed); - do_check_eq(aActual.timePasswordChanged, aExpected.timePasswordChanged); - do_check_eq(aActual.timesUsed, aExpected.timesUsed); -} - -/** - * nsILoginInfo instances with or without nsILoginMetaInfo properties. - */ -var gLoginInfo1; -var gLoginInfo2; -var gLoginInfo3; - -/** - * nsILoginInfo instances reloaded with all the nsILoginMetaInfo properties. - * These are often used to provide the reference values to test against. - */ -var gLoginMetaInfo1; -var gLoginMetaInfo2; -var gLoginMetaInfo3; - -// Tests - -/** - * Prepare the test objects that will be used by the following tests. - */ -add_task(function test_initialize() -{ - // Use a reference time from ten minutes ago to initialize one instance of - // nsILoginMetaInfo, to test that reference times are updated when needed. - let baseTimeMs = Date.now() - 600000; - - gLoginInfo1 = TestData.formLogin(); - gLoginInfo2 = TestData.formLogin({ - hostname: "http://other.example.com", - guid: gUUIDGenerator.generateUUID().toString(), - timeCreated: baseTimeMs, - timeLastUsed: baseTimeMs + 2, - timePasswordChanged: baseTimeMs + 1, - timesUsed: 2, - }); - gLoginInfo3 = TestData.authLogin(); -}); - -/** - * Tests the behavior of addLogin with regard to metadata. The logins added - * here are also used by the following tests. - */ -add_task(function test_addLogin_metainfo() -{ - // Add a login without metadata to the database. - Services.logins.addLogin(gLoginInfo1); - - // The object provided to addLogin should not have been modified. - do_check_eq(gLoginInfo1.guid, null); - do_check_eq(gLoginInfo1.timeCreated, 0); - do_check_eq(gLoginInfo1.timeLastUsed, 0); - do_check_eq(gLoginInfo1.timePasswordChanged, 0); - do_check_eq(gLoginInfo1.timesUsed, 0); - - // A login with valid metadata should have been stored. - gLoginMetaInfo1 = retrieveLoginMatching(gLoginInfo1); - do_check_true(gLooksLikeUUIDRegex.test(gLoginMetaInfo1.guid)); - let creationTime = gLoginMetaInfo1.timeCreated; - LoginTestUtils.assertTimeIsAboutNow(creationTime); - do_check_eq(gLoginMetaInfo1.timeLastUsed, creationTime); - do_check_eq(gLoginMetaInfo1.timePasswordChanged, creationTime); - do_check_eq(gLoginMetaInfo1.timesUsed, 1); - - // Add a login without metadata to the database. - let originalLogin = gLoginInfo2.clone().QueryInterface(Ci.nsILoginMetaInfo); - Services.logins.addLogin(gLoginInfo2); - - // The object provided to addLogin should not have been modified. - assertMetaInfoEqual(gLoginInfo2, originalLogin); - - // A login with the provided metadata should have been stored. - gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2); - assertMetaInfoEqual(gLoginMetaInfo2, gLoginInfo2); - - // Add an authentication login to the database before continuing. - Services.logins.addLogin(gLoginInfo3); - gLoginMetaInfo3 = retrieveLoginMatching(gLoginInfo3); - LoginTestUtils.checkLogins([gLoginInfo1, gLoginInfo2, gLoginInfo3]); -}); - -/** - * Tests that adding a login with a duplicate GUID throws an exception. - */ -add_task(function test_addLogin_metainfo_duplicate() -{ - let loginInfo = TestData.formLogin({ - hostname: "http://duplicate.example.com", - guid: gLoginMetaInfo2.guid, - }); - Assert.throws(() => Services.logins.addLogin(loginInfo), - /specified GUID already exists/); - - // Verify that no data was stored by the previous call. - LoginTestUtils.checkLogins([gLoginInfo1, gLoginInfo2, gLoginInfo3]); -}); - -/** - * Tests that the existing metadata is not changed when modifyLogin is called - * with an nsILoginInfo argument. - */ -add_task(function test_modifyLogin_nsILoginInfo_metainfo_ignored() -{ - let newLoginInfo = gLoginInfo1.clone().QueryInterface(Ci.nsILoginMetaInfo); - newLoginInfo.guid = gUUIDGenerator.generateUUID().toString(); - newLoginInfo.timeCreated = Date.now(); - newLoginInfo.timeLastUsed = Date.now(); - newLoginInfo.timePasswordChanged = Date.now(); - newLoginInfo.timesUsed = 12; - Services.logins.modifyLogin(gLoginInfo1, newLoginInfo); - - newLoginInfo = retrieveLoginMatching(gLoginInfo1); - assertMetaInfoEqual(newLoginInfo, gLoginMetaInfo1); -}); - -/** - * Tests the modifyLogin function with an nsIProperyBag argument. - */ -add_task(function test_modifyLogin_nsIProperyBag_metainfo() -{ - // Use a new reference time that is two minutes from now. - let newTimeMs = Date.now() + 120000; - let newUUIDValue = gUUIDGenerator.generateUUID().toString(); - - // Check that properties are changed as requested. - Services.logins.modifyLogin(gLoginInfo1, newPropertyBag({ - guid: newUUIDValue, - timeCreated: newTimeMs, - timeLastUsed: newTimeMs + 2, - timePasswordChanged: newTimeMs + 1, - timesUsed: 2, - })); - - gLoginMetaInfo1 = retrieveLoginMatching(gLoginInfo1); - do_check_eq(gLoginMetaInfo1.guid, newUUIDValue); - do_check_eq(gLoginMetaInfo1.timeCreated, newTimeMs); - do_check_eq(gLoginMetaInfo1.timeLastUsed, newTimeMs + 2); - do_check_eq(gLoginMetaInfo1.timePasswordChanged, newTimeMs + 1); - do_check_eq(gLoginMetaInfo1.timesUsed, 2); - - // Check that timePasswordChanged is updated when changing the password. - let originalLogin = gLoginInfo2.clone().QueryInterface(Ci.nsILoginMetaInfo); - Services.logins.modifyLogin(gLoginInfo2, newPropertyBag({ - password: "new password", - })); - gLoginInfo2.password = "new password"; - - gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2); - do_check_eq(gLoginMetaInfo2.password, gLoginInfo2.password); - do_check_eq(gLoginMetaInfo2.timeCreated, originalLogin.timeCreated); - do_check_eq(gLoginMetaInfo2.timeLastUsed, originalLogin.timeLastUsed); - LoginTestUtils.assertTimeIsAboutNow(gLoginMetaInfo2.timePasswordChanged); - - // Check that timePasswordChanged is not set to the current time when changing - // the password and specifying a new value for the property at the same time. - Services.logins.modifyLogin(gLoginInfo2, newPropertyBag({ - password: "other password", - timePasswordChanged: newTimeMs, - })); - gLoginInfo2.password = "other password"; - - gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2); - do_check_eq(gLoginMetaInfo2.password, gLoginInfo2.password); - do_check_eq(gLoginMetaInfo2.timeCreated, originalLogin.timeCreated); - do_check_eq(gLoginMetaInfo2.timeLastUsed, originalLogin.timeLastUsed); - do_check_eq(gLoginMetaInfo2.timePasswordChanged, newTimeMs); - - // Check the special timesUsedIncrement property. - Services.logins.modifyLogin(gLoginInfo2, newPropertyBag({ - timesUsedIncrement: 2, - })); - - gLoginMetaInfo2 = retrieveLoginMatching(gLoginInfo2); - do_check_eq(gLoginMetaInfo2.timeCreated, originalLogin.timeCreated); - do_check_eq(gLoginMetaInfo2.timeLastUsed, originalLogin.timeLastUsed); - do_check_eq(gLoginMetaInfo2.timePasswordChanged, newTimeMs); - do_check_eq(gLoginMetaInfo2.timesUsed, 4); -}); - -/** - * Tests that modifying a login to a duplicate GUID throws an exception. - */ -add_task(function test_modifyLogin_nsIProperyBag_metainfo_duplicate() -{ - Assert.throws(() => Services.logins.modifyLogin(gLoginInfo1, newPropertyBag({ - guid: gLoginInfo2.guid, - })), /specified GUID already exists/); - LoginTestUtils.checkLogins([gLoginInfo1, gLoginInfo2, gLoginInfo3]); -}); - -/** - * Tests searching logins using nsILoginMetaInfo properties. - */ -add_task(function test_searchLogins_metainfo() -{ - // Find by GUID. - let logins = Services.logins.searchLogins({}, newPropertyBag({ - guid: gLoginMetaInfo1.guid, - })); - do_check_eq(logins.length, 1); - let foundLogin = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - assertMetaInfoEqual(foundLogin, gLoginMetaInfo1); - - // Find by timestamp. - logins = Services.logins.searchLogins({}, newPropertyBag({ - timePasswordChanged: gLoginMetaInfo2.timePasswordChanged, - })); - do_check_eq(logins.length, 1); - foundLogin = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - assertMetaInfoEqual(foundLogin, gLoginMetaInfo2); - - // Find using two properties at the same time. - logins = Services.logins.searchLogins({}, newPropertyBag({ - guid: gLoginMetaInfo3.guid, - timePasswordChanged: gLoginMetaInfo3.timePasswordChanged, - })); - do_check_eq(logins.length, 1); - foundLogin = logins[0].QueryInterface(Ci.nsILoginMetaInfo); - assertMetaInfoEqual(foundLogin, gLoginMetaInfo3); -}); - -/** - * Tests that the default nsILoginManagerStorage module attached to the Login - * Manager service is able to save and reload nsILoginMetaInfo properties. - */ -add_task(function* test_storage_metainfo() -{ - yield* LoginTestUtils.reloadData(); - LoginTestUtils.checkLogins([gLoginInfo1, gLoginInfo2, gLoginInfo3]); - - assertMetaInfoEqual(retrieveLoginMatching(gLoginInfo1), gLoginMetaInfo1); - assertMetaInfoEqual(retrieveLoginMatching(gLoginInfo2), gLoginMetaInfo2); - assertMetaInfoEqual(retrieveLoginMatching(gLoginInfo3), gLoginMetaInfo3); -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_logins_search.js b/toolkit/components/passwordmgr/test/unit/test_logins_search.js deleted file mode 100644 index 730771981..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_logins_search.js +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Tests methods that find specific logins in the store (findLogins, - * searchLogins, and countLogins). - * - * The getAllLogins method is not tested explicitly here, because it is used by - * all tests to verify additions, removals and modifications to the login store. - */ - -"use strict"; - -// Globals - -/** - * Returns a list of new nsILoginInfo objects that are a subset of the test - * data, built to match the specified query. - * - * @param aQuery - * Each property and value of this object restricts the search to those - * entries from the test data that match the property exactly. - */ -function buildExpectedLogins(aQuery) -{ - return TestData.loginList().filter( - entry => Object.keys(aQuery).every(name => entry[name] === aQuery[name])); -} - -/** - * Tests the searchLogins function. - * - * @param aQuery - * Each property and value of this object is translated to an entry in - * the nsIPropertyBag parameter of searchLogins. - * @param aExpectedCount - * Number of logins from the test data that should be found. The actual - * list of logins is obtained using the buildExpectedLogins helper, and - * this value is just used to verify that modifications to the test data - * don't make the current test meaningless. - */ -function checkSearchLogins(aQuery, aExpectedCount) -{ - do_print("Testing searchLogins for " + JSON.stringify(aQuery)); - - let expectedLogins = buildExpectedLogins(aQuery); - do_check_eq(expectedLogins.length, aExpectedCount); - - let outCount = {}; - let logins = Services.logins.searchLogins(outCount, newPropertyBag(aQuery)); - do_check_eq(outCount.value, expectedLogins.length); - LoginTestUtils.assertLoginListsEqual(logins, expectedLogins); -} - -/** - * Tests findLogins, searchLogins, and countLogins with the same query. - * - * @param aQuery - * The "hostname", "formSubmitURL", and "httpRealm" properties of this - * object are passed as parameters to findLogins and countLogins. The - * same object is then passed to the checkSearchLogins function. - * @param aExpectedCount - * Number of logins from the test data that should be found. The actual - * list of logins is obtained using the buildExpectedLogins helper, and - * this value is just used to verify that modifications to the test data - * don't make the current test meaningless. - */ -function checkAllSearches(aQuery, aExpectedCount) -{ - do_print("Testing all search functions for " + JSON.stringify(aQuery)); - - let expectedLogins = buildExpectedLogins(aQuery); - do_check_eq(expectedLogins.length, aExpectedCount); - - // The findLogins and countLogins functions support wildcard matches by - // specifying empty strings as parameters, while searchLogins requires - // omitting the property entirely. - let hostname = ("hostname" in aQuery) ? aQuery.hostname : ""; - let formSubmitURL = ("formSubmitURL" in aQuery) ? aQuery.formSubmitURL : ""; - let httpRealm = ("httpRealm" in aQuery) ? aQuery.httpRealm : ""; - - // Test findLogins. - let outCount = {}; - let logins = Services.logins.findLogins(outCount, hostname, formSubmitURL, - httpRealm); - do_check_eq(outCount.value, expectedLogins.length); - LoginTestUtils.assertLoginListsEqual(logins, expectedLogins); - - // Test countLogins. - let count = Services.logins.countLogins(hostname, formSubmitURL, httpRealm); - do_check_eq(count, expectedLogins.length); - - // Test searchLogins. - checkSearchLogins(aQuery, aExpectedCount); -} - -// Tests - -/** - * Prepare data for the following tests. - */ -add_task(function test_initialize() -{ - for (let login of TestData.loginList()) { - Services.logins.addLogin(login); - } -}); - -/** - * Tests findLogins, searchLogins, and countLogins with basic queries. - */ -add_task(function test_search_all_basic() -{ - // Find all logins, using no filters in the search functions. - checkAllSearches({}, 23); - - // Find all form logins, then all authentication logins. - checkAllSearches({ httpRealm: null }, 14); - checkAllSearches({ formSubmitURL: null }, 9); - - // Find all form logins on one host, then all authentication logins. - checkAllSearches({ hostname: "http://www4.example.com", - httpRealm: null }, 3); - checkAllSearches({ hostname: "http://www2.example.org", - formSubmitURL: null }, 2); - - // Verify that scheme and subdomain are distinct in the hostname. - checkAllSearches({ hostname: "http://www.example.com" }, 1); - checkAllSearches({ hostname: "https://www.example.com" }, 1); - checkAllSearches({ hostname: "https://example.com" }, 1); - checkAllSearches({ hostname: "http://www3.example.com" }, 3); - - // Verify that scheme and subdomain are distinct in formSubmitURL. - checkAllSearches({ formSubmitURL: "http://www.example.com" }, 2); - checkAllSearches({ formSubmitURL: "https://www.example.com" }, 2); - checkAllSearches({ formSubmitURL: "http://example.com" }, 1); - - // Find by formSubmitURL on a single host. - checkAllSearches({ hostname: "http://www3.example.com", - formSubmitURL: "http://www.example.com" }, 1); - checkAllSearches({ hostname: "http://www3.example.com", - formSubmitURL: "https://www.example.com" }, 1); - checkAllSearches({ hostname: "http://www3.example.com", - formSubmitURL: "http://example.com" }, 1); - - // Find by httpRealm on all hosts. - checkAllSearches({ httpRealm: "The HTTP Realm" }, 3); - checkAllSearches({ httpRealm: "ftp://ftp.example.org" }, 1); - checkAllSearches({ httpRealm: "The HTTP Realm Other" }, 2); - - // Find by httpRealm on a single host. - checkAllSearches({ hostname: "http://example.net", - httpRealm: "The HTTP Realm" }, 1); - checkAllSearches({ hostname: "http://example.net", - httpRealm: "The HTTP Realm Other" }, 1); - checkAllSearches({ hostname: "ftp://example.net", - httpRealm: "ftp://example.net" }, 1); -}); - -/** - * Tests searchLogins with advanced queries. - */ -add_task(function test_searchLogins() -{ - checkSearchLogins({ usernameField: "form_field_username" }, 12); - checkSearchLogins({ passwordField: "form_field_password" }, 13); - - // Find all logins with an empty usernameField, including for authentication. - checkSearchLogins({ usernameField: "" }, 11); - - // Find form logins with an empty usernameField. - checkSearchLogins({ httpRealm: null, - usernameField: "" }, 2); - - // Find logins with an empty usernameField on one host. - checkSearchLogins({ hostname: "http://www6.example.com", - usernameField: "" }, 1); -}); - -/** - * Tests searchLogins with invalid arguments. - */ -add_task(function test_searchLogins_invalid() -{ - Assert.throws(() => Services.logins.searchLogins({}, - newPropertyBag({ username: "value" })), - /Unexpected field/); -}); - -/** - * Tests that matches are case-sensitive, compare the full field value, and are - * strict when interpreting the prePath of URIs. - */ -add_task(function test_search_all_full_case_sensitive() -{ - checkAllSearches({ hostname: "http://www.example.com" }, 1); - checkAllSearches({ hostname: "http://www.example.com/" }, 0); - checkAllSearches({ hostname: "example.com" }, 0); - - checkAllSearches({ formSubmitURL: "http://www.example.com" }, 2); - checkAllSearches({ formSubmitURL: "http://www.example.com/" }, 0); - checkAllSearches({ formSubmitURL: "http://" }, 0); - checkAllSearches({ formSubmitURL: "example.com" }, 0); - - checkAllSearches({ httpRealm: "The HTTP Realm" }, 3); - checkAllSearches({ httpRealm: "The http Realm" }, 0); - checkAllSearches({ httpRealm: "The HTTP" }, 0); - checkAllSearches({ httpRealm: "Realm" }, 0); -}); - -/** - * Tests findLogins, searchLogins, and countLogins with queries that should - * return no values. - */ -add_task(function test_search_all_empty() -{ - checkAllSearches({ hostname: "http://nonexistent.example.com" }, 0); - checkAllSearches({ formSubmitURL: "http://www.example.com", - httpRealm: "The HTTP Realm" }, 0); - - checkSearchLogins({ hostname: "" }, 0); - checkSearchLogins({ id: "1000" }, 0); -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_maybeImportLogin.js b/toolkit/components/passwordmgr/test/unit/test_maybeImportLogin.js deleted file mode 100644 index 19175df59..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_maybeImportLogin.js +++ /dev/null @@ -1,169 +0,0 @@ -"use strict"; - -Cu.import("resource://gre/modules/Services.jsm"); -Cu.import("resource://gre/modules/LoginHelper.jsm"); - -const HOST1 = "https://www.example.com/"; -const HOST2 = "https://www.mozilla.org/"; - -const USER1 = "myuser"; -const USER2 = "anotheruser"; - -const PASS1 = "mypass"; -const PASS2 = "anotherpass"; -const PASS3 = "yetanotherpass"; - -add_task(function test_new_logins() { - let importedLogin = LoginHelper.maybeImportLogin({ - username: USER1, - password: PASS1, - hostname: HOST1, - formSubmitURL: HOST1, - }); - Assert.ok(importedLogin, "Return value should indicate imported login."); - let matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 1, `There should be 1 login for ${HOST1}`); - - importedLogin = LoginHelper.maybeImportLogin({ - username: USER1, - password: PASS1, - hostname: HOST2, - formSubmitURL: HOST2, - }); - - Assert.ok(importedLogin, "Return value should indicate another imported login."); - matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 1, `There should still be 1 login for ${HOST1}`); - - matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST2}); - Assert.equal(matchingLogins.length, 1, `There should also be 1 login for ${HOST2}`); - Assert.equal(Services.logins.getAllLogins().length, 2, "There should be 2 logins in total"); - Services.logins.removeAllLogins(); -}); - -add_task(function test_duplicate_logins() { - let importedLogin = LoginHelper.maybeImportLogin({ - username: USER1, - password: PASS1, - hostname: HOST1, - formSubmitURL: HOST1, - }); - Assert.ok(importedLogin, "Return value should indicate imported login."); - let matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 1, `There should be 1 login for ${HOST1}`); - - importedLogin = LoginHelper.maybeImportLogin({ - username: USER1, - password: PASS1, - hostname: HOST1, - formSubmitURL: HOST1, - }); - Assert.ok(!importedLogin, "Return value should indicate no new login was imported."); - matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 1, `There should still be 1 login for ${HOST1}`); - Services.logins.removeAllLogins(); -}); - -add_task(function test_different_passwords() { - let importedLogin = LoginHelper.maybeImportLogin({ - username: USER1, - password: PASS1, - hostname: HOST1, - formSubmitURL: HOST1, - timeCreated: new Date(Date.now() - 1000), - }); - Assert.ok(importedLogin, "Return value should indicate imported login."); - let matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 1, `There should be 1 login for ${HOST1}`); - - // This item will be newer, so its password should take precedence. - importedLogin = LoginHelper.maybeImportLogin({ - username: USER1, - password: PASS2, - hostname: HOST1, - formSubmitURL: HOST1, - timeCreated: new Date(), - }); - Assert.ok(!importedLogin, "Return value should not indicate imported login (as we updated an existing one)."); - matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 1, `There should still be 1 login for ${HOST1}`); - Assert.equal(matchingLogins[0].password, PASS2, "We should have updated the password for this login."); - - // Now try to update with an older password: - importedLogin = LoginHelper.maybeImportLogin({ - username: USER1, - password: PASS3, - hostname: HOST1, - formSubmitURL: HOST1, - timeCreated: new Date(Date.now() - 1000000), - }); - Assert.ok(!importedLogin, "Return value should not indicate imported login (as we didn't update anything)."); - matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 1, `There should still be 1 login for ${HOST1}`); - Assert.equal(matchingLogins[0].password, PASS2, "We should NOT have updated the password for this login."); - - Services.logins.removeAllLogins(); -}); - -add_task(function test_different_usernames() { - let importedLogin = LoginHelper.maybeImportLogin({ - username: USER1, - password: PASS1, - hostname: HOST1, - formSubmitURL: HOST1, - }); - Assert.ok(importedLogin, "Return value should indicate imported login."); - let matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 1, `There should be 1 login for ${HOST1}`); - - importedLogin = LoginHelper.maybeImportLogin({ - username: USER2, - password: PASS1, - hostname: HOST1, - formSubmitURL: HOST1, - }); - Assert.ok(importedLogin, "Return value should indicate another imported login."); - matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 2, `There should now be 2 logins for ${HOST1}`); - - Services.logins.removeAllLogins(); -}); - -add_task(function test_different_targets() { - let importedLogin = LoginHelper.maybeImportLogin({ - username: USER1, - password: PASS1, - hostname: HOST1, - formSubmitURL: HOST1, - }); - Assert.ok(importedLogin, "Return value should indicate imported login."); - let matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 1, `There should be 1 login for ${HOST1}`); - - // Not passing either a formSubmitURL or a httpRealm should be treated as - // the same as the previous login - importedLogin = LoginHelper.maybeImportLogin({ - username: USER1, - password: PASS1, - hostname: HOST1, - }); - Assert.ok(!importedLogin, "Return value should NOT indicate imported login " + - "(because a missing formSubmitURL and httpRealm should be duped to the existing login)."); - matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 1, `There should still be 1 login for ${HOST1}`); - Assert.equal(matchingLogins[0].formSubmitURL, HOST1, "The form submission URL should have been kept."); - - importedLogin = LoginHelper.maybeImportLogin({ - username: USER1, - password: PASS1, - hostname: HOST1, - httpRealm: HOST1, - }); - Assert.ok(importedLogin, "Return value should indicate another imported login " + - "as an httpRealm login shouldn't be duped."); - matchingLogins = LoginHelper.searchLoginsWithObject({hostname: HOST1}); - Assert.equal(matchingLogins.length, 2, `There should now be 2 logins for ${HOST1}`); - - Services.logins.removeAllLogins(); -}); - diff --git a/toolkit/components/passwordmgr/test/unit/test_module_LoginImport.js b/toolkit/components/passwordmgr/test/unit/test_module_LoginImport.js deleted file mode 100644 index b8793e1bd..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_module_LoginImport.js +++ /dev/null @@ -1,243 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests the LoginImport object. - */ - -"use strict"; - -// Globals - -Cu.import("resource://gre/modules/Task.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper", - "resource://gre/modules/LoginHelper.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "LoginImport", - "resource://gre/modules/LoginImport.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "LoginStore", - "resource://gre/modules/LoginStore.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Sqlite", - "resource://gre/modules/Sqlite.jsm"); - -XPCOMUtils.defineLazyServiceGetter(this, "gLoginManagerCrypto", - "@mozilla.org/login-manager/crypto/SDR;1", - "nsILoginManagerCrypto"); -XPCOMUtils.defineLazyServiceGetter(this, "gUUIDGenerator", - "@mozilla.org/uuid-generator;1", - "nsIUUIDGenerator"); - -/** - * Creates empty login data tables in the given SQLite connection, resembling - * the most recent schema version (excluding indices). - */ -function promiseCreateDatabaseSchema(aConnection) -{ - return Task.spawn(function* () { - yield aConnection.setSchemaVersion(5); - yield aConnection.execute("CREATE TABLE moz_logins (" + - "id INTEGER PRIMARY KEY," + - "hostname TEXT NOT NULL," + - "httpRealm TEXT," + - "formSubmitURL TEXT," + - "usernameField TEXT NOT NULL," + - "passwordField TEXT NOT NULL," + - "encryptedUsername TEXT NOT NULL," + - "encryptedPassword TEXT NOT NULL," + - "guid TEXT," + - "encType INTEGER," + - "timeCreated INTEGER," + - "timeLastUsed INTEGER," + - "timePasswordChanged INTEGER," + - "timesUsed INTEGER)"); - yield aConnection.execute("CREATE TABLE moz_disabledHosts (" + - "id INTEGER PRIMARY KEY," + - "hostname TEXT UNIQUE)"); - yield aConnection.execute("CREATE TABLE moz_deleted_logins (" + - "id INTEGER PRIMARY KEY," + - "guid TEXT," + - "timeDeleted INTEGER)"); - }); -} - -/** - * Inserts a new entry in the database resembling the given nsILoginInfo object. - */ -function promiseInsertLoginInfo(aConnection, aLoginInfo) -{ - aLoginInfo.QueryInterface(Ci.nsILoginMetaInfo); - - // We can't use the aLoginInfo object directly in the execute statement - // because the bind code in Sqlite.jsm doesn't allow objects with extra - // properties beyond those being binded. So we might as well use an array as - // it is simpler. - let values = [ - aLoginInfo.hostname, - aLoginInfo.httpRealm, - aLoginInfo.formSubmitURL, - aLoginInfo.usernameField, - aLoginInfo.passwordField, - gLoginManagerCrypto.encrypt(aLoginInfo.username), - gLoginManagerCrypto.encrypt(aLoginInfo.password), - aLoginInfo.guid, - aLoginInfo.encType, - aLoginInfo.timeCreated, - aLoginInfo.timeLastUsed, - aLoginInfo.timePasswordChanged, - aLoginInfo.timesUsed, - ]; - - return aConnection.execute("INSERT INTO moz_logins (hostname, " + - "httpRealm, formSubmitURL, usernameField, " + - "passwordField, encryptedUsername, " + - "encryptedPassword, guid, encType, timeCreated, " + - "timeLastUsed, timePasswordChanged, timesUsed) " + - "VALUES (?" + ",?".repeat(12) + ")", values); -} - -/** - * Inserts a new disabled host entry in the database. - */ -function promiseInsertDisabledHost(aConnection, aHostname) -{ - return aConnection.execute("INSERT INTO moz_disabledHosts (hostname) " + - "VALUES (?)", [aHostname]); -} - -// Tests - -/** - * Imports login data from a SQLite file constructed using the test data. - */ -add_task(function* test_import() -{ - let store = new LoginStore(getTempFile("test-import.json").path); - let loginsSqlite = getTempFile("test-logins.sqlite").path; - - // Prepare the logins to be imported, including the nsILoginMetaInfo data. - let loginList = TestData.loginList(); - for (let loginInfo of loginList) { - loginInfo.QueryInterface(Ci.nsILoginMetaInfo); - loginInfo.guid = gUUIDGenerator.generateUUID().toString(); - loginInfo.timeCreated = Date.now(); - loginInfo.timeLastUsed = Date.now(); - loginInfo.timePasswordChanged = Date.now(); - loginInfo.timesUsed = 1; - } - - // Create and populate the SQLite database first. - let connection = yield Sqlite.openConnection({ path: loginsSqlite }); - try { - yield promiseCreateDatabaseSchema(connection); - for (let loginInfo of loginList) { - yield promiseInsertLoginInfo(connection, loginInfo); - } - yield promiseInsertDisabledHost(connection, "http://www.example.com"); - yield promiseInsertDisabledHost(connection, "https://www.example.org"); - } finally { - yield connection.close(); - } - - // The "load" method must be called before importing data. - yield store.load(); - yield new LoginImport(store, loginsSqlite).import(); - - // Verify that every login in the test data has a matching imported row. - do_check_eq(loginList.length, store.data.logins.length); - do_check_true(loginList.every(function (loginInfo) { - return store.data.logins.some(function (loginDataItem) { - let username = gLoginManagerCrypto.decrypt(loginDataItem.encryptedUsername); - let password = gLoginManagerCrypto.decrypt(loginDataItem.encryptedPassword); - return loginDataItem.hostname == loginInfo.hostname && - loginDataItem.httpRealm == loginInfo.httpRealm && - loginDataItem.formSubmitURL == loginInfo.formSubmitURL && - loginDataItem.usernameField == loginInfo.usernameField && - loginDataItem.passwordField == loginInfo.passwordField && - username == loginInfo.username && - password == loginInfo.password && - loginDataItem.guid == loginInfo.guid && - loginDataItem.encType == loginInfo.encType && - loginDataItem.timeCreated == loginInfo.timeCreated && - loginDataItem.timeLastUsed == loginInfo.timeLastUsed && - loginDataItem.timePasswordChanged == loginInfo.timePasswordChanged && - loginDataItem.timesUsed == loginInfo.timesUsed; - }); - })); - - // Verify that disabled hosts have been imported. - do_check_eq(store.data.disabledHosts.length, 2); - do_check_true(store.data.disabledHosts.indexOf("http://www.example.com") != -1); - do_check_true(store.data.disabledHosts.indexOf("https://www.example.org") != -1); -}); - -/** - * Tests imports of NULL values due to a downgraded database. - */ -add_task(function* test_import_downgraded() -{ - let store = new LoginStore(getTempFile("test-import-downgraded.json").path); - let loginsSqlite = getTempFile("test-logins-downgraded.sqlite").path; - - // Create and populate the SQLite database first. - let connection = yield Sqlite.openConnection({ path: loginsSqlite }); - try { - yield promiseCreateDatabaseSchema(connection); - yield connection.setSchemaVersion(3); - yield promiseInsertLoginInfo(connection, TestData.formLogin({ - guid: gUUIDGenerator.generateUUID().toString(), - timeCreated: null, - timeLastUsed: null, - timePasswordChanged: null, - timesUsed: 0, - })); - } finally { - yield connection.close(); - } - - // The "load" method must be called before importing data. - yield store.load(); - yield new LoginImport(store, loginsSqlite).import(); - - // Verify that the missing metadata was generated correctly. - let loginItem = store.data.logins[0]; - let creationTime = loginItem.timeCreated; - LoginTestUtils.assertTimeIsAboutNow(creationTime); - do_check_eq(loginItem.timeLastUsed, creationTime); - do_check_eq(loginItem.timePasswordChanged, creationTime); - do_check_eq(loginItem.timesUsed, 1); -}); - -/** - * Verifies that importing from a SQLite file with database version 2 fails. - */ -add_task(function* test_import_v2() -{ - let store = new LoginStore(getTempFile("test-import-v2.json").path); - let loginsSqlite = do_get_file("data/signons-v2.sqlite").path; - - // The "load" method must be called before importing data. - yield store.load(); - try { - yield new LoginImport(store, loginsSqlite).import(); - do_throw("The operation should have failed."); - } catch (ex) { } -}); - -/** - * Imports login data from a SQLite file, with database version 3. - */ -add_task(function* test_import_v3() -{ - let store = new LoginStore(getTempFile("test-import-v3.json").path); - let loginsSqlite = do_get_file("data/signons-v3.sqlite").path; - - // The "load" method must be called before importing data. - yield store.load(); - yield new LoginImport(store, loginsSqlite).import(); - - // We only execute basic integrity checks. - do_check_eq(store.data.logins[0].usernameField, "u1"); - do_check_eq(store.data.disabledHosts.length, 0); -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_module_LoginStore.js b/toolkit/components/passwordmgr/test/unit/test_module_LoginStore.js deleted file mode 100644 index 335eb601b..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_module_LoginStore.js +++ /dev/null @@ -1,206 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests the LoginStore object. - */ - -"use strict"; - -// Globals - -XPCOMUtils.defineLazyModuleGetter(this, "LoginStore", - "resource://gre/modules/LoginStore.jsm"); - -const TEST_STORE_FILE_NAME = "test-logins.json"; - -// Tests - -/** - * Saves login data to a file, then reloads it. - */ -add_task(function* test_save_reload() -{ - let storeForSave = new LoginStore(getTempFile(TEST_STORE_FILE_NAME).path); - - // The "load" method must be called before preparing the data to be saved. - yield storeForSave.load(); - - let rawLoginData = { - id: storeForSave.data.nextId++, - hostname: "http://www.example.com", - httpRealm: null, - formSubmitURL: "http://www.example.com/submit-url", - usernameField: "field_" + String.fromCharCode(533, 537, 7570, 345), - passwordField: "field_" + String.fromCharCode(421, 259, 349, 537), - encryptedUsername: "(test)", - encryptedPassword: "(test)", - guid: "(test)", - encType: Ci.nsILoginManagerCrypto.ENCTYPE_SDR, - timeCreated: Date.now(), - timeLastUsed: Date.now(), - timePasswordChanged: Date.now(), - timesUsed: 1, - }; - storeForSave.data.logins.push(rawLoginData); - - storeForSave.data.disabledHosts.push("http://www.example.org"); - - yield storeForSave._save(); - - // Test the asynchronous initialization path. - let storeForLoad = new LoginStore(storeForSave.path); - yield storeForLoad.load(); - - do_check_eq(storeForLoad.data.logins.length, 1); - do_check_matches(storeForLoad.data.logins[0], rawLoginData); - do_check_eq(storeForLoad.data.disabledHosts.length, 1); - do_check_eq(storeForLoad.data.disabledHosts[0], "http://www.example.org"); - - // Test the synchronous initialization path. - storeForLoad = new LoginStore(storeForSave.path); - storeForLoad.ensureDataReady(); - - do_check_eq(storeForLoad.data.logins.length, 1); - do_check_matches(storeForLoad.data.logins[0], rawLoginData); - do_check_eq(storeForLoad.data.disabledHosts.length, 1); - do_check_eq(storeForLoad.data.disabledHosts[0], "http://www.example.org"); -}); - -/** - * Checks that loading from a missing file results in empty arrays. - */ -add_task(function* test_load_empty() -{ - let store = new LoginStore(getTempFile(TEST_STORE_FILE_NAME).path); - - do_check_false(yield OS.File.exists(store.path)); - - yield store.load(); - - do_check_false(yield OS.File.exists(store.path)); - - do_check_eq(store.data.logins.length, 0); - do_check_eq(store.data.disabledHosts.length, 0); -}); - -/** - * Checks that saving empty data still overwrites any existing file. - */ -add_task(function* test_save_empty() -{ - let store = new LoginStore(getTempFile(TEST_STORE_FILE_NAME).path); - - yield store.load(); - - let createdFile = yield OS.File.open(store.path, { create: true }); - yield createdFile.close(); - - yield store._save(); - - do_check_true(yield OS.File.exists(store.path)); -}); - -/** - * Loads data from a string in a predefined format. The purpose of this test is - * to verify that the JSON format used in previous versions can be loaded. - */ -add_task(function* test_load_string_predefined() -{ - let store = new LoginStore(getTempFile(TEST_STORE_FILE_NAME).path); - - let string = "{\"logins\":[{" + - "\"id\":1," + - "\"hostname\":\"http://www.example.com\"," + - "\"httpRealm\":null," + - "\"formSubmitURL\":\"http://www.example.com/submit-url\"," + - "\"usernameField\":\"usernameField\"," + - "\"passwordField\":\"passwordField\"," + - "\"encryptedUsername\":\"(test)\"," + - "\"encryptedPassword\":\"(test)\"," + - "\"guid\":\"(test)\"," + - "\"encType\":1," + - "\"timeCreated\":1262304000000," + - "\"timeLastUsed\":1262390400000," + - "\"timePasswordChanged\":1262476800000," + - "\"timesUsed\":1}],\"disabledHosts\":[" + - "\"http://www.example.org\"]}"; - - yield OS.File.writeAtomic(store.path, - new TextEncoder().encode(string), - { tmpPath: store.path + ".tmp" }); - - yield store.load(); - - do_check_eq(store.data.logins.length, 1); - do_check_matches(store.data.logins[0], { - id: 1, - hostname: "http://www.example.com", - httpRealm: null, - formSubmitURL: "http://www.example.com/submit-url", - usernameField: "usernameField", - passwordField: "passwordField", - encryptedUsername: "(test)", - encryptedPassword: "(test)", - guid: "(test)", - encType: Ci.nsILoginManagerCrypto.ENCTYPE_SDR, - timeCreated: 1262304000000, - timeLastUsed: 1262390400000, - timePasswordChanged: 1262476800000, - timesUsed: 1, - }); - - do_check_eq(store.data.disabledHosts.length, 1); - do_check_eq(store.data.disabledHosts[0], "http://www.example.org"); -}); - -/** - * Loads login data from a malformed JSON string. - */ -add_task(function* test_load_string_malformed() -{ - let store = new LoginStore(getTempFile(TEST_STORE_FILE_NAME).path); - - let string = "{\"logins\":[{\"hostname\":\"http://www.example.com\"," + - "\"id\":1,"; - - yield OS.File.writeAtomic(store.path, new TextEncoder().encode(string), - { tmpPath: store.path + ".tmp" }); - - yield store.load(); - - // A backup file should have been created. - do_check_true(yield OS.File.exists(store.path + ".corrupt")); - yield OS.File.remove(store.path + ".corrupt"); - - // The store should be ready to accept new data. - do_check_eq(store.data.logins.length, 0); - do_check_eq(store.data.disabledHosts.length, 0); -}); - -/** - * Loads login data from a malformed JSON string, using the synchronous - * initialization path. - */ -add_task(function* test_load_string_malformed_sync() -{ - let store = new LoginStore(getTempFile(TEST_STORE_FILE_NAME).path); - - let string = "{\"logins\":[{\"hostname\":\"http://www.example.com\"," + - "\"id\":1,"; - - yield OS.File.writeAtomic(store.path, new TextEncoder().encode(string), - { tmpPath: store.path + ".tmp" }); - - store.ensureDataReady(); - - // A backup file should have been created. - do_check_true(yield OS.File.exists(store.path + ".corrupt")); - yield OS.File.remove(store.path + ".corrupt"); - - // The store should be ready to accept new data. - do_check_eq(store.data.logins.length, 0); - do_check_eq(store.data.disabledHosts.length, 0); -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_notifications.js b/toolkit/components/passwordmgr/test/unit/test_notifications.js deleted file mode 100644 index 41caa2c1b..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_notifications.js +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Tests notifications dispatched when modifying stored logins. - */ - -var expectedNotification; -var expectedData; - -var TestObserver = { - QueryInterface : XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsISupportsWeakReference]), - - observe : function (subject, topic, data) { - do_check_eq(topic, "passwordmgr-storage-changed"); - do_check_eq(data, expectedNotification); - - switch (data) { - case "addLogin": - do_check_true(subject instanceof Ci.nsILoginInfo); - do_check_true(subject instanceof Ci.nsILoginMetaInfo); - do_check_true(expectedData.equals(subject)); // nsILoginInfo.equals() - break; - case "modifyLogin": - do_check_true(subject instanceof Ci.nsIArray); - do_check_eq(subject.length, 2); - var oldLogin = subject.queryElementAt(0, Ci.nsILoginInfo); - var newLogin = subject.queryElementAt(1, Ci.nsILoginInfo); - do_check_true(expectedData[0].equals(oldLogin)); // nsILoginInfo.equals() - do_check_true(expectedData[1].equals(newLogin)); - break; - case "removeLogin": - do_check_true(subject instanceof Ci.nsILoginInfo); - do_check_true(subject instanceof Ci.nsILoginMetaInfo); - do_check_true(expectedData.equals(subject)); // nsILoginInfo.equals() - break; - case "removeAllLogins": - do_check_eq(subject, null); - break; - case "hostSavingEnabled": - case "hostSavingDisabled": - do_check_true(subject instanceof Ci.nsISupportsString); - do_check_eq(subject.data, expectedData); - break; - default: - do_throw("Unhandled notification: " + data + " / " + topic); - } - - expectedNotification = null; // ensure a duplicate is flagged as unexpected. - expectedData = null; - } -}; - -add_task(function test_notifications() -{ - -try { - -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 testuser2 = new LoginInfo("http://testhost2", "", null, - "dummydude2", "itsasecret2", "put_user2_here", "put_pw2_here"); - -Services.obs.addObserver(TestObserver, "passwordmgr-storage-changed", false); - - -/* ========== 1 ========== */ -testnum = 1; -testdesc = "Initial connection to storage module"; - -/* ========== 2 ========== */ -testnum++; -testdesc = "addLogin"; - -expectedNotification = "addLogin"; -expectedData = testuser1; -Services.logins.addLogin(testuser1); -LoginTestUtils.checkLogins([testuser1]); -do_check_eq(expectedNotification, null); // check that observer got a notification - -/* ========== 3 ========== */ -testnum++; -testdesc = "modifyLogin"; - -expectedNotification = "modifyLogin"; -expectedData = [testuser1, testuser2]; -Services.logins.modifyLogin(testuser1, testuser2); -do_check_eq(expectedNotification, null); -LoginTestUtils.checkLogins([testuser2]); - -/* ========== 4 ========== */ -testnum++; -testdesc = "removeLogin"; - -expectedNotification = "removeLogin"; -expectedData = testuser2; -Services.logins.removeLogin(testuser2); -do_check_eq(expectedNotification, null); -LoginTestUtils.checkLogins([]); - -/* ========== 5 ========== */ -testnum++; -testdesc = "removeAllLogins"; - -expectedNotification = "removeAllLogins"; -expectedData = null; -Services.logins.removeAllLogins(); -do_check_eq(expectedNotification, null); -LoginTestUtils.checkLogins([]); - -/* ========== 6 ========== */ -testnum++; -testdesc = "removeAllLogins (again)"; - -expectedNotification = "removeAllLogins"; -expectedData = null; -Services.logins.removeAllLogins(); -do_check_eq(expectedNotification, null); -LoginTestUtils.checkLogins([]); - -/* ========== 7 ========== */ -testnum++; -testdesc = "setLoginSavingEnabled / false"; - -expectedNotification = "hostSavingDisabled"; -expectedData = "http://site.com"; -Services.logins.setLoginSavingEnabled("http://site.com", false); -do_check_eq(expectedNotification, null); -LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), - ["http://site.com"]); - -/* ========== 8 ========== */ -testnum++; -testdesc = "setLoginSavingEnabled / false (again)"; - -expectedNotification = "hostSavingDisabled"; -expectedData = "http://site.com"; -Services.logins.setLoginSavingEnabled("http://site.com", false); -do_check_eq(expectedNotification, null); -LoginTestUtils.assertDisabledHostsEqual(Services.logins.getAllDisabledHosts(), - ["http://site.com"]); - -/* ========== 9 ========== */ -testnum++; -testdesc = "setLoginSavingEnabled / true"; - -expectedNotification = "hostSavingEnabled"; -expectedData = "http://site.com"; -Services.logins.setLoginSavingEnabled("http://site.com", true); -do_check_eq(expectedNotification, null); -LoginTestUtils.checkLogins([]); - -/* ========== 10 ========== */ -testnum++; -testdesc = "setLoginSavingEnabled / true (again)"; - -expectedNotification = "hostSavingEnabled"; -expectedData = "http://site.com"; -Services.logins.setLoginSavingEnabled("http://site.com", true); -do_check_eq(expectedNotification, null); -LoginTestUtils.checkLogins([]); - -Services.obs.removeObserver(TestObserver, "passwordmgr-storage-changed"); - -LoginTestUtils.clearData(); - -} catch (e) { - throw new Error("FAILED in test #" + testnum + " -- " + testdesc + ": " + e); -} - -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_recipes_add.js b/toolkit/components/passwordmgr/test/unit/test_recipes_add.js deleted file mode 100644 index ef5086c3b..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_recipes_add.js +++ /dev/null @@ -1,177 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests adding and retrieving LoginRecipes in the parent process. - */ - -"use strict"; - -add_task(function* test_init() { - let parent = new LoginRecipesParent({ defaults: null }); - let initPromise1 = parent.initializationPromise; - let initPromise2 = parent.initializationPromise; - Assert.strictEqual(initPromise1, initPromise2, "Check that the same promise is returned"); - - let recipesParent = yield initPromise1; - Assert.ok(recipesParent instanceof LoginRecipesParent, "Check init return value"); - Assert.strictEqual(recipesParent._recipesByHost.size, 0, "Initially 0 recipes"); -}); - -add_task(function* test_get_missing_host() { - let recipesParent = yield RecipeHelpers.initNewParent(); - let exampleRecipes = recipesParent.getRecipesForHost("example.invalid"); - Assert.strictEqual(exampleRecipes.size, 0, "Check recipe count for example.invalid"); - -}); - -add_task(function* test_add_get_simple_host() { - let recipesParent = yield RecipeHelpers.initNewParent(); - Assert.strictEqual(recipesParent._recipesByHost.size, 0, "Initially 0 recipes"); - recipesParent.add({ - hosts: ["example.com"], - }); - Assert.strictEqual(recipesParent._recipesByHost.size, 1, - "Check number of hosts after the addition"); - - let exampleRecipes = recipesParent.getRecipesForHost("example.com"); - Assert.strictEqual(exampleRecipes.size, 1, "Check recipe count for example.com"); - let recipe = [...exampleRecipes][0]; - Assert.strictEqual(typeof(recipe), "object", "Check recipe type"); - Assert.strictEqual(recipe.hosts.length, 1, "Check that one host is present"); - Assert.strictEqual(recipe.hosts[0], "example.com", "Check the one host"); -}); - -add_task(function* test_add_get_non_standard_port_host() { - let recipesParent = yield RecipeHelpers.initNewParent(); - recipesParent.add({ - hosts: ["example.com:8080"], - }); - Assert.strictEqual(recipesParent._recipesByHost.size, 1, - "Check number of hosts after the addition"); - - let exampleRecipes = recipesParent.getRecipesForHost("example.com:8080"); - Assert.strictEqual(exampleRecipes.size, 1, "Check recipe count for example.com:8080"); - let recipe = [...exampleRecipes][0]; - Assert.strictEqual(typeof(recipe), "object", "Check recipe type"); - Assert.strictEqual(recipe.hosts.length, 1, "Check that one host is present"); - Assert.strictEqual(recipe.hosts[0], "example.com:8080", "Check the one host"); -}); - -add_task(function* test_add_multiple_hosts() { - let recipesParent = yield RecipeHelpers.initNewParent(); - recipesParent.add({ - hosts: ["example.com", "foo.invalid"], - }); - Assert.strictEqual(recipesParent._recipesByHost.size, 2, - "Check number of hosts after the addition"); - - let exampleRecipes = recipesParent.getRecipesForHost("example.com"); - Assert.strictEqual(exampleRecipes.size, 1, "Check recipe count for example.com"); - let recipe = [...exampleRecipes][0]; - Assert.strictEqual(typeof(recipe), "object", "Check recipe type"); - Assert.strictEqual(recipe.hosts.length, 2, "Check that two hosts are present"); - Assert.strictEqual(recipe.hosts[0], "example.com", "Check the first host"); - Assert.strictEqual(recipe.hosts[1], "foo.invalid", "Check the second host"); - - let fooRecipes = recipesParent.getRecipesForHost("foo.invalid"); - Assert.strictEqual(fooRecipes.size, 1, "Check recipe count for foo.invalid"); - let fooRecipe = [...fooRecipes][0]; - Assert.strictEqual(fooRecipe, recipe, "Check that the recipe is shared"); - Assert.strictEqual(typeof(fooRecipe), "object", "Check recipe type"); - Assert.strictEqual(fooRecipe.hosts.length, 2, "Check that two hosts are present"); - Assert.strictEqual(fooRecipe.hosts[0], "example.com", "Check the first host"); - Assert.strictEqual(fooRecipe.hosts[1], "foo.invalid", "Check the second host"); -}); - -add_task(function* test_add_pathRegex() { - let recipesParent = yield RecipeHelpers.initNewParent(); - recipesParent.add({ - hosts: ["example.com"], - pathRegex: /^\/mypath\//, - }); - Assert.strictEqual(recipesParent._recipesByHost.size, 1, - "Check number of hosts after the addition"); - - let exampleRecipes = recipesParent.getRecipesForHost("example.com"); - Assert.strictEqual(exampleRecipes.size, 1, "Check recipe count for example.com"); - let recipe = [...exampleRecipes][0]; - Assert.strictEqual(typeof(recipe), "object", "Check recipe type"); - Assert.strictEqual(recipe.hosts.length, 1, "Check that one host is present"); - Assert.strictEqual(recipe.hosts[0], "example.com", "Check the one host"); - Assert.strictEqual(recipe.pathRegex.toString(), "/^\\/mypath\\//", "Check the pathRegex"); -}); - -add_task(function* test_add_selectors() { - let recipesParent = yield RecipeHelpers.initNewParent(); - recipesParent.add({ - hosts: ["example.com"], - usernameSelector: "#my-username", - passwordSelector: "#my-form > input.password", - }); - Assert.strictEqual(recipesParent._recipesByHost.size, 1, - "Check number of hosts after the addition"); - - let exampleRecipes = recipesParent.getRecipesForHost("example.com"); - Assert.strictEqual(exampleRecipes.size, 1, "Check recipe count for example.com"); - let recipe = [...exampleRecipes][0]; - Assert.strictEqual(typeof(recipe), "object", "Check recipe type"); - Assert.strictEqual(recipe.hosts.length, 1, "Check that one host is present"); - Assert.strictEqual(recipe.hosts[0], "example.com", "Check the one host"); - Assert.strictEqual(recipe.usernameSelector, "#my-username", "Check the usernameSelector"); - Assert.strictEqual(recipe.passwordSelector, "#my-form > input.password", "Check the passwordSelector"); -}); - -/* Begin checking errors with add */ - -add_task(function* test_add_missing_prop() { - let recipesParent = yield RecipeHelpers.initNewParent(); - Assert.throws(() => recipesParent.add({}), /required/, "Some properties are required"); -}); - -add_task(function* test_add_unknown_prop() { - let recipesParent = yield RecipeHelpers.initNewParent(); - Assert.throws(() => recipesParent.add({ - unknownProp: true, - }), /supported/, "Unknown properties should cause an error to help with typos"); -}); - -add_task(function* test_add_invalid_hosts() { - let recipesParent = yield RecipeHelpers.initNewParent(); - Assert.throws(() => recipesParent.add({ - hosts: 404, - }), /array/, "hosts should be an array"); -}); - -add_task(function* test_add_empty_host_array() { - let recipesParent = yield RecipeHelpers.initNewParent(); - Assert.throws(() => recipesParent.add({ - hosts: [], - }), /array/, "hosts should be a non-empty array"); -}); - -add_task(function* test_add_pathRegex_non_regexp() { - let recipesParent = yield RecipeHelpers.initNewParent(); - Assert.throws(() => recipesParent.add({ - hosts: ["example.com"], - pathRegex: "foo", - }), /regular expression/, "pathRegex should be a RegExp"); -}); - -add_task(function* test_add_usernameSelector_non_string() { - let recipesParent = yield RecipeHelpers.initNewParent(); - Assert.throws(() => recipesParent.add({ - hosts: ["example.com"], - usernameSelector: 404, - }), /string/, "usernameSelector should be a string"); -}); - -add_task(function* test_add_passwordSelector_non_string() { - let recipesParent = yield RecipeHelpers.initNewParent(); - Assert.throws(() => recipesParent.add({ - hosts: ["example.com"], - passwordSelector: 404, - }), /string/, "passwordSelector should be a string"); -}); - -/* End checking errors with add */ diff --git a/toolkit/components/passwordmgr/test/unit/test_recipes_content.js b/toolkit/components/passwordmgr/test/unit/test_recipes_content.js deleted file mode 100644 index 3d3751452..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_recipes_content.js +++ /dev/null @@ -1,39 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Test filtering recipes in LoginRecipesContent. - */ - -"use strict"; - -Cu.importGlobalProperties(["URL"]); - -add_task(function* test_getFieldOverrides() { - let recipes = new Set([ - { // path doesn't match but otherwise good - hosts: ["example.com:8080"], - passwordSelector: "#password", - pathRegex: /^\/$/, - usernameSelector: ".username", - }, - { // match with no field overrides - hosts: ["example.com:8080"], - }, - { // best match (field selectors + path match) - description: "best match", - hosts: ["a.invalid", "example.com:8080", "other.invalid"], - passwordSelector: "#password", - pathRegex: /^\/first\/second\/$/, - usernameSelector: ".username", - }, - ]); - - let form = MockDocument.createTestDocument("http://localhost:8080/first/second/", "<form>"). - forms[0]; - let override = LoginRecipesContent.getFieldOverrides(recipes, form); - Assert.strictEqual(override.description, "best match", - "Check the best field override recipe was returned"); - Assert.strictEqual(override.usernameSelector, ".username", "Check usernameSelector"); - Assert.strictEqual(override.passwordSelector, "#password", "Check passwordSelector"); -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_removeLegacySignonFiles.js b/toolkit/components/passwordmgr/test/unit/test_removeLegacySignonFiles.js deleted file mode 100644 index 51a107170..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_removeLegacySignonFiles.js +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Tests the LoginHelper object. - */ - -"use strict"; - - -Cu.import("resource://gre/modules/Task.jsm"); - -XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper", - "resource://gre/modules/LoginHelper.jsm"); - - -function* createSignonFile(singon) { - let {file, pref} = singon; - - if (pref) { - Services.prefs.setCharPref(pref, file); - } - - yield OS.File.writeAtomic( - OS.Path.join(OS.Constants.Path.profileDir, file), new Uint8Array(1)); -} - -function* isSignonClear(singon) { - const {file, pref} = singon; - const fileExists = yield OS.File.exists( - OS.Path.join(OS.Constants.Path.profileDir, file)); - - if (pref) { - try { - Services.prefs.getCharPref(pref); - return false; - } catch (e) {} - } - - return !fileExists; -} - -add_task(function* test_remove_lagecy_signonfile() { - // In the last test case, signons3.txt being deleted even when - // it doesn't exist. - const signonsSettings = [[ - { file: "signons.txt" }, - { file: "signons2.txt" }, - { file: "signons3.txt" } - ], [ - { file: "signons.txt", pref: "signon.SignonFileName" }, - { file: "signons2.txt", pref: "signon.SignonFileName2" }, - { file: "signons3.txt", pref: "signon.SignonFileName3" } - ], [ - { file: "signons2.txt" }, - { file: "singons.txt", pref: "signon.SignonFileName" }, - { file: "customized2.txt", pref: "signon.SignonFileName2" }, - { file: "customized3.txt", pref: "signon.SignonFileName3" } - ]]; - - for (let setting of signonsSettings) { - for (let singon of setting) { - yield createSignonFile(singon); - } - - LoginHelper.removeLegacySignonFiles(); - - for (let singon of setting) { - equal(yield isSignonClear(singon), true); - } - } -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_search_schemeUpgrades.js b/toolkit/components/passwordmgr/test/unit/test_search_schemeUpgrades.js deleted file mode 100644 index 3406becff..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_search_schemeUpgrades.js +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Test Services.logins.searchLogins with the `schemeUpgrades` property. - */ - -const HTTP3_ORIGIN = "http://www3.example.com"; -const HTTPS_ORIGIN = "https://www.example.com"; -const HTTP_ORIGIN = "http://www.example.com"; - -/** - * Returns a list of new nsILoginInfo objects that are a subset of the test - * data, built to match the specified query. - * - * @param {Object} aQuery - * Each property and value of this object restricts the search to those - * entries from the test data that match the property exactly. - */ -function buildExpectedLogins(aQuery) { - return TestData.loginList().filter( - entry => Object.keys(aQuery).every(name => { - if (name == "schemeUpgrades") { - return true; - } - if (["hostname", "formSubmitURL"].includes(name)) { - return LoginHelper.isOriginMatching(entry[name], aQuery[name], { - schemeUpgrades: aQuery.schemeUpgrades, - }); - } - return entry[name] === aQuery[name]; - })); -} - -/** - * Tests the searchLogins function. - * - * @param {Object} aQuery - * Each property and value of this object is translated to an entry in - * the nsIPropertyBag parameter of searchLogins. - * @param {Number} aExpectedCount - * Number of logins from the test data that should be found. The actual - * list of logins is obtained using the buildExpectedLogins helper, and - * this value is just used to verify that modifications to the test data - * don't make the current test meaningless. - */ -function checkSearch(aQuery, aExpectedCount) { - do_print("Testing searchLogins for " + JSON.stringify(aQuery)); - - let expectedLogins = buildExpectedLogins(aQuery); - do_check_eq(expectedLogins.length, aExpectedCount); - - let outCount = {}; - let logins = Services.logins.searchLogins(outCount, newPropertyBag(aQuery)); - do_check_eq(outCount.value, expectedLogins.length); - LoginTestUtils.assertLoginListsEqual(logins, expectedLogins); -} - -/** - * Prepare data for the following tests. - */ -add_task(function test_initialize() { - for (let login of TestData.loginList()) { - Services.logins.addLogin(login); - } -}); - -/** - * Tests searchLogins with the `schemeUpgrades` property - */ -add_task(function test_search_schemeUpgrades_hostname() { - // Hostname-only - checkSearch({ - hostname: HTTPS_ORIGIN, - }, 1); - checkSearch({ - hostname: HTTPS_ORIGIN, - schemeUpgrades: false, - }, 1); - checkSearch({ - hostname: HTTPS_ORIGIN, - schemeUpgrades: undefined, - }, 1); - checkSearch({ - hostname: HTTPS_ORIGIN, - schemeUpgrades: true, - }, 2); -}); - -/** - * Same as above but replacing hostname with formSubmitURL. - */ -add_task(function test_search_schemeUpgrades_formSubmitURL() { - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - }, 2); - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - schemeUpgrades: false, - }, 2); - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - schemeUpgrades: undefined, - }, 2); - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - schemeUpgrades: true, - }, 4); -}); - - -add_task(function test_search_schemeUpgrades_hostname_formSubmitURL() { - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - hostname: HTTPS_ORIGIN, - }, 1); - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - hostname: HTTPS_ORIGIN, - schemeUpgrades: false, - }, 1); - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - hostname: HTTPS_ORIGIN, - schemeUpgrades: undefined, - }, 1); - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - hostname: HTTPS_ORIGIN, - schemeUpgrades: true, - }, 2); - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - hostname: HTTPS_ORIGIN, - schemeUpgrades: true, - usernameField: "form_field_username", - }, 2); - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - hostname: HTTPS_ORIGIN, - passwordField: "form_field_password", - schemeUpgrades: true, - usernameField: "form_field_username", - }, 2); - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - hostname: HTTPS_ORIGIN, - httpRealm: null, - passwordField: "form_field_password", - schemeUpgrades: true, - usernameField: "form_field_username", - }, 2); -}); - -/** - * HTTP submitting to HTTPS - */ -add_task(function test_http_to_https() { - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - hostname: HTTP3_ORIGIN, - httpRealm: null, - schemeUpgrades: false, - }, 1); - checkSearch({ - formSubmitURL: HTTPS_ORIGIN, - hostname: HTTP3_ORIGIN, - httpRealm: null, - schemeUpgrades: true, - }, 2); -}); - -/** - * schemeUpgrades shouldn't cause downgrades - */ -add_task(function test_search_schemeUpgrades_downgrade() { - checkSearch({ - formSubmitURL: HTTP_ORIGIN, - hostname: HTTP_ORIGIN, - }, 1); - do_print("The same number should be found with schemeUpgrades since we're searching for HTTP"); - checkSearch({ - formSubmitURL: HTTP_ORIGIN, - hostname: HTTP_ORIGIN, - schemeUpgrades: true, - }, 1); -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_storage.js b/toolkit/components/passwordmgr/test/unit/test_storage.js deleted file mode 100644 index d65516d9b..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_storage.js +++ /dev/null @@ -1,102 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests that the default nsILoginManagerStorage module attached to the Login - * Manager service is able to save and reload nsILoginInfo properties correctly, - * even when they include special characters. - */ - -"use strict"; - -// Globals - -function* reloadAndCheckLoginsGen(aExpectedLogins) -{ - yield LoginTestUtils.reloadData(); - LoginTestUtils.checkLogins(aExpectedLogins); - LoginTestUtils.clearData(); -} - -// Tests - -/** - * Tests addLogin with valid non-ASCII characters. - */ -add_task(function* test_storage_addLogin_nonascii() -{ - let hostname = "http://" + String.fromCharCode(355) + ".example.com"; - - // Store the strings "user" and "pass" using similarly looking glyphs. - let loginInfo = TestData.formLogin({ - hostname: hostname, - formSubmitURL: hostname, - username: String.fromCharCode(533, 537, 7570, 345), - password: String.fromCharCode(421, 259, 349, 537), - usernameField: "field_" + String.fromCharCode(533, 537, 7570, 345), - passwordField: "field_" + String.fromCharCode(421, 259, 349, 537), - }); - Services.logins.addLogin(loginInfo); - yield* reloadAndCheckLoginsGen([loginInfo]); - - // Store the string "test" using similarly looking glyphs. - loginInfo = TestData.authLogin({ - httpRealm: String.fromCharCode(355, 277, 349, 357), - }); - Services.logins.addLogin(loginInfo); - yield* reloadAndCheckLoginsGen([loginInfo]); -}); - -/** - * Tests addLogin with newline characters in the username and password. - */ -add_task(function* test_storage_addLogin_newlines() -{ - let loginInfo = TestData.formLogin({ - username: "user\r\nname", - password: "password\r\n", - }); - Services.logins.addLogin(loginInfo); - yield* reloadAndCheckLoginsGen([loginInfo]); -}); - -/** - * Tests addLogin with a single dot in fields where it is allowed. - * - * These tests exist to verify the legacy "signons.txt" storage format. - */ -add_task(function* test_storage_addLogin_dot() -{ - let loginInfo = TestData.formLogin({ hostname: ".", passwordField: "." }); - Services.logins.addLogin(loginInfo); - yield* reloadAndCheckLoginsGen([loginInfo]); - - loginInfo = TestData.authLogin({ httpRealm: "." }); - Services.logins.addLogin(loginInfo); - yield* reloadAndCheckLoginsGen([loginInfo]); -}); - -/** - * Tests addLogin with parentheses in hostnames. - * - * These tests exist to verify the legacy "signons.txt" storage format. - */ -add_task(function* test_storage_addLogin_parentheses() -{ - let loginList = [ - TestData.authLogin({ httpRealm: "(realm" }), - TestData.authLogin({ httpRealm: "realm)" }), - TestData.authLogin({ httpRealm: "(realm)" }), - TestData.authLogin({ httpRealm: ")realm(" }), - TestData.authLogin({ hostname: "http://parens(.example.com" }), - TestData.authLogin({ hostname: "http://parens).example.com" }), - TestData.authLogin({ hostname: "http://parens(example).example.com" }), - TestData.authLogin({ hostname: "http://parens)example(.example.com" }), - ]; - for (let loginInfo of loginList) { - Services.logins.addLogin(loginInfo); - } - yield* reloadAndCheckLoginsGen(loginList); -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_storage_mozStorage.js b/toolkit/components/passwordmgr/test/unit/test_storage_mozStorage.js deleted file mode 100644 index 8eab6efe5..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_storage_mozStorage.js +++ /dev/null @@ -1,507 +0,0 @@ -/* - * This test interfaces directly with the mozStorage password storage module, - * bypassing the normal password manager usage. - */ - - -const ENCTYPE_BASE64 = 0; -const ENCTYPE_SDR = 1; -const PERMISSION_SAVE_LOGINS = "login-saving"; - -// Current schema version used by storage-mozStorage.js. This will need to be -// kept in sync with the version there (or else the tests fail). -const CURRENT_SCHEMA = 6; - -function* copyFile(aLeafName) -{ - yield OS.File.copy(OS.Path.join(do_get_file("data").path, aLeafName), - OS.Path.join(OS.Constants.Path.profileDir, aLeafName)); -} - -function openDB(aLeafName) -{ - var dbFile = new FileUtils.File(OS.Constants.Path.profileDir); - dbFile.append(aLeafName); - - return Services.storage.openDatabase(dbFile); -} - -function deleteFile(pathname, filename) -{ - var file = new FileUtils.File(pathname); - file.append(filename); - - // Suppress failures, this happens in the mozstorage tests on Windows - // because the module may still be holding onto the DB. (We don't - // have a way to explicitly shutdown/GC the module). - try { - if (file.exists()) - file.remove(false); - } catch (e) {} -} - -function reloadStorage(aInputPathName, aInputFileName) -{ - var inputFile = null; - if (aInputFileName) { - inputFile = Cc["@mozilla.org/file/local;1"]. - createInstance(Ci.nsILocalFile); - inputFile.initWithPath(aInputPathName); - inputFile.append(aInputFileName); - } - - let storage = Cc["@mozilla.org/login-manager/storage/mozStorage;1"] - .createInstance(Ci.nsILoginManagerStorage); - storage.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIVariant) - .initWithFile(inputFile); - - return storage; -} - -function checkStorageData(storage, ref_disabledHosts, ref_logins) -{ - LoginTestUtils.assertLoginListsEqual(storage.getAllLogins(), ref_logins); - LoginTestUtils.assertDisabledHostsEqual(getAllDisabledHostsFromPermissionManager(), - ref_disabledHosts); -} - -function getAllDisabledHostsFromPermissionManager() { - let disabledHosts = []; - let enumerator = Services.perms.enumerator; - - while (enumerator.hasMoreElements()) { - let perm = enumerator.getNext(); - if (perm.type == PERMISSION_SAVE_LOGINS && perm.capability == Services.perms.DENY_ACTION) { - disabledHosts.push(perm.principal.URI.prePath); - } - } - - return disabledHosts; -} - -function setLoginSavingEnabled(origin, enabled) { - let uri = Services.io.newURI(origin, null, null); - - if (enabled) { - Services.perms.remove(uri, PERMISSION_SAVE_LOGINS); - } else { - Services.perms.add(uri, PERMISSION_SAVE_LOGINS, Services.perms.DENY_ACTION); - } -} - -add_task(function* test_execute() -{ - -const OUTDIR = OS.Constants.Path.profileDir; - -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); - } - - 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", - Components.interfaces.nsILoginInfo); -do_check_true(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"; - -yield* copyFile("signons-v999.sqlite"); -// Verify the schema version in the test file. -dbConnection = openDB("signons-v999.sqlite"); -do_check_eq(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"); -do_check_eq(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. -yield* copyFile("signons-v999-2.sqlite"); -yield OS.File.remove(failFile); - -Assert.throws(() => reloadStorage(OUTDIR, "signons-v999-2.sqlite"), - /Initialization failed/); - -// Check to ensure the DB file was renamed to .corrupt. -do_check_false(yield OS.File.exists(origFile)); -do_check_true(yield OS.File.exists(failFile)); - -yield OS.File.remove(failFile); - -/* ========== 3 ========== */ -testnum++; -testdesc = "Test upgrade from v1->v2 storage"; - -yield* copyFile("signons-v1.sqlite"); -// Sanity check the test file. -dbConnection = openDB("signons-v1.sqlite"); -do_check_eq(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"); -do_check_eq(CURRENT_SCHEMA, dbConnection.schemaVersion); -var guid = getGUIDforID(dbConnection, 1); -do_check_true(isGUID.test(guid)); -guid = getGUIDforID(dbConnection, 2); -do_check_true(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. - -yield* copyFile("signons-v1v2.sqlite"); -// Sanity check the test file. -dbConnection = openDB("signons-v1v2.sqlite"); -do_check_eq(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"); -do_check_eq(CURRENT_SCHEMA, dbConnection.schemaVersion); -guid = getGUIDforID(dbConnection, 1); -do_check_eq("{655c7358-f1d6-6446-adab-53f98ac5d80f}", guid); -guid = getGUIDforID(dbConnection, 2); -do_check_eq("{13d9bfdc-572a-4d4e-9436-68e9803e84c1}", guid); -guid = getGUIDforID(dbConnection, 3); -do_check_true(isGUID.test(guid)); -dbConnection.close(); - -deleteFile(OUTDIR, "signons-v1v2.sqlite"); - -/* ========== 5 ========== */ -testnum++; -testdesc = "Test upgrade from v2->v3 storage"; - -yield* copyFile("signons-v2.sqlite"); -// Sanity check the test file. -dbConnection = openDB("signons-v2.sqlite"); -do_check_eq(2, dbConnection.schemaVersion); - -storage = reloadStorage(OUTDIR, "signons-v2.sqlite"); - -// Check to see that we added the correct encType to the logins. -do_check_eq(CURRENT_SCHEMA, dbConnection.schemaVersion); -var encTypes = [ENCTYPE_BASE64, ENCTYPE_SDR, ENCTYPE_BASE64, ENCTYPE_BASE64]; -for (let i = 0; i < encTypes.length; i++) - do_check_eq(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. - -yield* copyFile("signons-v2v3.sqlite"); -// Sanity check the test file. -dbConnection = openDB("signons-v2v3.sqlite"); -do_check_eq(2, dbConnection.schemaVersion); -encTypes = [ENCTYPE_BASE64, ENCTYPE_SDR, ENCTYPE_BASE64, ENCTYPE_BASE64, null]; -for (let i = 0; i < encTypes.length; i++) - do_check_eq(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"); -do_check_eq(CURRENT_SCHEMA, dbConnection.schemaVersion); - -encTypes = [ENCTYPE_BASE64, ENCTYPE_SDR, ENCTYPE_BASE64, ENCTYPE_BASE64, ENCTYPE_SDR]; -for (let i = 0; i < encTypes.length; i++) - do_check_eq(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++) - do_check_eq(encTypes[i], getEncTypeForID(dbConnection, i + 1)); -dbConnection.close(); - -deleteFile(OUTDIR, "signons-v2v3.sqlite"); - - -/* ========== 7 ========== */ -testnum++; -testdesc = "Test upgrade from v3->v4 storage"; - -yield* copyFile("signons-v3.sqlite"); -// Sanity check the test file. -dbConnection = openDB("signons-v3.sqlite"); -do_check_eq(3, dbConnection.schemaVersion); - -storage = reloadStorage(OUTDIR, "signons-v3.sqlite"); -do_check_eq(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++) { - do_check_true(logins[i] instanceof Ci.nsILoginMetaInfo); - do_check_eq(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"; - -yield* copyFile("signons-v3v4.sqlite"); -// Sanity check the test file. -dbConnection = openDB("signons-v3v4.sqlite"); -do_check_eq(3, dbConnection.schemaVersion); - -storage = reloadStorage(OUTDIR, "signons-v3v4.sqlite"); -do_check_eq(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]; -} - -do_check_true(t1 instanceof Ci.nsILoginMetaInfo); -do_check_true(t2 instanceof Ci.nsILoginMetaInfo); - -do_check_eq(9, t1.timesUsed); -do_check_eq(1262049951275, t1.timeCreated); -do_check_eq(1262049951275, t1.timeLastUsed); -do_check_eq(1262049951275, t1.timePasswordChanged); - -do_check_eq(1, t2.timesUsed); -LoginTestUtils.assertTimeIsAboutNow(t2.timeCreated); -LoginTestUtils.assertTimeIsAboutNow(t2.timeLastUsed); -LoginTestUtils.assertTimeIsAboutNow(t2.timePasswordChanged); - - -/* ========== 9 ========== */ -testnum++; -testdesc = "Test upgrade from v4 storage"; - -yield* copyFile("signons-v4.sqlite"); -// Sanity check the test file. -dbConnection = openDB("signons-v4.sqlite"); -do_check_eq(4, dbConnection.schemaVersion); -do_check_false(dbConnection.tableExists("moz_deleted_logins")); - -storage = reloadStorage(OUTDIR, "signons-v4.sqlite"); -do_check_eq(CURRENT_SCHEMA, dbConnection.schemaVersion); -do_check_true(dbConnection.tableExists("moz_deleted_logins")); - - -/* ========== 10 ========== */ -testnum++; -testdesc = "Test upgrade from v4->v5->v4 storage"; - -yield copyFile("signons-v4v5.sqlite"); -// Sanity check the test file. -dbConnection = openDB("signons-v4v5.sqlite"); -do_check_eq(4, dbConnection.schemaVersion); -do_check_true(dbConnection.tableExists("moz_deleted_logins")); - -storage = reloadStorage(OUTDIR, "signons-v4v5.sqlite"); -do_check_eq(CURRENT_SCHEMA, dbConnection.schemaVersion); -do_check_true(dbConnection.tableExists("moz_deleted_logins")); - -/* ========== 11 ========== */ -testnum++; -testdesc = "Test upgrade from v5->v6 storage"; - -yield* copyFile("signons-v5v6.sqlite"); - -// Sanity check the test file. -dbConnection = openDB("signons-v5v6.sqlite"); -do_check_eq(5, dbConnection.schemaVersion); -do_check_true(dbConnection.tableExists("moz_disabledHosts")); - -// Initial disabled hosts inside signons-v5v6.sqlite -var disabledHosts = [ - "http://disabled1.example.com", - "http://大.net", - "http://xn--19g.com" -]; - -LoginTestUtils.assertDisabledHostsEqual(disabledHosts, getAllDisabledHostsFromMozStorage(dbConnection)); - -// Reload storage -storage = reloadStorage(OUTDIR, "signons-v5v6.sqlite"); -do_check_eq(CURRENT_SCHEMA, dbConnection.schemaVersion); - -// 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(); - -// 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); -} - -/* ========== 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"); - - -/* - * ---------------------- 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"; - -const filename = "signons-c.sqlite"; -const filepath = OS.Path.join(OS.Constants.Path.profileDir, filename); - -yield 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/); - -// check that the backup file exists -do_check_true(yield OS.File.exists(filepath + ".corrupt")); - -// check that the original corrupt file has been deleted -do_check_false(yield OS.File.exists(filepath)); - -// 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]); - -// check the file exists -var file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile); -file.initWithPath(OS.Constants.Path.profileDir); -file.append(filename); -do_check_true(file.exists()); - -deleteFile(OS.Constants.Path.profileDir, filename + ".corrupt"); -deleteFile(OS.Constants.Path.profileDir, filename); - -} catch (e) { - throw new Error("FAILED in test #" + testnum + " -- " + testdesc + ": " + e); -} - -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_telemetry.js b/toolkit/components/passwordmgr/test/unit/test_telemetry.js deleted file mode 100644 index 1d8f80226..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_telemetry.js +++ /dev/null @@ -1,187 +0,0 @@ -/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * Tests the statistics and other counters reported through telemetry. - */ - -"use strict"; - -// Globals - -const MS_PER_DAY = 24 * 60 * 60 * 1000; - -// To prevent intermittent failures when the test is executed at a time that is -// very close to a day boundary, we make it deterministic by using a static -// reference date for all the time-based statistics. -const gReferenceTimeMs = new Date("2000-01-01T00:00:00").getTime(); - -// Returns a milliseconds value to use with nsILoginMetaInfo properties, falling -// approximately in the middle of the specified number of days before the -// reference time, where zero days indicates a time within the past 24 hours. -var daysBeforeMs = days => gReferenceTimeMs - (days + 0.5) * MS_PER_DAY; - -/** - * Contains metadata that will be attached to test logins in order to verify - * that the statistics collection is working properly. Most properties of the - * logins are initialized to the default test values already. - * - * If you update this data or any of the telemetry histograms it checks, you'll - * probably need to update the expected statistics in the test below. - */ -const StatisticsTestData = [ - { - timeLastUsed: daysBeforeMs(0), - }, - { - timeLastUsed: daysBeforeMs(1), - }, - { - timeLastUsed: daysBeforeMs(7), - formSubmitURL: null, - httpRealm: "The HTTP Realm", - }, - { - username: "", - timeLastUsed: daysBeforeMs(7), - }, - { - username: "", - timeLastUsed: daysBeforeMs(30), - }, - { - username: "", - timeLastUsed: daysBeforeMs(31), - }, - { - timeLastUsed: daysBeforeMs(365), - }, - { - username: "", - timeLastUsed: daysBeforeMs(366), - }, - { - // If the login was saved in the future, it is ignored for statistiscs. - timeLastUsed: daysBeforeMs(-1), - }, - { - timeLastUsed: daysBeforeMs(1000), - }, -]; - -/** - * Triggers the collection of those statistics that are not accumulated each - * time an action is taken, but are a static snapshot of the current state. - */ -function triggerStatisticsCollection() { - Services.obs.notifyObservers(null, "gather-telemetry", "" + gReferenceTimeMs); -} - -/** - * Tests the telemetry histogram with the given ID contains only the specified - * non-zero ranges, expressed in the format { range1: value1, range2: value2 }. - */ -function testHistogram(histogramId, expectedNonZeroRanges) { - let snapshot = Services.telemetry.getHistogramById(histogramId).snapshot(); - - // Compute the actual ranges in the format { range1: value1, range2: value2 }. - let actualNonZeroRanges = {}; - for (let [index, range] of snapshot.ranges.entries()) { - let value = snapshot.counts[index]; - if (value > 0) { - actualNonZeroRanges[range] = value; - } - } - - // These are stringified to visualize the differences between the values. - do_print("Testing histogram: " + histogramId); - do_check_eq(JSON.stringify(actualNonZeroRanges), - JSON.stringify(expectedNonZeroRanges)); -} - -// Tests - -/** - * Enable local telemetry recording for the duration of the tests, and prepare - * the test data that will be used by the following tests. - */ -add_task(function test_initialize() { - let oldCanRecord = Services.telemetry.canRecordExtended; - Services.telemetry.canRecordExtended = true; - do_register_cleanup(function () { - Services.telemetry.canRecordExtended = oldCanRecord; - }); - - let uniqueNumber = 1; - for (let loginModifications of StatisticsTestData) { - loginModifications.hostname = `http://${uniqueNumber++}.example.com`; - Services.logins.addLogin(TestData.formLogin(loginModifications)); - } -}); - -/** - * Tests the collection of statistics related to login metadata. - */ -add_task(function test_logins_statistics() { - // Repeat the operation twice to test that histograms are not accumulated. - for (let repeating of [false, true]) { - triggerStatisticsCollection(); - - // Should record 1 in the bucket corresponding to the number of passwords. - testHistogram("PWMGR_NUM_SAVED_PASSWORDS", - { 10: 1 }); - - // Should record 1 in the bucket corresponding to the number of passwords. - testHistogram("PWMGR_NUM_HTTPAUTH_PASSWORDS", - { 1: 1 }); - - // For each saved login, should record 1 in the bucket corresponding to the - // age in days since the login was last used. - testHistogram("PWMGR_LOGIN_LAST_USED_DAYS", - { 0: 1, 1: 1, 7: 2, 29: 2, 356: 2, 750: 1 }); - - // Should record the number of logins without a username in bucket 0, and - // the number of logins with a username in bucket 1. - testHistogram("PWMGR_USERNAME_PRESENT", - { 0: 4, 1: 6 }); - } -}); - -/** - * Tests the collection of statistics related to hosts for which passowrd saving - * has been explicitly disabled. - */ -add_task(function test_disabledHosts_statistics() { - // Should record 1 in the bucket corresponding to the number of sites for - // which password saving is disabled. - Services.logins.setLoginSavingEnabled("http://www.example.com", false); - triggerStatisticsCollection(); - testHistogram("PWMGR_BLOCKLIST_NUM_SITES", { 1: 1 }); - - Services.logins.setLoginSavingEnabled("http://www.example.com", true); - triggerStatisticsCollection(); - testHistogram("PWMGR_BLOCKLIST_NUM_SITES", { 0: 1 }); -}); - -/** - * Tests the collection of statistics related to general settings. - */ -add_task(function test_settings_statistics() { - let oldRememberSignons = Services.prefs.getBoolPref("signon.rememberSignons"); - do_register_cleanup(function () { - Services.prefs.setBoolPref("signon.rememberSignons", oldRememberSignons); - }); - - // Repeat the operation twice per value to test that histograms are reset. - for (let remember of [false, true, false, true]) { - // This change should be observed immediately by the login service. - Services.prefs.setBoolPref("signon.rememberSignons", remember); - - triggerStatisticsCollection(); - - // Should record 1 in either bucket 0 or bucket 1 based on the preference. - testHistogram("PWMGR_SAVING_ENABLED", remember ? { 1: 1 } : { 0: 1 }); - } -}); diff --git a/toolkit/components/passwordmgr/test/unit/test_user_autocomplete_result.js b/toolkit/components/passwordmgr/test/unit/test_user_autocomplete_result.js deleted file mode 100644 index e1d250a76..000000000 --- a/toolkit/components/passwordmgr/test/unit/test_user_autocomplete_result.js +++ /dev/null @@ -1,488 +0,0 @@ -XPCOMUtils.defineLazyModuleGetter(this, "LoginHelper", - "resource://gre/modules/LoginHelper.jsm"); -Cu.import("resource://gre/modules/LoginManagerContent.jsm"); -var nsLoginInfo = Components.Constructor("@mozilla.org/login-manager/loginInfo;1", - Ci.nsILoginInfo, "init"); - -const PREF_INSECURE_FIELD_WARNING_ENABLED = "security.insecure_field_warning.contextual.enabled"; -const PREF_INSECURE_AUTOFILLFORMS_ENABLED = "signon.autofillForms.http"; - -let matchingLogins = []; -matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "", "emptypass1", "uname", "pword")); - -matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "tempuser1", "temppass1", "uname", "pword")); - -matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "testuser2", "testpass2", "uname", "pword")); - -matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "testuser3", "testpass3", "uname", "pword")); - -matchingLogins.push(new nsLoginInfo("http://mochi.test:8888", "http://autocomplete:8888", null, - "zzzuser4", "zzzpass4", "uname", "pword")); - -let meta = matchingLogins[0].QueryInterface(Ci.nsILoginMetaInfo); -let dateAndTimeFormatter = new Intl.DateTimeFormat(undefined, - { day: "numeric", month: "short", year: "numeric" }); -let time = dateAndTimeFormatter.format(new Date(meta.timePasswordChanged)); -const LABEL_NO_USERNAME = "No username (" + time + ")"; - -let expectedResults = [ - { - insecureFieldWarningEnabled: true, - insecureAutoFillFormsEnabled: true, - isSecure: true, - isPasswordField: false, - matchingLogins: matchingLogins, - items: [{ - value: "", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "tempuser1", - label: "tempuser1", - style: "login", - }, { - value: "testuser2", - label: "testuser2", - style: "login", - }, { - value: "testuser3", - label: "testuser3", - style: "login", - }, { - value: "zzzuser4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: true, - insecureAutoFillFormsEnabled: true, - isSecure: false, - isPasswordField: false, - matchingLogins: matchingLogins, - items: [{ - value: "", - label: "This connection is not secure. Logins entered here could be compromised. Learn More", - style: "insecureWarning" - }, { - value: "", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "tempuser1", - label: "tempuser1", - style: "login", - }, { - value: "testuser2", - label: "testuser2", - style: "login", - }, { - value: "testuser3", - label: "testuser3", - style: "login", - }, { - value: "zzzuser4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: true, - insecureAutoFillFormsEnabled: true, - isSecure: true, - isPasswordField: true, - matchingLogins: matchingLogins, - items: [{ - value: "emptypass1", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "temppass1", - label: "tempuser1", - style: "login", - }, { - value: "testpass2", - label: "testuser2", - style: "login", - }, { - value: "testpass3", - label: "testuser3", - style: "login", - }, { - value: "zzzpass4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: true, - insecureAutoFillFormsEnabled: true, - isSecure: false, - isPasswordField: true, - matchingLogins: matchingLogins, - items: [{ - value: "", - label: "This connection is not secure. Logins entered here could be compromised. Learn More", - style: "insecureWarning" - }, { - value: "emptypass1", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "temppass1", - label: "tempuser1", - style: "login", - }, { - value: "testpass2", - label: "testuser2", - style: "login", - }, { - value: "testpass3", - label: "testuser3", - style: "login", - }, { - value: "zzzpass4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: false, - insecureAutoFillFormsEnabled: true, - isSecure: true, - isPasswordField: false, - matchingLogins: matchingLogins, - items: [{ - value: "", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "tempuser1", - label: "tempuser1", - style: "login", - }, { - value: "testuser2", - label: "testuser2", - style: "login", - }, { - value: "testuser3", - label: "testuser3", - style: "login", - }, { - value: "zzzuser4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: false, - insecureAutoFillFormsEnabled: true, - isSecure: false, - isPasswordField: false, - matchingLogins: matchingLogins, - items: [{ - value: "", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "tempuser1", - label: "tempuser1", - style: "login", - }, { - value: "testuser2", - label: "testuser2", - style: "login", - }, { - value: "testuser3", - label: "testuser3", - style: "login", - }, { - value: "zzzuser4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: false, - insecureAutoFillFormsEnabled: true, - isSecure: true, - isPasswordField: true, - matchingLogins: matchingLogins, - items: [{ - value: "emptypass1", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "temppass1", - label: "tempuser1", - style: "login", - }, { - value: "testpass2", - label: "testuser2", - style: "login", - }, { - value: "testpass3", - label: "testuser3", - style: "login", - }, { - value: "zzzpass4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: false, - insecureAutoFillFormsEnabled: true, - isSecure: false, - isPasswordField: true, - matchingLogins: matchingLogins, - items: [{ - value: "emptypass1", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "temppass1", - label: "tempuser1", - style: "login", - }, { - value: "testpass2", - label: "testuser2", - style: "login", - }, { - value: "testpass3", - label: "testuser3", - style: "login", - }, { - value: "zzzpass4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: true, - insecureAutoFillFormsEnabled: false, - isSecure: true, - isPasswordField: false, - matchingLogins: matchingLogins, - items: [{ - value: "", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "tempuser1", - label: "tempuser1", - style: "login", - }, { - value: "testuser2", - label: "testuser2", - style: "login", - }, { - value: "testuser3", - label: "testuser3", - style: "login", - }, { - value: "zzzuser4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: true, - insecureAutoFillFormsEnabled: false, - isSecure: false, - isPasswordField: false, - matchingLogins: matchingLogins, - items: [{ - value: "", - label: "This connection is not secure. Logins entered here could be compromised. Learn More", - style: "insecureWarning" - }, { - value: "", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "tempuser1", - label: "tempuser1", - style: "login", - }, { - value: "testuser2", - label: "testuser2", - style: "login", - }, { - value: "testuser3", - label: "testuser3", - style: "login", - }, { - value: "zzzuser4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: true, - insecureAutoFillFormsEnabled: false, - isSecure: true, - isPasswordField: true, - matchingLogins: matchingLogins, - items: [{ - value: "emptypass1", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "temppass1", - label: "tempuser1", - style: "login", - }, { - value: "testpass2", - label: "testuser2", - style: "login", - }, { - value: "testpass3", - label: "testuser3", - style: "login", - }, { - value: "zzzpass4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: true, - insecureAutoFillFormsEnabled: false, - isSecure: false, - isPasswordField: true, - matchingLogins: matchingLogins, - items: [{ - value: "", - label: "This connection is not secure. Logins entered here could be compromised. Learn More", - style: "insecureWarning" - }, { - value: "emptypass1", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "temppass1", - label: "tempuser1", - style: "login", - }, { - value: "testpass2", - label: "testuser2", - style: "login", - }, { - value: "testpass3", - label: "testuser3", - style: "login", - }, { - value: "zzzpass4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: false, - insecureAutoFillFormsEnabled: false, - isSecure: true, - isPasswordField: false, - matchingLogins: matchingLogins, - items: [{ - value: "", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "tempuser1", - label: "tempuser1", - style: "login", - }, { - value: "testuser2", - label: "testuser2", - style: "login", - }, { - value: "testuser3", - label: "testuser3", - style: "login", - }, { - value: "zzzuser4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: false, - insecureAutoFillFormsEnabled: false, - isSecure: false, - isPasswordField: false, - matchingLogins: matchingLogins, - items: [] - }, - { - insecureFieldWarningEnabled: false, - insecureAutoFillFormsEnabled: false, - isSecure: true, - isPasswordField: true, - matchingLogins: matchingLogins, - items: [{ - value: "emptypass1", - label: LABEL_NO_USERNAME, - style: "login", - }, { - value: "temppass1", - label: "tempuser1", - style: "login", - }, { - value: "testpass2", - label: "testuser2", - style: "login", - }, { - value: "testpass3", - label: "testuser3", - style: "login", - }, { - value: "zzzpass4", - label: "zzzuser4", - style: "login", - }] - }, - { - insecureFieldWarningEnabled: false, - insecureAutoFillFormsEnabled: false, - isSecure: false, - isPasswordField: true, - matchingLogins: matchingLogins, - items: [] - }, -]; - -add_task(function* test_all_patterns() { - LoginHelper.createLogger("UserAutoCompleteResult"); - expectedResults.forEach(pattern => { - Services.prefs.setBoolPref(PREF_INSECURE_FIELD_WARNING_ENABLED, - pattern.insecureFieldWarningEnabled); - Services.prefs.setBoolPref(PREF_INSECURE_AUTOFILLFORMS_ENABLED, - pattern.insecureAutoFillFormsEnabled); - let actual = new UserAutoCompleteResult("", pattern.matchingLogins, - { - isSecure: pattern.isSecure, - isPasswordField: pattern.isPasswordField - }); - pattern.items.forEach((item, index) => { - equal(actual.getValueAt(index), item.value); - equal(actual.getLabelAt(index), item.label); - equal(actual.getStyleAt(index), item.style); - }); - - if (pattern.items.length != 0) { - Assert.throws(() => actual.getValueAt(pattern.items.length), - /Index out of range\./); - - Assert.throws(() => actual.getLabelAt(pattern.items.length), - /Index out of range\./); - - Assert.throws(() => actual.removeValueAt(pattern.items.length, true), - /Index out of range\./); - } - }); -}); diff --git a/toolkit/components/passwordmgr/test/unit/xpcshell.ini b/toolkit/components/passwordmgr/test/unit/xpcshell.ini deleted file mode 100644 index 8f8c92a28..000000000 --- a/toolkit/components/passwordmgr/test/unit/xpcshell.ini +++ /dev/null @@ -1,46 +0,0 @@ -[DEFAULT] -head = head.js -tail = -support-files = data/** - -# Test JSON file access and import from SQLite, not applicable to Android. -[test_module_LoginImport.js] -skip-if = os == "android" -[test_module_LoginStore.js] -skip-if = os == "android" -[test_removeLegacySignonFiles.js] -skip-if = os == "android" - -# Test SQLite database backup and migration, applicable to Android only. -[test_storage_mozStorage.js] -skip-if = true || os != "android" # Bug 1171687: Needs fixing on Android - -# The following tests apply to any storage back-end. -[test_context_menu.js] -skip-if = os == "android" # The context menu isn't used on Android. -# LoginManagerContextMenu is only included for MOZ_BUILD_APP == 'browser'. -run-if = buildapp == "browser" -[test_dedupeLogins.js] -[test_disabled_hosts.js] -[test_getFormFields.js] -[test_getPasswordFields.js] -[test_getPasswordOrigin.js] -[test_isOriginMatching.js] -[test_legacy_empty_formSubmitURL.js] -[test_legacy_validation.js] -[test_logins_change.js] -[test_logins_decrypt_failure.js] -skip-if = os == "android" # Bug 1171687: Needs fixing on Android -[test_user_autocomplete_result.js] -skip-if = os == "android" -[test_logins_metainfo.js] -[test_logins_search.js] -[test_maybeImportLogin.js] -[test_notifications.js] -[test_OSCrypto_win.js] -skip-if = os != "win" -[test_recipes_add.js] -[test_recipes_content.js] -[test_search_schemeUpgrades.js] -[test_storage.js] -[test_telemetry.js] |