const { LoginAutoCompleteResult } = ChromeUtils.importESModule( "resource://gre/modules/LoginAutoComplete.sys.mjs" ); let nsLoginInfo = Components.Constructor( "@mozilla.org/login-manager/loginInfo;1", Ci.nsILoginInfo, "init" ); const PREF_SCHEME_UPGRADES = "signon.schemeUpgrades"; let matchingLogins = []; matchingLogins.push( new nsLoginInfo( "https://mochi.test:8888", "https://autocomplete:8888", null, "", "emptypass1", "uname", "pword" ) ); matchingLogins.push( new nsLoginInfo( "https://mochi.test:8888", "https://autocomplete:8888", null, "tempuser1", "temppass1", "uname", "pword" ) ); matchingLogins.push( new nsLoginInfo( "https://mochi.test:8888", "https://autocomplete:8888", null, "testuser2", "testpass2", "uname", "pword" ) ); // subdomain: matchingLogins.push( new nsLoginInfo( "https://sub.mochi.test:8888", "https://autocomplete:8888", null, "testuser3", "testpass3", "uname", "pword" ) ); // to test signon.schemeUpgrades matchingLogins.push( new nsLoginInfo( "http://mochi.test:8888", "http://autocomplete:8888", null, "zzzuser4", "zzzpass4", "uname", "pword" ) ); // HTTP auth matchingLogins.push( new nsLoginInfo( "https://mochi.test:8888", null, "My HTTP auth realm", "httpuser", "httppass" ) ); add_setup(async () => { // Get a profile so we have storage access and insert the logins to get unique GUIDs. do_get_profile(); matchingLogins = await Services.logins.addLogins(matchingLogins); }); add_task(async function test_all_patterns() { let meta = matchingLogins[0].QueryInterface(Ci.nsILoginMetaInfo); let dateAndTimeFormatter = new Services.intl.DateTimeFormat(undefined, { dateStyle: "medium", }); let time = dateAndTimeFormatter.format(new Date(meta.timePasswordChanged)); const LABEL_NO_USERNAME = "No username (" + time + ")"; const EXACT_ORIGIN_MATCH_COMMENT = "From this website"; let expectedResults = [ { isSecure: true, hasBeenTypePassword: false, matchingLogins, items: [ { value: "", label: LABEL_NO_USERNAME, style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "tempuser1", label: "tempuser1", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "testuser2", label: "testuser2", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "zzzuser4", label: "zzzuser4", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "httpuser", label: "httpuser", style: "loginWithOrigin", comment: { comment: "mochi.test:8888 (My HTTP auth realm)" }, }, { value: "testuser3", label: "testuser3", style: "loginWithOrigin", comment: { comment: "sub.mochi.test:8888" }, }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test", telemetryEventData: { searchStartTimeMS: 0 }, }, }, ], }, { isSecure: false, hasBeenTypePassword: false, matchingLogins: [], items: [ { value: "", label: "This connection is not secure. Logins entered here could be compromised. Learn More", style: "insecureWarning", comment: "", }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test", telemetryEventData: { searchStartTimeMS: 1 }, }, }, ], }, { isSecure: false, hasBeenTypePassword: false, matchingLogins, items: [ { value: "", label: "This connection is not secure. Logins entered here could be compromised. Learn More", style: "insecureWarning", comment: "", }, { value: "", label: LABEL_NO_USERNAME, style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "tempuser1", label: "tempuser1", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "testuser2", label: "testuser2", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "zzzuser4", label: "zzzuser4", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "httpuser", label: "httpuser", style: "loginWithOrigin", comment: { comment: "mochi.test:8888 (My HTTP auth realm)" }, }, { value: "testuser3", label: "testuser3", style: "loginWithOrigin", comment: { comment: "sub.mochi.test:8888" }, }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, { isSecure: true, hasBeenTypePassword: true, matchingLogins, items: [ { value: "emptypass1", label: LABEL_NO_USERNAME, style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "temppass1", label: "tempuser1", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "testpass2", label: "testuser2", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "zzzpass4", label: "zzzuser4", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "httppass", label: "httpuser", style: "loginWithOrigin", comment: { comment: "mochi.test:8888 (My HTTP auth realm)" }, }, { value: "testpass3", label: "testuser3", style: "loginWithOrigin", comment: { comment: "sub.mochi.test:8888" }, }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, { isSecure: false, hasBeenTypePassword: true, matchingLogins, items: [ { value: "", label: "This connection is not secure. Logins entered here could be compromised. Learn More", style: "insecureWarning", comment: "", }, { value: "emptypass1", label: LABEL_NO_USERNAME, style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "temppass1", label: "tempuser1", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "testpass2", label: "testuser2", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "zzzpass4", label: "zzzuser4", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "httppass", label: "httpuser", style: "loginWithOrigin", comment: { comment: "mochi.test:8888 (My HTTP auth realm)" }, }, { value: "testpass3", label: "testuser3", style: "loginWithOrigin", comment: { comment: "sub.mochi.test:8888" }, }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, { isSecure: true, hasBeenTypePassword: false, matchingLogins, items: [ { value: "", label: LABEL_NO_USERNAME, style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "tempuser1", label: "tempuser1", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "testuser2", label: "testuser2", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "zzzuser4", label: "zzzuser4", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "httpuser", label: "httpuser", style: "loginWithOrigin", comment: { comment: "mochi.test:8888 (My HTTP auth realm)" }, }, { value: "testuser3", label: "testuser3", style: "loginWithOrigin", comment: { comment: "sub.mochi.test:8888" }, }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, { isSecure: false, hasBeenTypePassword: false, matchingLogins: [], searchString: "foo", items: [ { value: "", label: "This connection is not secure. Logins entered here could be compromised. Learn More", style: "insecureWarning", comment: "", }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, { isSecure: true, hasBeenTypePassword: true, matchingLogins: [], items: [ { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, { isSecure: true, hasBeenTypePassword: true, matchingLogins: [], searchString: "foo", items: [], }, { generatedPassword: "9ljgfd4shyktb45", isSecure: true, hasBeenTypePassword: true, matchingLogins: [], items: [ { value: "9ljgfd4shyktb45", label: "Use a Securely Generated Password", style: "generatedPassword", comment: { generatedPassword: "9ljgfd4shyktb45", willAutoSaveGeneratedPassword: false, }, }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, { description: "willAutoSaveGeneratedPassword should propagate to the comment", generatedPassword: "9ljgfd4shyktb45", willAutoSaveGeneratedPassword: true, isSecure: true, hasBeenTypePassword: true, matchingLogins: [], items: [ { value: "9ljgfd4shyktb45", label: "Use a Securely Generated Password", style: "generatedPassword", comment: { generatedPassword: "9ljgfd4shyktb45", willAutoSaveGeneratedPassword: true, }, }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, { description: "If a generated password is passed then show it even if there is a search string. This handles when forcing the generation option from the context menu of a non-empty field", generatedPassword: "9ljgfd4shyktb45", isSecure: true, hasBeenTypePassword: true, matchingLogins: [], searchString: "9ljgfd4shyktb45", items: [ { value: "9ljgfd4shyktb45", label: "Use a Securely Generated Password", style: "generatedPassword", comment: { generatedPassword: "9ljgfd4shyktb45", willAutoSaveGeneratedPassword: false, }, }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, { description: "secure username field on sub.mochi.test", formOrigin: "https://sub.mochi.test:8888", isSecure: true, hasBeenTypePassword: false, matchingLogins, items: [ { value: "testuser3", label: "testuser3", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "", label: LABEL_NO_USERNAME, style: "loginWithOrigin", comment: { comment: "mochi.test:8888" }, }, { value: "tempuser1", label: "tempuser1", style: "loginWithOrigin", comment: { comment: "mochi.test:8888" }, }, { value: "testuser2", label: "testuser2", style: "loginWithOrigin", comment: { comment: "mochi.test:8888" }, }, { value: "zzzuser4", label: "zzzuser4", style: "loginWithOrigin", comment: { comment: "mochi.test:8888" }, }, { value: "httpuser", label: "httpuser", style: "loginWithOrigin", comment: { comment: "mochi.test:8888 (My HTTP auth realm)" }, }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, { description: "secure password field on sub.mochi.test", formOrigin: "https://sub.mochi.test:8888", isSecure: true, hasBeenTypePassword: true, matchingLogins, items: [ { value: "testpass3", label: "testuser3", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "emptypass1", label: LABEL_NO_USERNAME, style: "loginWithOrigin", comment: { comment: "mochi.test:8888" }, }, { value: "temppass1", label: "tempuser1", style: "loginWithOrigin", comment: { comment: "mochi.test:8888" }, }, { value: "testpass2", label: "testuser2", style: "loginWithOrigin", comment: { comment: "mochi.test:8888" }, }, { value: "zzzpass4", label: "zzzuser4", style: "loginWithOrigin", comment: { comment: "mochi.test:8888" }, }, { value: "httppass", label: "httpuser", style: "loginWithOrigin", comment: { comment: "mochi.test:8888 (My HTTP auth realm)" }, }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, { description: "schemeUpgrades: false", formOrigin: "https://mochi.test:8888", schemeUpgrades: false, isSecure: true, hasBeenTypePassword: false, matchingLogins, items: [ { value: "", label: LABEL_NO_USERNAME, style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "tempuser1", label: "tempuser1", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "testuser2", label: "testuser2", style: "loginWithOrigin", comment: { comment: EXACT_ORIGIN_MATCH_COMMENT }, }, { value: "zzzuser4", label: "zzzuser4", style: "loginWithOrigin", comment: { comment: "mochi.test:8888" }, }, { value: "httpuser", label: "httpuser", style: "loginWithOrigin", comment: { comment: "mochi.test:8888 (My HTTP auth realm)" }, }, { value: "testuser3", label: "testuser3", style: "loginWithOrigin", comment: { comment: "sub.mochi.test:8888" }, }, { value: "", label: "Manage Passwords", style: "loginsFooter", comment: { formHostname: "mochi.test" }, }, ], }, ]; LoginHelper.createLogger("LoginAutoCompleteResult"); Services.prefs.setBoolPref("signon.showAutoCompleteFooter", true); expectedResults.forEach((pattern, testIndex) => { info(`expectedResults[${testIndex}]`); info(JSON.stringify(pattern, null, 2)); Services.prefs.setBoolPref( PREF_SCHEME_UPGRADES, "schemeUpgrades" in pattern ? pattern.schemeUpgrades : true ); let actual = new LoginAutoCompleteResult( pattern.searchString || "", pattern.matchingLogins, [], pattern.formOrigin || "https://mochi.test:8888", { hostname: "mochi.test", generatedPassword: pattern.generatedPassword, willAutoSaveGeneratedPassword: !!pattern.willAutoSaveGeneratedPassword, isSecure: pattern.isSecure, hasBeenTypePassword: pattern.hasBeenTypePassword, telemetryEventData: { searchStartTimeMS: testIndex }, } ); equal( actual.matchCount, pattern.items.length, `${testIndex}: Check matching row count` ); pattern.items.forEach((item, index) => { equal( actual.getValueAt(index), item.value, `${testIndex}: Value ${index}` ); equal( actual.getLabelAt(index), item.label, `${testIndex}: Label ${index}` ); equal( actual.getStyleAt(index), item.style, `${testIndex}: Style ${index}` ); let actualComment = actual.getCommentAt(index); if (typeof item.comment == "object") { let parsedComment = JSON.parse(actualComment); for (let [key, val] of Object.entries(item.comment)) { Assert.deepEqual( parsedComment[key], val, `${testIndex}: Comment.${key} ${index}` ); } } else { equal(actualComment, item.comment, `${testIndex}: Comment ${index}`); } }); if (pattern.items.length) { 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), /Index out of range\./ ); } }); });