From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../passwordmgr/test/mochitest/.eslintrc.js | 17 + .../test/mochitest/auth2/authenticate.sjs | 216 ++++ .../passwordmgr/test/mochitest/chrome_timeout.js | 14 + .../test/mochitest/file_history_back.html | 14 + .../test/mochitest/form_basic_bfcache.html | 58 + ..._DOM_both_fields_together_in_a_shadow_root.html | 31 + ...adow_DOM_each_field_in_its_own_shadow_root.html | 31 + ..._form_and_fields_together_in_a_shadow_root.html | 33 + ..._DOM_both_fields_together_in_a_shadow_root.html | 34 + ...adow_DOM_each_field_in_its_own_shadow_root.html | 38 + ..._form_and_fields_together_in_a_shadow_root.html | 37 + ..._DOM_both_fields_together_in_a_shadow_root.html | 28 + ...adow_DOM_each_field_in_its_own_shadow_root.html | 28 + ..._form_and_fields_together_in_a_shadow_root.html | 30 + .../passwordmgr/test/mochitest/mochitest.toml | 419 +++++++ ...ltiple_forms_shadow_DOM_all_known_variants.html | 111 ++ .../passwordmgr/test/mochitest/pwmgr_common.js | 1175 ++++++++++++++++++++ .../test/mochitest/pwmgr_common_parent.js | 247 ++++ .../passwordmgr/test/mochitest/slow_image.html | 9 + .../passwordmgr/test/mochitest/slow_image.sjs | 25 + .../test/mochitest/subtst_prefilled_form.html | 18 + .../test/mochitest/subtst_primary_pass.html | 8 + .../test/mochitest/subtst_prompt_async.html | 12 + ...d_between_DOMContentLoaded_and_load_events.html | 61 + ...inManagerContent_passwordEditedOrGenerated.html | 160 +++ ...ocomplete_autofill_related_realms_no_dupes.html | 112 ++ .../mochitest/test_autocomplete_basic_form.html | 935 ++++++++++++++++ ...t_autocomplete_basic_form_formActionOrigin.html | 79 ++ .../test_autocomplete_basic_form_insecure.html | 932 ++++++++++++++++ ...est_autocomplete_basic_form_related_realms.html | 112 ++ .../test_autocomplete_hasBeenTypePassword.html | 93 ++ .../mochitest/test_autocomplete_highlight.html | 86 ++ .../test_autocomplete_highlight_non_login.html | 91 ++ ..._autocomplete_highlight_username_only_form.html | 56 + .../test_autocomplete_https_downgrade.html | 105 ++ .../mochitest/test_autocomplete_https_upgrade.html | 191 ++++ .../test_autocomplete_password_generation.html | 596 ++++++++++ ...t_autocomplete_password_generation_confirm.html | 380 +++++++ ...autocomplete_password_generation_telemetry.html | 309 +++++ .../mochitest/test_autocomplete_password_open.html | 90 ++ .../mochitest/test_autocomplete_sandboxed.html | 70 ++ .../test_autocomplete_tab_between_fields.html | 167 +++ .../test_autofill_autocomplete_types.html | 112 ++ .../test_autofill_different_formActionOrigin.html | 91 ++ .../test_autofill_different_subdomain.html | 150 +++ .../test/mochitest/test_autofill_from_bfcache.html | 58 + .../test_autofill_hasBeenTypePassword.html | 64 ++ .../test/mochitest/test_autofill_highlight.html | 58 + .../test_autofill_highlight_empty_username.html | 60 + ...test_autofill_highlight_username_only_form.html | 50 + .../mochitest/test_autofill_https_downgrade.html | 118 ++ .../mochitest/test_autofill_https_upgrade.html | 148 +++ .../mochitest/test_autofill_password-only.html | 133 +++ .../test/mochitest/test_autofill_sandboxed.html | 100 ++ .../test_autofill_tab_between_fields.html | 151 +++ .../mochitest/test_autofill_username-only.html | 107 ++ .../test_autofill_username-only_threshold.html | 83 ++ .../test/mochitest/test_autofocus_js.html | 114 ++ .../test/mochitest/test_basic_form.html | 48 + .../test/mochitest/test_basic_form_0pw.html | 70 ++ .../test/mochitest/test_basic_form_1pw.html | 171 +++ .../test/mochitest/test_basic_form_1pw_2.html | 115 ++ .../test/mochitest/test_basic_form_2pw_1.html | 190 ++++ .../test/mochitest/test_basic_form_2pw_2.html | 111 ++ .../test/mochitest/test_basic_form_3pw_1.html | 259 +++++ .../test_basic_form_honor_autocomplete_off.html | 149 +++ .../test/mochitest/test_basic_form_html5.html | 165 +++ .../test/mochitest/test_basic_form_pwevent.html | 50 + .../test/mochitest/test_basic_form_pwonly.html | 193 ++++ .../test/mochitest/test_bug_627616.html | 163 +++ .../test/mochitest/test_bug_776171.html | 57 + .../test/mochitest/test_case_differences.html | 100 ++ .../test_dismissed_doorhanger_in_shadow_DOM.html | 108 ++ .../test_formLike_rootElement_with_Shadow_DOM.html | 151 +++ .../test/mochitest/test_form_action_1.html | 140 +++ .../test/mochitest/test_form_action_2.html | 173 +++ .../mochitest/test_form_action_javascript.html | 44 + .../test/mochitest/test_formless_autofill.html | 140 +++ .../test/mochitest/test_formless_submit.html | 242 ++++ .../test_formless_submit_form_removal.html | 287 +++++ ...test_formless_submit_form_removal_negative.html | 204 ++++ .../mochitest/test_formless_submit_navigation.html | 267 +++++ .../test_formless_submit_navigation_negative.html | 148 +++ .../test_include_other_subdomains_in_lookup.html | 202 ++++ .../test/mochitest/test_input_events.html | 56 + .../test_input_events_for_identical_values.html | 52 + .../test_insecure_form_field_no_saved_login.html | 91 ++ .../passwordmgr/test/mochitest/test_maxlength.html | 144 +++ .../test/mochitest/test_munged_values.html | 362 ++++++ .../mochitest/test_one_doorhanger_per_un_pw.html | 59 + .../test/mochitest/test_onsubmit_value_change.html | 71 ++ .../test_password_field_autocomplete.html | 185 +++ .../test/mochitest/test_password_length.html | 145 +++ .../mochitest/test_passwords_in_type_password.html | 114 ++ .../test/mochitest/test_primary_password.html | 296 +++++ .../passwordmgr/test/mochitest/test_prompt.html | 669 +++++++++++ .../test/mochitest/test_prompt_async.html | 621 +++++++++++ .../test/mochitest/test_prompt_http.html | 319 ++++++ .../test/mochitest/test_prompt_noWindow.html | 72 ++ .../test/mochitest/test_prompt_promptAuth.html | 370 ++++++ .../mochitest/test_prompt_promptAuth_proxy.html | 269 +++++ .../test/mochitest/test_recipe_login_fields.html | 212 ++++ .../test_set_stored_logins_during_task.html | 50 + .../test_submit_without_field_modifications.html | 311 ++++++ .../test/mochitest/test_username_focus.html | 166 +++ .../passwordmgr/test/mochitest/test_xhr.html | 164 +++ .../passwordmgr/test/mochitest/test_xhr_2.html | 56 + 107 files changed, 17656 insertions(+) create mode 100644 toolkit/components/passwordmgr/test/mochitest/.eslintrc.js create mode 100644 toolkit/components/passwordmgr/test/mochitest/auth2/authenticate.sjs create mode 100644 toolkit/components/passwordmgr/test/mochitest/chrome_timeout.js create mode 100644 toolkit/components/passwordmgr/test/mochitest/file_history_back.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/form_basic_bfcache.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_both_fields_together_in_a_shadow_root.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_each_field_in_its_own_shadow_root.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_form_and_fields_together_in_a_shadow_root.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_both_fields_together_in_a_shadow_root.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_each_field_in_its_own_shadow_root.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_form_and_fields_together_in_a_shadow_root.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_both_fields_together_in_a_shadow_root.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_each_field_in_its_own_shadow_root.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_form_and_fields_together_in_a_shadow_root.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/mochitest.toml create mode 100644 toolkit/components/passwordmgr/test/mochitest/multiple_forms_shadow_DOM_all_known_variants.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js create mode 100644 toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js create mode 100644 toolkit/components/passwordmgr/test/mochitest/slow_image.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/slow_image.sjs create mode 100644 toolkit/components/passwordmgr/test/mochitest/subtst_prefilled_form.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/subtst_primary_pass.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/subtst_prompt_async.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_DOMInputPasswordAdded_fired_between_DOMContentLoaded_and_load_events.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_LoginManagerContent_passwordEditedOrGenerated.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_autofill_related_realms_no_dupes.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_formActionOrigin.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_insecure.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_related_realms.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_hasBeenTypePassword.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight_non_login.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight_username_only_form.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_downgrade.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_upgrade.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_confirm.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_telemetry.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_open.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_sandboxed.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autocomplete_tab_between_fields.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_autocomplete_types.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_different_formActionOrigin.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_different_subdomain.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_from_bfcache.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_hasBeenTypePassword.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight_empty_username.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight_username_only_form.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_https_downgrade.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_https_upgrade.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_password-only.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_sandboxed.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_tab_between_fields.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_username-only.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofill_username-only_threshold.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_autofocus_js.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_basic_form.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_basic_form_0pw.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw_2.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_1.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_2.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_basic_form_3pw_1.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_basic_form_honor_autocomplete_off.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_basic_form_html5.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwevent.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwonly.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_bug_627616.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_bug_776171.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_case_differences.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_dismissed_doorhanger_in_shadow_DOM.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_formLike_rootElement_with_Shadow_DOM.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_form_action_1.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_form_action_2.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_form_action_javascript.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_formless_autofill.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_formless_submit.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_formless_submit_form_removal.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_formless_submit_form_removal_negative.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation_negative.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_include_other_subdomains_in_lookup.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_input_events.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_input_events_for_identical_values.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_no_saved_login.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_maxlength.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_munged_values.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_one_doorhanger_per_un_pw.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_onsubmit_value_change.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_password_length.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_passwords_in_type_password.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_primary_password.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_prompt.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_prompt_async.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_prompt_noWindow.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_recipe_login_fields.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_set_stored_logins_during_task.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_submit_without_field_modifications.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_username_focus.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_xhr.html create mode 100644 toolkit/components/passwordmgr/test/mochitest/test_xhr_2.html (limited to 'toolkit/components/passwordmgr/test/mochitest') diff --git a/toolkit/components/passwordmgr/test/mochitest/.eslintrc.js b/toolkit/components/passwordmgr/test/mochitest/.eslintrc.js new file mode 100644 index 0000000000..beb8ec4738 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/.eslintrc.js @@ -0,0 +1,17 @@ +"use strict"; + +module.exports = { + globals: { + promptDone: true, + startTest: true, + // Make no-undef happy with our runInParent mixed environments since you + // can't indicate a single function is a new env. + assert: true, + addMessageListener: true, + sendAsyncMessage: true, + Assert: true, + }, + rules: { + "no-var": "off", + }, +}; diff --git a/toolkit/components/passwordmgr/test/mochitest/auth2/authenticate.sjs b/toolkit/components/passwordmgr/test/mochitest/auth2/authenticate.sjs new file mode 100644 index 0000000000..bc11bb29f8 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/auth2/authenticate.sjs @@ -0,0 +1,216 @@ +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) { + let match; + let 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. + let query = "?" + request.queryString; + + let expected_user = "", + expected_pass = "", + realm = "mochitest"; + let proxy_expected_user = "", + proxy_expected_pass = "", + proxy_realm = "mochi-proxy"; + let huge = false, + plugin = false, + anonymous = false; + let 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. + + let 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); + } + + let userpass = atob(match[1]); + match = /(.*):(.*)/.exec(userpass); + if (match.length != 3) { + throw new Error("Couldn't decode auth header: " + userpass); + } + actual_user = match[1]; + actual_pass = match[2]; + } + + let 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); + } + + let userpass = atob(match[1]); + 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 (let 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 (let 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(""); + response.write( + "

Login: " + + (requestAuth ? "FAIL" : "PASS") + + "

\n" + ); + response.write( + "

Proxy: " + + (requestProxyAuth ? "FAIL" : "PASS") + + "

\n" + ); + response.write("

Auth: " + authHeader + "

\n"); + response.write("

User: " + actual_user + "

\n"); + response.write("

Pass: " + actual_pass + "

\n"); + + if (huge) { + response.write("
"); + for (let i = 0; i < 100000; i++) { + response.write("123456789\n"); + } + response.write("
"); + response.write( + "This is a footnote after the huge content fill" + ); + } + + if (plugin) { + response.write( + "\n" + ); + } + + response.write(""); +} diff --git a/toolkit/components/passwordmgr/test/mochitest/chrome_timeout.js b/toolkit/components/passwordmgr/test/mochitest/chrome_timeout.js new file mode 100644 index 0000000000..25a797e1d2 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/chrome_timeout.js @@ -0,0 +1,14 @@ +/* eslint-env mozilla/chrome-script */ + +const timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); +addMessageListener("setTimeout", msg => { + timer.init( + _ => { + sendAsyncMessage("timeout"); + }, + msg.delay, + Ci.nsITimer.TYPE_ONE_SHOT + ); +}); + +sendAsyncMessage("ready"); diff --git a/toolkit/components/passwordmgr/test/mochitest/file_history_back.html b/toolkit/components/passwordmgr/test/mochitest/file_history_back.html new file mode 100644 index 0000000000..4e3e071a71 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/file_history_back.html @@ -0,0 +1,14 @@ + + + + + + + This page should navigate back in history upon load. + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/form_basic_bfcache.html b/toolkit/components/passwordmgr/test/mochitest/form_basic_bfcache.html new file mode 100644 index 0000000000..852ff950b6 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/form_basic_bfcache.html @@ -0,0 +1,58 @@ + + + + + + + + + + +
+ + + +
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_both_fields_together_in_a_shadow_root.html b/toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_both_fields_together_in_a_shadow_root.html new file mode 100644 index 0000000000..ab558c4955 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_both_fields_together_in_a_shadow_root.html @@ -0,0 +1,31 @@ + + + + + +
+ + +
+ + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_each_field_in_its_own_shadow_root.html b/toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_each_field_in_its_own_shadow_root.html new file mode 100644 index 0000000000..19edd12330 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_each_field_in_its_own_shadow_root.html @@ -0,0 +1,31 @@ + + + + + +
+ + +
+ + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_form_and_fields_together_in_a_shadow_root.html b/toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_form_and_fields_together_in_a_shadow_root.html new file mode 100644 index 0000000000..225fb4e7f8 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/form_basic_shadow_DOM_form_and_fields_together_in_a_shadow_root.html @@ -0,0 +1,33 @@ + + + + + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_both_fields_together_in_a_shadow_root.html b/toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_both_fields_together_in_a_shadow_root.html new file mode 100644 index 0000000000..876c7d3b85 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_both_fields_together_in_a_shadow_root.html @@ -0,0 +1,34 @@ + + + + + +
+ + + + +
+ + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_each_field_in_its_own_shadow_root.html b/toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_each_field_in_its_own_shadow_root.html new file mode 100644 index 0000000000..9a844f236a --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_each_field_in_its_own_shadow_root.html @@ -0,0 +1,38 @@ + + + + + +
+ + + + + + + +
+ + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_form_and_fields_together_in_a_shadow_root.html b/toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_form_and_fields_together_in_a_shadow_root.html new file mode 100644 index 0000000000..79481c4a3a --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/form_nested_shadow_DOM_form_and_fields_together_in_a_shadow_root.html @@ -0,0 +1,37 @@ + + + + + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_both_fields_together_in_a_shadow_root.html b/toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_both_fields_together_in_a_shadow_root.html new file mode 100644 index 0000000000..ed261af9aa --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_both_fields_together_in_a_shadow_root.html @@ -0,0 +1,28 @@ + + + + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_each_field_in_its_own_shadow_root.html b/toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_each_field_in_its_own_shadow_root.html new file mode 100644 index 0000000000..b0ea0dc486 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_each_field_in_its_own_shadow_root.html @@ -0,0 +1,28 @@ + + + + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_form_and_fields_together_in_a_shadow_root.html b/toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_form_and_fields_together_in_a_shadow_root.html new file mode 100644 index 0000000000..a93e5ea752 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/formless_basic_shadow_DOM_form_and_fields_together_in_a_shadow_root.html @@ -0,0 +1,30 @@ + + + + + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/mochitest.toml b/toolkit/components/passwordmgr/test/mochitest/mochitest.toml new file mode 100644 index 0000000000..86d5d83912 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/mochitest.toml @@ -0,0 +1,419 @@ +[DEFAULT] +prefs = [ + "signon.rememberSignons=true", + "signon.autofillForms.http=true", + "signon.showAutoCompleteFooter=true", + 'signon.showAutoCompleteImport=""', + "signon.testOnlyUserHasInteractedByPrefValue=true", + "signon.testOnlyUserHasInteractedWithDocument=true", + "network.auth.non-web-content-triggered-resources-http-auth-allow=true", + # signon.relatedRealms.enabled pref needed until Bug 1699698 lands + "signon.relatedRealms.enabled=true", + "signon.usernameOnlyForm.enabled=true", + "signon.usernameOnlyForm.lookupThreshold=100", + "security.webauth.webauthn_enable_softtoken=true", + "security.webauth.webauthn_enable_usbtoken=false", + "security.webauthn.enable_conditional_mediation=true", +] +support-files = [ + "../../../prompts/test/chromeScript.js", + "!/toolkit/components/prompts/test/prompt_common.js", + "../../../satchel/test/parent_utils.js", + "!/toolkit/components/satchel/test/satchel_common.js", + "../blank.html", + "../browser/form_autofocus_js.html", + "../browser/form_basic.html", + "../browser/formless_basic.html", + "../browser/form_cross_origin_secure_action.html", + "../browser/form_same_origin_action.html", + "auth2/authenticate.sjs", + "file_history_back.html", + "form_basic_shadow_DOM_both_fields_together_in_a_shadow_root.html", + "form_basic_shadow_DOM_each_field_in_its_own_shadow_root.html", + "form_basic_shadow_DOM_form_and_fields_together_in_a_shadow_root.html", + "form_nested_shadow_DOM_both_fields_together_in_a_shadow_root.html", + "form_nested_shadow_DOM_each_field_in_its_own_shadow_root.html", + "form_nested_shadow_DOM_form_and_fields_together_in_a_shadow_root.html", + "formless_basic_shadow_DOM_both_fields_together_in_a_shadow_root.html", + "formless_basic_shadow_DOM_each_field_in_its_own_shadow_root.html", + "formless_basic_shadow_DOM_form_and_fields_together_in_a_shadow_root.html", + "multiple_forms_shadow_DOM_all_known_variants.html", + "pwmgr_common.js", + "pwmgr_common_parent.js", + "../authenticate.sjs", +] +skip-if = ["os == 'android'"] # Don't run on GeckoView + +# Note: new tests should use scheme = https unless they have a specific reason not to + +["test_DOMInputPasswordAdded_fired_between_DOMContentLoaded_and_load_events.html"] +scheme = "https" +support-files = [ + "slow_image.sjs", + "slow_image.html", +] + +["test_LoginManagerContent_passwordEditedOrGenerated.html"] +scheme = "https" +skip-if = ["os == 'android'"] # password generation + +["test_autocomplete_autofill_related_realms_no_dupes.html"] +skip-if = ["xorigin"] # Bug 1716412 - New fission platform triage +scheme = "https" + +["test_autocomplete_basic_form.html"] +skip-if = [ + "os == 'android'", # autocomplete + "xorigin", # Bug 1716412 - New fission platform triage + "display == 'wayland' && os_version == '22.04'", # Bug 1857071 +] +scheme = "https" + +["test_autocomplete_basic_form_formActionOrigin.html"] +skip-if = [ + "os == 'android'", # android:autocomplete. + "xorigin", # Bug 1716412 - New fission platform triage +] +scheme = "https" + +["test_autocomplete_basic_form_insecure.html"] +skip-if = [ + "os == 'android'", # autocomplete + "xorigin", # Bug 1716412 - New fission platform triage +] + +["test_autocomplete_basic_form_related_realms.html"] +skip-if = ["xorigin"] # Bug 1716412 - New fission platform triage +scheme = "https" + +["test_autocomplete_hasBeenTypePassword.html"] +scheme = "https" +skip-if = ["os == 'android'"] # autocomplete + +["test_autocomplete_highlight.html"] +scheme = "https" +skip-if = ["os == 'android'"] # autocomplete + +["test_autocomplete_highlight_non_login.html"] +scheme = "https" +skip-if = ["os == 'android'"] # autocomplete + +["test_autocomplete_highlight_username_only_form.html"] +scheme = "https" +skip-if = ["os == 'android'"] # autocomplete + +["test_autocomplete_https_downgrade.html"] +scheme = "http" # Tests downgrading +skip-if = [ + "os == 'android'", # autocomplete + "os == 'linux' && debug", # Bug 1554959 + "xorigin", # Bug 1716412 - New fission platform triage +] + +["test_autocomplete_https_upgrade.html"] +scheme = "https" +skip-if = [ + "verify", + "os == 'android'", # autocomplete + "os == 'linux' && debug", # Bug 1554959 for linux debug disable +] + +["test_autocomplete_password_generation.html"] +scheme = "https" +skip-if = [ + "xorigin", + "os == 'android'", # autocomplete +] + +["test_autocomplete_password_generation_confirm.html"] +scheme = "https" +skip-if = ["os == 'android'"] # autocomplete + +["test_autocomplete_password_generation_telemetry.html"] +scheme = "https" +skip-if = [ + "xorigin", + "os == 'android'", # autocomplete +] + +["test_autocomplete_password_open.html"] +scheme = "https" +skip-if = [ + "os == 'android'", # autocomplete + "verify", +] + +["test_autocomplete_sandboxed.html"] +scheme = "https" +skip-if = ["os == 'android'"] # autocomplete + +["test_autocomplete_tab_between_fields.html"] +scheme = "https" +skip-if = [ + "xorigin", + "os == 'android'", # autocomplete +] + +["test_autofill_autocomplete_types.html"] +scheme = "https" +skip-if = ["os == 'android'"] # bug 1533965 + +["test_autofill_different_formActionOrigin.html"] +scheme = "https" +skip-if = ["os == 'android'"] # Bug 1259768 + +["test_autofill_different_subdomain.html"] +scheme = "https" +skip-if = [ + "os == 'android'", # Bug 1259768 + "http3", + "http2", +] + +["test_autofill_from_bfcache.html"] +scheme = "https" +skip-if = ["os == 'android'"] # bug 1527403 +support-files = ["form_basic_bfcache.html"] + +["test_autofill_hasBeenTypePassword.html"] +scheme = "https" + +["test_autofill_highlight.html"] +scheme = "https" +skip-if = ["os == 'android'"] # Bug 1531185 + +["test_autofill_highlight_empty_username.html"] +scheme = "https" + +["test_autofill_highlight_username_only_form.html"] +scheme = "https" + +["test_autofill_https_downgrade.html"] +scheme = "http" # we need http to test handling of https logins on http forms +skip-if = [ + "http3", + "http2", +] + +["test_autofill_https_upgrade.html"] +skip-if = [ + "os == 'android'", # Bug 1259768 + "http3", + "http2", +] + +["test_autofill_password-only.html"] + +["test_autofill_sandboxed.html"] +scheme = "https" +skip-if = ["os == 'android'"] + +["test_autofill_tab_between_fields.html"] +scheme = "https" + +["test_autofill_username-only.html"] + +["test_autofill_username-only_threshold.html"] + +["test_autofocus_js.html"] +scheme = "https" +skip-if = ["os == '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_honor_autocomplete_off.html"] +scheme = "https" +skip-if = [ + "xorigin", + "os == 'android'", # android:autocomplete. +] + +["test_basic_form_html5.html"] + +["test_basic_form_pwevent.html"] +skip-if = ["xorigin"] + +["test_basic_form_pwonly.html"] + +["test_bug_627616.html"] +skip-if = [ + "os == 'android'", # Tests desktop prompts + "http3", + "http2", +] + +["test_bug_776171.html"] + +["test_case_differences.html"] +skip-if = ["os == 'android'"] # autocomplete +scheme = "https" + +["test_dismissed_doorhanger_in_shadow_DOM.html"] +skip-if = ["os == 'android'"] # Tests desktop prompt +scheme = "https" + +["test_formLike_rootElement_with_Shadow_DOM.html"] +scheme = "https" + +["test_form_action_1.html"] + +["test_form_action_2.html"] + +["test_form_action_javascript.html"] + +["test_formless_autofill.html"] +skip-if = [ + "xorigin", + "http3", + "http2", +] + +["test_formless_submit.html"] +skip-if = [ + "os == 'android' && debug", # bug 1397615 + "http3", + "http2", +] + +["test_formless_submit_form_removal.html"] +skip-if = [ + "http3", + "http2", +] + +["test_formless_submit_form_removal_negative.html"] +skip-if = [ + "http3", + "http2", +] + +["test_formless_submit_navigation.html"] +skip-if = [ + "os == 'android' && debug", # bug 1397615 + "http3", + "http2", +] + +["test_formless_submit_navigation_negative.html"] +skip-if = [ + "os == 'android' && debug", # bug 1397615 + "http3", + "http2", +] + +["test_include_other_subdomains_in_lookup.html"] +skip-if = ["os == 'android'"] # android:autocomplete. +scheme = "https" + +["test_input_events.html"] +skip-if = ["xorigin"] + +["test_input_events_for_identical_values.html"] + +["test_insecure_form_field_no_saved_login.html"] +skip-if = ["os == 'android'"] # android:autocomplete. + +["test_maxlength.html"] + +["test_munged_values.html"] +scheme = "https" +skip-if = ["os == 'android'"] # bug 1527403 + +["test_one_doorhanger_per_un_pw.html"] +scheme = "https" +skip-if = ["os == 'android'"] # bug 1535505 + +["test_onsubmit_value_change.html"] + +["test_password_field_autocomplete.html"] +skip-if = ["os == 'android'"] # android:autocomplete. + +["test_password_length.html"] +scheme = "https" +skip-if = ["os == 'android'"] # bug 1527403 + +["test_passwords_in_type_password.html"] + +["test_primary_password.html"] +scheme = "https" +run-if = ["os == 'mac'"] +skip-if = [ + "verify", + "xorigin", # Tests desktop prompts and bug 1333264 +] +support-files = [ + "chrome_timeout.js", + "subtst_primary_pass.html", +] + +["test_prompt.html"] +skip-if = [ + "os == 'linux'", + "os == 'android'", # Tests desktop prompts +] + +["test_prompt_async.html"] +skip-if = [ + "os == 'android'", # Tests desktop prompts + "http3", + "http2", +] +support-files = ["subtst_prompt_async.html"] + +["test_prompt_http.html"] +skip-if = [ + "os == 'android'", # Tests desktop prompts + "os == 'linux'", + "xorigin", # Bug 1716412 - New fission platform triage +] + +["test_prompt_noWindow.html"] +skip-if = ["os == 'android'"] # Tests desktop prompts. + +["test_prompt_promptAuth.html"] +skip-if = [ + "os == 'linux'", + "os == 'android'", # Tests desktop prompts +] + +["test_prompt_promptAuth_proxy.html"] +skip-if = [ + "os == 'linux'", + "os == 'android'", # Tests desktop prompts +] + +["test_recipe_login_fields.html"] +skip-if = ["xorigin"] + +["test_set_stored_logins_during_task.html"] + +["test_submit_without_field_modifications.html"] +support-files = ["subtst_prefilled_form.html"] +skip-if = [ + "xorigin", + "http3", + "http2", +] + +["test_username_focus.html"] +skip-if = [ + "xorigin", + "os == 'android'", # android:autocomplete. +] + +["test_xhr.html"] +skip-if = ["os == 'android'"] # Tests desktop prompts + +["test_xhr_2.html"] diff --git a/toolkit/components/passwordmgr/test/mochitest/multiple_forms_shadow_DOM_all_known_variants.html b/toolkit/components/passwordmgr/test/mochitest/multiple_forms_shadow_DOM_all_known_variants.html new file mode 100644 index 0000000000..5ba547e671 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/multiple_forms_shadow_DOM_all_known_variants.html @@ -0,0 +1,111 @@ + + + + + + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js new file mode 100644 index 0000000000..8b125897a5 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common.js @@ -0,0 +1,1175 @@ +/** + * Helpers for password manager mochitest-plain tests. + */ + +/* import-globals-from ../../../../../toolkit/components/satchel/test/satchel_common.js */ + +const { LoginTestUtils } = SpecialPowers.ChromeUtils.importESModule( + "resource://testing-common/LoginTestUtils.sys.mjs" +); +const Services = SpecialPowers.Services; + +// Setup LoginTestUtils to report assertions to the mochitest harness. +LoginTestUtils.setAssertReporter( + SpecialPowers.wrapCallback((err, message, stack) => { + SimpleTest.record(!err, err ? err.message : message, null, stack); + }) +); + +const { LoginHelper } = SpecialPowers.ChromeUtils.importESModule( + "resource://gre/modules/LoginHelper.sys.mjs" +); + +const { LENGTH: GENERATED_PASSWORD_LENGTH, REGEX: GENERATED_PASSWORD_REGEX } = + LoginTestUtils.generation; +const LOGIN_FIELD_UTILS = LoginTestUtils.loginField; +const TESTS_DIR = "/tests/toolkit/components/passwordmgr/test/"; + +// Depending on pref state we either show auth prompts as windows or on tab level. +let authPromptModalType = SpecialPowers.Services.prefs.getIntPref( + "prompts.modalType.httpAuth" +); + +// Whether the auth prompt is a commonDialog.xhtml or a TabModalPrompt +let authPromptIsCommonDialog = + authPromptModalType === SpecialPowers.Services.prompt.MODAL_TYPE_WINDOW || + (authPromptModalType === SpecialPowers.Services.prompt.MODAL_TYPE_TAB && + SpecialPowers.Services.prefs.getBoolPref( + "prompts.tabChromePromptSubDialog", + false + )); + +/** + * Recreate a DOM tree using the outerHTML to ensure that any event listeners + * and internal state for the elements are removed. + */ +function recreateTree(element) { + // eslint-disable-next-line no-self-assign + element.outerHTML = element.outerHTML; +} + +function _checkArrayValues(actualValues, expectedValues, msg) { + is( + actualValues.length, + expectedValues.length, + "Checking array values: " + msg + ); + for (let i = 0; i < expectedValues.length; i++) { + is(actualValues[i], expectedValues[i], msg + " Checking array entry #" + i); + } +} + +/** + * Check autocomplete popup results to ensure that expected + * *labels* are being shown correctly as items in the popup. + */ +function checkAutoCompleteResults(actualValues, expectedValues, hostname, msg) { + if (hostname === null) { + _checkArrayValues(actualValues, expectedValues, msg); + return; + } + + isnot( + actualValues.length, + 0, + "There should be items in the autocomplete popup: " + + JSON.stringify(actualValues) + ); + + // Check the footer first. + let footerResult = actualValues[actualValues.length - 1]; + is(footerResult, "Manage Passwords", "the footer text is shown correctly"); + + if (actualValues.length == 1) { + is( + expectedValues.length, + 0, + "If only the footer is present then there should be no expectedValues" + ); + info("Only the footer is present in the popup"); + return; + } + + // Check the rest of the autocomplete item values. + _checkArrayValues(actualValues.slice(0, -1), expectedValues, msg); +} + +/** + * Wait for autocomplete popup to get closed + * @return {Promise} resolving when the AC popup is closed + */ +async function untilAutocompletePopupClosed() { + return SimpleTest.promiseWaitForCondition(async () => { + const popupState = await getPopupState(); + return !popupState.open; + }, "Wait for autocomplete popup to be closed"); +} + +function getIframeBrowsingContext(window, iframeNumber = 0) { + let bc = SpecialPowers.wrap(window).windowGlobalChild.browsingContext; + return SpecialPowers.unwrap(bc.children[iframeNumber]); +} + +/** + * Set input values via setUserInput to emulate user input + * and distinguish them from declarative or script-assigned values + */ +function setUserInputValues(parentNode, selectorValues, userInput = true) { + for (let [selector, newValue] of Object.entries(selectorValues)) { + info(`setUserInputValues, selector: ${selector}`); + try { + let field = SpecialPowers.wrap(parentNode.querySelector(selector)); + if (field.value == newValue) { + // we don't get an input event if the new value == the old + field.value += "#"; + } + if (userInput) { + field.setUserInput(newValue); + } else { + field.value = newValue; + } + } catch (ex) { + info(ex.message); + info(ex.stack); + ok( + false, + `setUserInputValues: Couldn't set value of field: ${ex.message}` + ); + } + } +} + +/** + * @param {Function} [aFilterFn = undefined] Function to filter out irrelevant submissions. + * @return {Promise} resolving when a relevant form submission was processed. + */ +function getSubmitMessage(aFilterFn = undefined) { + info("getSubmitMessage"); + return new Promise((resolve, reject) => { + PWMGR_COMMON_PARENT.addMessageListener( + "formSubmissionProcessed", + function processed(...args) { + if (aFilterFn && !aFilterFn(...args)) { + // This submission isn't the one we're waiting for. + return; + } + + info("got formSubmissionProcessed"); + PWMGR_COMMON_PARENT.removeMessageListener( + "formSubmissionProcessed", + processed + ); + resolve(args[0]); + } + ); + }); +} + +/** + * @return {Promise} resolves when a onPasswordEditedOrGenerated message is received at the parent + */ +function getPasswordEditedMessage() { + info("getPasswordEditedMessage"); + return new Promise((resolve, reject) => { + PWMGR_COMMON_PARENT.addMessageListener( + "passwordEditedOrGenerated", + function listener(...args) { + info("got passwordEditedOrGenerated"); + PWMGR_COMMON_PARENT.removeMessageListener( + "passwordEditedOrGenerated", + listener + ); + resolve(args[0]); + } + ); + }); +} + +/** + * Create a login form and insert into contents dom (identified by id + * `content`). If the form (identified by its number) is already present in the + * dom, it gets replaced. + * + * @param {number} [num = 1] - number of the form, used as id, eg `form1` + * @param {string} [action = ""] - action attribute of the form + * @param {string} [autocomplete = null] - forms autocomplete attribute. Default is none + * @param {object} [username = {}] - object describing attributes to the username field: + * @param {string} [username.id = null] - id of the field + * @param {string} [username.name = "uname"] - name attribute + * @param {string} [username.type = "text"] - type of the field + * @param {string} [username.value = null] - initial value of the field + * @param {string} [username.autocomplete = null] - autocomplete attribute + * @param {object} [password = {}] - an object describing attributes to the password field. If falsy, do not create a password field + * @param {string} [password.id = null] - id of the field + * @param {string} [password.name = "pword"] - name attribute + * @param {string} [password.type = "password"] - type of the field + * @param {string} [password.value = null] - initial value of the field + * @param {string} [password.label = null] - if present, wrap field in a label containing its value + * @param {string} [password.autocomplete = null] - autocomplete attribute + * + * @return {HTMLDomElement} the form + */ +function createLoginForm({ + num = 1, + action = "", + autocomplete = null, + username = {}, + password = {}, +} = {}) { + username.name ||= "uname"; + username.type ||= "text"; + username.id ||= null; + username.value ||= null; + username.autocomplete ||= null; + + password.name ||= "pword"; + password.type ||= "password"; + password.id ||= null; + password.value ||= null; + password.label ||= null; + password.autocomplete ||= null; + password.readonly ||= null; + password.disabled ||= null; + + info( + `Creating login form ${JSON.stringify({ num, action, username, password })}` + ); + + const form = document.createElement("form"); + form.id = `form${num}`; + form.action = action; + form.onsubmit = () => false; + + if (autocomplete != null) { + form.setAttribute("autocomplete", autocomplete); + } + + const usernameInput = document.createElement("input"); + + usernameInput.type = username.type; + usernameInput.name = username.name; + + if (username.id != null) { + usernameInput.id = username.id; + } + if (username.value != null) { + usernameInput.value = username.value; + } + if (username.autocomplete != null) { + usernameInput.setAttribute("autocomplete", username.autocomplete); + } + + form.appendChild(usernameInput); + + if (password) { + const passwordInput = document.createElement("input"); + + passwordInput.type = password.type; + passwordInput.name = password.name; + + if (password.id != null) { + passwordInput.id = password.id; + } + if (password.value != null) { + passwordInput.value = password.value; + } + if (password.autocomplete != null) { + passwordInput.setAttribute("autocomplete", password.autocomplete); + } + if (password.readonly != null) { + passwordInput.setAttribute("readonly", password.readonly); + } + if (password.disabled != null) { + passwordInput.setAttribute("disabled", password.disabled); + } + + if (password.label != null) { + const passwordLabel = document.createElement("label"); + passwordLabel.innerText = password.label; + passwordLabel.appendChild(passwordInput); + form.appendChild(passwordLabel); + } else { + form.appendChild(passwordInput); + } + } + + const submitButton = document.createElement("button"); + submitButton.type = "submit"; + submitButton.name = "submit"; + submitButton.innerText = "Submit"; + form.appendChild(submitButton); + + const content = document.getElementById("content"); + + const oldForm = document.getElementById(form.id); + if (oldForm) { + content.replaceChild(form, oldForm); + } else { + content.appendChild(form); + } + + return form; +} + +/** + * Check for expected username/password in form. + * @see `checkForm` below for a similar function. + */ +function checkLoginForm( + usernameField, + expectedUsername, + passwordField, + expectedPassword +) { + let formID = usernameField.parentNode.id; + is( + usernameField.value, + expectedUsername, + "Checking " + formID + " username is: " + expectedUsername + ); + is( + passwordField.value, + expectedPassword, + "Checking " + formID + " password is: " + expectedPassword + ); +} + +/** + * Check repeatedly for a while to see if a particular condition still applies. + * This function checks the return value of `condition` repeatedly until either + * the condition has a falsy return value, or `retryTimes` is exceeded. + */ + +function ensureCondition( + condition, + errorMsg = "Condition did not last.", + retryTimes = 10 +) { + return new Promise((resolve, reject) => { + let tries = 0; + let conditionFailed = false; + let interval = setInterval(async function () { + try { + const conditionPassed = await condition(); + conditionFailed ||= !conditionPassed; + } catch (e) { + ok(false, e + "\n" + e.stack); + conditionFailed = true; + } + if (conditionFailed || tries >= retryTimes) { + ok(!conditionFailed, errorMsg); + clearInterval(interval); + if (conditionFailed) { + reject(errorMsg); + } else { + resolve(); + } + } + tries++; + }, 100); + }); +} + +/** + * Wait a while to ensure login form stays filled with username and password + * @see `checkLoginForm` below for a similar function. + * @returns a promise, resolving when done + * + * TODO: eventually get rid of this time based check, and transition to an + * event based approach. See Bug 1811142. + * Filling happens by `_fillForm()` which can report it's decision and we can + * wait for it. One of the options is to have `didFillFormAsync()` from + * https://phabricator.services.mozilla.com/D167214#change-3njWgUgqswws + */ +function ensureLoginFormStaysFilledWith( + usernameField, + expectedUsername, + passwordField, + expectedPassword +) { + return ensureCondition(() => { + return ( + Object.is(usernameField.value, expectedUsername) && + Object.is(passwordField.value, expectedPassword) + ); + }, `Ensuring form ${usernameField.parentNode.id} stays filled with "${expectedUsername}:${expectedPassword}"`); +} + +function checkLoginFormInFrame( + iframeBC, + usernameFieldId, + expectedUsername, + passwordFieldId, + expectedPassword +) { + return SpecialPowers.spawn( + iframeBC, + [usernameFieldId, expectedUsername, passwordFieldId, expectedPassword], + ( + usernameFieldIdF, + expectedUsernameF, + passwordFieldIdF, + expectedPasswordF + ) => { + let usernameField = + this.content.document.getElementById(usernameFieldIdF); + let passwordField = + this.content.document.getElementById(passwordFieldIdF); + + let formID = usernameField.parentNode.id; + Assert.equal( + usernameField.value, + expectedUsernameF, + "Checking " + formID + " username is: " + expectedUsernameF + ); + Assert.equal( + passwordField.value, + expectedPasswordF, + "Checking " + formID + " password is: " + expectedPasswordF + ); + } + ); +} + +async function checkUnmodifiedFormInFrame(bc, formNum) { + return SpecialPowers.spawn(bc, [formNum], formNumF => { + let form = this.content.document.getElementById(`form${formNumF}`); + ok(form, "Locating form " + formNumF); + + 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 " + formNumF + ); + } + }); +} + +/** + * Check a form for expected values even if it is in a different top level window + * or process. If an argument is null, a field's expected value will be the default + * value. + * + * Similar to the checkForm helper, but it works across (cross-origin) frames. + * + *
+ * checkLoginFormInFrameWithElementValues(#, "foo"); + */ +async function checkLoginFormInFrameWithElementValues( + browsingContext, + formNum, + ...values +) { + return SpecialPowers.spawn( + browsingContext, + [formNum, values], + function checkFormWithElementValues(formNumF, valuesF) { + let [val1F, val2F, val3F] = valuesF; + let doc = this.content.document; + let e; + let form = doc.getElementById("form" + formNumF); + ok(form, "Locating form " + formNumF); + + let numToCheck = arguments.length - 1; + + if (!numToCheck--) { + return; + } + e = form.elements[0]; + if (val1F == null) { + is( + e.value, + e.defaultValue, + "Test default value of field " + e.name + " in form " + formNumF + ); + } else { + is( + e.value, + val1F, + "Test value of field " + e.name + " in form " + formNumF + ); + } + + if (!numToCheck--) { + return; + } + + e = form.elements[1]; + if (val2F == null) { + is( + e.value, + e.defaultValue, + "Test default value of field " + e.name + " in form " + formNumF + ); + } else { + is( + e.value, + val2F, + "Test value of field " + e.name + " in form " + formNumF + ); + } + + if (!numToCheck--) { + return; + } + e = form.elements[2]; + if (val3F == null) { + is( + e.value, + e.defaultValue, + "Test default value of field " + e.name + " in form " + formNumF + ); + } else { + is( + e.value, + val3F, + "Test value of field " + e.name + " in form " + formNumF + ); + } + } + ); +} + +/** + * Check a form for expected values. If an argument is null, a field's + * expected value will be the default value. + * + * + * 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. + * + * + * 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 + ); + } +} + +/** + * Wait for the document to be ready and any existing password fields on + * forms to be processed. + * + * @param existingPasswordFieldsCount the number of password fields + * that begin on the test page. + */ +function registerRunTests(existingPasswordFieldsCount = 0, callback) { + return new Promise(resolve => { + function onDOMContentLoaded() { + 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); + + let foundForcer = false; + var observer = SpecialPowers.wrapCallback(function ( + subject, + topic, + data + ) { + if (data === "observerforcer") { + foundForcer = true; + } else { + existingPasswordFieldsCount--; + } + + if (!foundForcer || existingPasswordFieldsCount > 0) { + return; + } + + SpecialPowers.removeObserver(observer, "passwordmgr-processed-form"); + form.remove(); + SimpleTest.executeSoon(() => { + callback?.(); + resolve(); + }); + }); + SpecialPowers.addObserver(observer, "passwordmgr-processed-form"); + + document.body.appendChild(form); + } + // 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. + if ( + document.readyState == "complete" || + document.readyState == "interactive" + ) { + onDOMContentLoaded(); + } else { + window.addEventListener("DOMContentLoaded", onDOMContentLoaded); + } + }); +} + +function enablePrimaryPassword() { + setPrimaryPassword(true); +} + +function disablePrimaryPassword() { + setPrimaryPassword(false); +} + +function setPrimaryPassword(enable) { + PWMGR_COMMON_PARENT.sendAsyncMessage("setPrimaryPassword", { enable }); +} + +function isLoggedIn() { + return PWMGR_COMMON_PARENT.sendQuery("isLoggedIn"); +} + +function logoutPrimaryPassword() { + runInParent(function parent_logoutPrimaryPassword() { + var sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + sdr.logoutAndTeardown(); + }); +} + +/** + * Resolves when a specified number of forms have been processed for (potential) filling. + * This relies on the observer service which only notifies observers within the same process. + */ +function promiseFormsProcessedInSameProcess(expectedCount = 1) { + var processedCount = 0; + return new Promise((resolve, reject) => { + function onProcessedForm(subject, topic, data) { + processedCount++; + if (processedCount == expectedCount) { + info(`${processedCount} form(s) processed`); + SpecialPowers.removeObserver( + onProcessedForm, + "passwordmgr-processed-form" + ); + resolve(SpecialPowers.Cu.waiveXrays(subject), data); + } + } + SpecialPowers.addObserver(onProcessedForm, "passwordmgr-processed-form"); + }); +} + +/** + * Resolves when a form has been processed for (potential) filling. + * This works across processes. + */ +async function promiseFormsProcessed(expectedCount = 1) { + info(`waiting for ${expectedCount} forms to be processed`); + var processedCount = 0; + return new Promise(resolve => { + PWMGR_COMMON_PARENT.addMessageListener( + "formProcessed", + function formProcessed() { + processedCount++; + info(`processed form ${processedCount} of ${expectedCount}`); + if (processedCount == expectedCount) { + info(`processing of ${expectedCount} forms complete`); + PWMGR_COMMON_PARENT.removeMessageListener( + "formProcessed", + formProcessed + ); + resolve(); + } + } + ); + }); +} + +async function loadFormIntoWindow(origin, html, win, expectedCount = 1, task) { + let loadedPromise = new Promise(resolve => { + win.addEventListener( + "load", + function (event) { + if (event.target.location.href.endsWith("blank.html")) { + resolve(); + } + }, + { once: true } + ); + }); + + let processedPromise = promiseFormsProcessed(expectedCount); + win.location = + origin + "/tests/toolkit/components/passwordmgr/test/mochitest/blank.html"; + info(`Waiting for window to load for origin: ${origin}`); + await loadedPromise; + + await SpecialPowers.spawn( + win, + [html, task?.toString()], + function (contentHtml, contentTask = null) { + this.content.document.documentElement.innerHTML = contentHtml; + // Similar to the invokeContentTask helper in accessible/tests/browser/shared-head.js + if (contentTask) { + // eslint-disable-next-line no-eval + const runnableTask = eval(` + (() => { + return (${contentTask}); + })();`); + runnableTask.call(this); + } + } + ); + + info("Waiting for the form to be processed"); + await processedPromise; +} + +async function getTelemetryEvents(options) { + let events = await PWMGR_COMMON_PARENT.sendQuery( + "getTelemetryEvents", + options + ); + info("CONTENT: getTelemetryEvents gotResult: " + JSON.stringify(events)); + return events; +} + +function loadRecipes(recipes) { + info("Loading recipes"); + return PWMGR_COMMON_PARENT.sendQuery("loadRecipes", recipes); +} + +function resetRecipes() { + info("Resetting recipes"); + return PWMGR_COMMON_PARENT.sendQuery("resetRecipes"); +} + +async function promiseStorageChanged(expectedChangeTypes) { + let result = await PWMGR_COMMON_PARENT.sendQuery("storageChanged", { + expectedChangeTypes, + }); + + if (result) { + ok(false, result); + } +} + +async function promisePromptShown(expectedTopic) { + let topic = await PWMGR_COMMON_PARENT.sendQuery("promptShown"); + is(topic, expectedTopic, "Check expected prompt topic"); +} + +/** + * 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; +} + +/** Manage logins in parent chrome process. + * */ +function manageLoginsInParent() { + return runInParent(function addLoginsInParentInner() { + /* eslint-env mozilla/chrome-script */ + addMessageListener("removeAllUserFacingLogins", () => { + Services.logins.removeAllUserFacingLogins(); + }); + + /* eslint-env mozilla/chrome-script */ + addMessageListener("getLogins", async () => { + const logins = await Services.logins.getAllLogins(); + return logins.map( + ({ + origin, + formActionOrigin, + httpRealm, + username, + password, + usernameField, + passwordField, + }) => [ + origin, + formActionOrigin, + httpRealm, + username, + password, + usernameField, + passwordField, + ] + ); + }); + + /* eslint-env mozilla/chrome-script */ + addMessageListener("addLogins", async logins => { + let nsLoginInfo = Components.Constructor( + "@mozilla.org/login-manager/loginInfo;1", + Ci.nsILoginInfo, + "init" + ); + + const loginInfos = logins.map(login => new nsLoginInfo(...login)); + try { + await Services.logins.addLogins(loginInfos); + } catch (e) { + assert.ok(false, "addLogins threw: " + e); + } + }); + }); +} + +/** Initialize with a list of logins. The logins are added within the parent chrome process. + * @param {array} aLogins - a list of logins to add. Each login is an array of the arguments + * that would be passed to nsLoginInfo.init(). + */ +async function addLoginsInParent(...aLogins) { + const script = manageLoginsInParent(); + await script.sendQuery("addLogins", aLogins); + return script; +} + +/** Initialize with a list of logins, after removing all user facing logins. + * The logins are added within the parent chrome process. + * @param {array} aLogins - a list of logins to add. Each login is an array of the arguments + * that would be passed to nsLoginInfo.init(). + */ +async function setStoredLoginsAsync(...aLogins) { + const script = manageLoginsInParent(); + script.sendQuery("removeAllUserFacingLogins"); + await script.sendQuery("addLogins", aLogins); + return script; +} + +/** + * Sets given logins for the duration of the test. Existing logins are first + * removed and finally restored when the test is finished. + * The logins are added within the parent chrome process. + * @param {array} logins - a list of logins to add. Each login is an array of the arguments + * that would be passed to nsLoginInfo.init(). + */ +async function setStoredLoginsDuringTest(...logins) { + const script = manageLoginsInParent(); + const loginsBefore = await script.sendQuery("getLogins"); + await script.sendQuery("removeAllUserFacingLogins"); + await script.sendQuery("addLogins", logins); + SimpleTest.registerCleanupFunction(async () => { + await script.sendQuery("removeAllUserFacingLogins"); + await script.sendQuery("addLogins", loginsBefore); + }); +} + +/** + * Sets given logins for the duration of the task. Existing logins are first + * removed and finally restored when the task is finished. + * @param {array} logins - a list of logins to add. Each login is an array of the arguments + * that would be passed to nsLoginInfo.init(). + */ +async function setStoredLoginsDuringTask(...logins) { + const script = manageLoginsInParent(); + const loginsBefore = await script.sendQuery("getLogins"); + await script.sendQuery("removeAllUserFacingLogins"); + await script.sendQuery("addLogins", logins); + SimpleTest.registerTaskCleanupFunction(async () => { + await script.sendQuery("removeAllUserFacingLogins"); + await script.sendQuery("addLogins", loginsBefore); + }); +} + +/** Returns a promise which resolves to a list of logins + */ +function getLogins() { + const script = manageLoginsInParent(); + return script.sendQuery("getLogins"); +} + +/* + * gTestDependsOnDeprecatedLogin Set this global to true if your test relies + * on the testuser/testpass login that is created in pwmgr_common.js. New tests + * should not rely on this login. + */ +var gTestDependsOnDeprecatedLogin = false; + +/** + * Replace the content innerHTML with the provided form and wait for autofill to fill in the form. + * + * @param {string} form The form to be appended to the #content element. + * @param {string} fieldSelector The CSS selector for the field to-be-filled + * @param {string} fieldValue The value expected to be filled + * @param {string} formId The ID (excluding the # character) of the form + */ +function setFormAndWaitForFieldFilled( + form, + { fieldSelector, fieldValue, formId } +) { + document.querySelector("#content").innerHTML = form; + return SimpleTest.promiseWaitForCondition(() => { + let ancestor = formId + ? document.querySelector("#" + formId) + : document.documentElement; + return ancestor.querySelector(fieldSelector).value == fieldValue; + }, "Wait for password manager to fill form"); +} + +/** + * Run commonInit synchronously in the parent then run the test function if supplied. + * + * @param {Function} aFunction The test function to run + */ +async function runChecksAfterCommonInit(aFunction = null) { + SimpleTest.waitForExplicitFinish(); + await PWMGR_COMMON_PARENT.sendQuery("setupParent", { + testDependsOnDeprecatedLogin: gTestDependsOnDeprecatedLogin, + }); + + if (aFunction) { + await registerRunTests(0, aFunction); + } + + return PWMGR_COMMON_PARENT; +} + +// Begin code that runs immediately for all tests that include this file. + +const PWMGR_COMMON_PARENT = runInParent( + SimpleTest.getTestFileURL("pwmgr_common_parent.js") +); + +SimpleTest.registerCleanupFunction(() => { + SpecialPowers.flushPrefEnv(); + + PWMGR_COMMON_PARENT.sendAsyncMessage("cleanup"); + + runInParent(function cleanupParent() { + /* eslint-env mozilla/chrome-script */ + // eslint-disable-next-line no-shadow + const { LoginManagerParent } = ChromeUtils.importESModule( + "resource://gre/modules/LoginManagerParent.sys.mjs" + ); + + // Remove all logins and disabled hosts + Services.logins.removeAllUserFacingLogins(); + + 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(); + + // Check that it's not null, instead of truthy to catch it becoming undefined + // in a refactoring. + if (LoginManagerParent._recipeManager !== null) { + 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) { + dump("Removing " + notes.length + " popup notifications.\n"); + } + for (let note of notes) { + note.remove(); + } + } + + // Clear events last in case the above cleanup records events. + Services.telemetry.clearEvents(); + }); +}); + +/** + * 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 PWMGR_COMMON_PARENT.sendQuery("proxyLoginManager", { + args: cloneableArgs, + loginInfoIndices, + methodName: prop, + }); + }; + }, + } +); + +/** + * Set the inner html of the content div and ensure it gets reset after current + * task finishes. + * Returns the first child node of the newly created content div for convenient + * access of the newly created dom node. + * + * @param {String} html + * string of dom content or dom element to be inserted into content element + */ +function setContentForTask(html) { + const content = document.querySelector("#content"); + const innerHTMLBefore = content.innerHTML || ""; + SimpleTest.registerCurrentTaskCleanupFunction( + () => (content.innerHTML = innerHTMLBefore) + ); + if (html.content?.cloneNode) { + const clone = html.content.cloneNode(true); + content.replaceChildren(clone); + } else { + content.innerHTML = html; + } + return content.firstElementChild; +} + +/* + * Set preferences via SpecialPowers.pushPrefEnv and reset them after current + * task has finished. + * + * @param {*Object} preferences + * */ +async function setPreferencesForTask(...preferences) { + await SpecialPowers.pushPrefEnv({ + set: preferences, + }); + SimpleTest.registerCurrentTaskCleanupFunction(() => SpecialPowers.popPrefEnv); +} + +// capture form autofill results between tasks +let gPwmgrCommonCapturedAutofillResults = {}; +PWMGR_COMMON_PARENT.addMessageListener( + "formProcessed", + ({ formId, autofillResult }) => { + if (formId === "observerforcer") { + return; + } + + gPwmgrCommonCapturedAutofillResults[formId] = autofillResult; + } +); +SimpleTest.registerTaskCleanupFunction(() => { + gPwmgrCommonCapturedAutofillResults = {}; +}); + +/** + * Create a promise that resolves when the form has been processed. + * Works with forms processed in the past since the task started and in the future, + * across parent and child processes. + * + * @param {String} formId / the id of the form of which to expect formautofill events + * @returns promise, resolving with the autofill result. + */ +async function formAutofillResult(formId) { + if (formId in gPwmgrCommonCapturedAutofillResults) { + const autofillResult = gPwmgrCommonCapturedAutofillResults[formId]; + delete gPwmgrCommonCapturedAutofillResults[formId]; + return autofillResult; + } + return new Promise((resolve, reject) => { + PWMGR_COMMON_PARENT.addMessageListener( + "formProcessed", + ({ formId: id, autofillResult }) => { + if (id !== formId) { + return; + } + delete gPwmgrCommonCapturedAutofillResults[formId]; + resolve(autofillResult); + }, + { once: true } + ); + }); +} diff --git a/toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js new file mode 100644 index 0000000000..09ad80f467 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/pwmgr_common_parent.js @@ -0,0 +1,247 @@ +/** + * Loaded as a frame script to do privileged things in mochitest-plain tests. + * See pwmgr_common.js for the content process companion. + */ + +/* eslint-env mozilla/chrome-script */ + +"use strict"; + +var { AppConstants } = ChromeUtils.importESModule( + "resource://gre/modules/AppConstants.sys.mjs" +); +var { LoginHelper } = ChromeUtils.importESModule( + "resource://gre/modules/LoginHelper.sys.mjs" +); +var { LoginManagerParent } = ChromeUtils.importESModule( + "resource://gre/modules/LoginManagerParent.sys.mjs" +); +const { LoginTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/LoginTestUtils.sys.mjs" +); +if (LoginHelper.relatedRealmsEnabled) { + let rsPromise = + LoginTestUtils.remoteSettings.setupWebsitesWithSharedCredentials(); + async () => { + await rsPromise; + }; +} +if (LoginHelper.improvedPasswordRulesEnabled) { + let rsPromise = LoginTestUtils.remoteSettings.setupImprovedPasswordRules({ + rules: "", + }); + async () => { + await rsPromise; + }; +} + +/** + * Init with a common login. + */ +async function commonInit(testDependsOnDeprecatedLogin) { + var pwmgr = Services.logins; + assert.ok(pwmgr != null, "Access LoginManager"); + + // Check that initial state has no logins + var logins = await pwmgr.getAllLogins(); + assert.equal(logins.length, 0, "Not expecting logins to be present"); + var disabledHosts = pwmgr.getAllDisabledHosts(); + if (disabledHosts.length) { + assert.ok(false, "Warning: wasn't expecting disabled hosts to be present."); + for (var host of disabledHosts) { + pwmgr.setLoginSavingEnabled(host, true); + } + } + + if (testDependsOnDeprecatedLogin) { + // Add a login that's used in multiple tests + var login = Cc["@mozilla.org/login-manager/loginInfo;1"].createInstance( + Ci.nsILoginInfo + ); + login.init( + "http://mochi.test:8888", + "http://mochi.test:8888", + null, + "testuser", + "testpass", + "uname", + "pword" + ); + await pwmgr.addLoginAsync(login); + } + + // Last sanity check + logins = await pwmgr.getAllLogins(); + assert.equal( + logins.length, + testDependsOnDeprecatedLogin ? 1 : 0, + "Checking for successful init login" + ); + disabledHosts = pwmgr.getAllDisabledHosts(); + assert.equal(disabledHosts.length, 0, "Checking for no disabled hosts"); +} + +async function dumpLogins() { + let logins = await Services.logins.getAllLogins(); + assert.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 += "origin: "; + loginText += login.origin; + loginText += " / formActionOrigin: "; + loginText += login.formActionOrigin; + 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; + assert.ok(true, label + loginText); +} + +addMessageListener("storageChanged", async function ({ expectedChangeTypes }) { + return new Promise((resolve, reject) => { + function storageChanged(subject, topic, data) { + let changeType = expectedChangeTypes.shift(); + if (data != changeType) { + resolve("Unexpected change type " + data + ", expected " + changeType); + } else if (expectedChangeTypes.length === 0) { + Services.obs.removeObserver( + storageChanged, + "passwordmgr-storage-changed" + ); + resolve(); + } + } + + Services.obs.addObserver(storageChanged, "passwordmgr-storage-changed"); + }); +}); + +addMessageListener("promptShown", async function () { + return new Promise(resolve => { + function promptShown(subject, topic, data) { + Services.obs.removeObserver(promptShown, "passwordmgr-prompt-change"); + Services.obs.removeObserver(promptShown, "passwordmgr-prompt-save"); + resolve(topic); + } + + Services.obs.addObserver(promptShown, "passwordmgr-prompt-change"); + Services.obs.addObserver(promptShown, "passwordmgr-prompt-save"); + }); +}); + +addMessageListener("cleanup", () => { + Services.logins.removeAllUserFacingLogins(); +}); + +// Begin message listeners + +addMessageListener( + "setupParent", + async ({ testDependsOnDeprecatedLogin = false } = {}) => { + return commonInit(testDependsOnDeprecatedLogin); + } +); + +addMessageListener("loadRecipes", async function (recipes) { + var recipeParent = await LoginManagerParent.recipeParentPromise; + await recipeParent.load(recipes); + return recipes; +}); + +addMessageListener("resetRecipes", async function () { + let recipeParent = await LoginManagerParent.recipeParentPromise; + await recipeParent.reset(); +}); + +addMessageListener("getTelemetryEvents", options => { + options = Object.assign( + { + filterProps: {}, + clear: false, + }, + options + ); + let snapshots = Services.telemetry.snapshotEvents( + Ci.nsITelemetry.DATASET_PRERELEASE_CHANNELS, + options.clear + ); + let events = options.process in snapshots ? snapshots[options.process] : []; + + // event is array of values like: [22476,"pwmgr","autocomplete_field","generatedpassword"] + let keys = ["id", "category", "method", "object", "value"]; + events = events.filter(entry => { + for (let idx = 0; idx < keys.length; idx++) { + let key = keys[idx]; + if ( + key in options.filterProps && + options.filterProps[key] !== entry[idx] + ) { + return false; + } + } + return true; + }); + + return events; +}); + +addMessageListener("proxyLoginManager", async 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 = await Services.logins[msg.methodName](...recreatedArgs); + if (rv instanceof Ci.nsILoginInfo) { + rv = LoginHelper.loginToVanillaObject(rv); + } else if ( + Array.isArray(rv) && + !!rv.length && + rv[0] instanceof Ci.nsILoginInfo + ) { + rv = rv.map(login => LoginHelper.loginToVanillaObject(login)); + } + return rv; +}); + +addMessageListener("isLoggedIn", () => { + // This can't use the LoginManager proxy in pwmgr_common.js since it's not a method. + return Services.logins.isLoggedIn; +}); + +addMessageListener("setPrimaryPassword", ({ enable }) => { + if (enable) { + LoginTestUtils.primaryPassword.enable(); + } else { + LoginTestUtils.primaryPassword.disable(); + } +}); + +LoginManagerParent.setListenerForTests((msg, { origin, data }) => { + if (msg == "ShowDoorhanger") { + sendAsyncMessage("formSubmissionProcessed", { origin, data }); + } else if (msg == "PasswordEditedOrGenerated") { + sendAsyncMessage("passwordEditedOrGenerated", { origin, data }); + } else if (msg == "FormProcessed") { + sendAsyncMessage("formProcessed", data); + } +}); + +addMessageListener("cleanup", () => { + LoginManagerParent.setListenerForTests(null); +}); diff --git a/toolkit/components/passwordmgr/test/mochitest/slow_image.html b/toolkit/components/passwordmgr/test/mochitest/slow_image.html new file mode 100644 index 0000000000..172d592633 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/slow_image.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/slow_image.sjs b/toolkit/components/passwordmgr/test/mochitest/slow_image.sjs new file mode 100644 index 0000000000..b955e43f5d --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/slow_image.sjs @@ -0,0 +1,25 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +// The delay time will not impact test running time, as the test does +// not wait for the "load" event. We just need to ensure the pwmgr code +// e.g. autofill happens before the delay time elapses. +const DELAY_MS = "5000"; + +let timer; + +function handleRequest(req, resp) { + resp.processAsync(); + resp.setHeader("Cache-Control", "no-cache", false); + resp.setHeader("Content-Type", "image/png", false); + + timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + timer.init( + () => { + resp.write(""); + resp.finish(); + }, + DELAY_MS, + Ci.nsITimer.TYPE_ONE_SHOT + ); +} diff --git a/toolkit/components/passwordmgr/test/mochitest/subtst_prefilled_form.html b/toolkit/components/passwordmgr/test/mochitest/subtst_prefilled_form.html new file mode 100644 index 0000000000..8a3e0b0240 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/subtst_prefilled_form.html @@ -0,0 +1,18 @@ + + + + + + + + + + +
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/subtst_primary_pass.html b/toolkit/components/passwordmgr/test/mochitest/subtst_primary_pass.html new file mode 100644 index 0000000000..dc892c50e2 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/subtst_primary_pass.html @@ -0,0 +1,8 @@ +

MP subtest

+This form triggers a MP and gets filled in.
+
+Username:
+Password:
+
+ diff --git a/toolkit/components/passwordmgr/test/mochitest/subtst_prompt_async.html b/toolkit/components/passwordmgr/test/mochitest/subtst_prompt_async.html new file mode 100644 index 0000000000..39a72add56 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/subtst_prompt_async.html @@ -0,0 +1,12 @@ + + + + + Multiple auth request + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_DOMInputPasswordAdded_fired_between_DOMContentLoaded_and_load_events.html b/toolkit/components/passwordmgr/test/mochitest/test_DOMInputPasswordAdded_fired_between_DOMContentLoaded_and_load_events.html new file mode 100644 index 0000000000..3ab40e92af --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_DOMInputPasswordAdded_fired_between_DOMContentLoaded_and_load_events.html @@ -0,0 +1,61 @@ + + + + + Test the password manager code called on DOMInputPasswordAdded runs when it occurs between DOMContentLoaded and load events + + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_LoginManagerContent_passwordEditedOrGenerated.html b/toolkit/components/passwordmgr/test/mochitest/test_LoginManagerContent_passwordEditedOrGenerated.html new file mode 100644 index 0000000000..9d23177924 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_LoginManagerContent_passwordEditedOrGenerated.html @@ -0,0 +1,160 @@ + + + + + Test behavior of unmasking in LMC._passwordEditedOrGenerated + + + + + + + +

+
+

+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_autofill_related_realms_no_dupes.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_autofill_related_realms_no_dupes.html
new file mode 100644
index 0000000000..b229993a42
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_autofill_related_realms_no_dupes.html
@@ -0,0 +1,112 @@
+
+
+
+  
+  Login Manager: Related Realms
+  
+  
+  
+  
+
+
+

+
+
+Testing related realms
+
+Related realms is feature to provide login suggestion based on similar domains.
+
+Out of the scope of this feature is subdomain handling, which is already part
+of the base functionality. The intent is to cover the ebay.com/ebay.co.uk and
+all other country TLD cases where the sign in page is actually
+signin.ebay.com/signin.ebay.co.uk but credentials could have manually been
+entered for ebay.com/ebay.co.uk or automatically stored as
+signin.ebay.com/sigin.ebay.co.uk
+
+The related realms feature can be enabled via the preference
+signon.relatedRealms.enabled. It is disabled by default.
+
+This test proves that related logins show up in the autocomplete menu when
+the feature is enabled and that the related logins do not count as duplicates
+and therefore the form gets filled directly.
+
+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form.html new file mode 100644 index 0000000000..cfa695e002 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form.html @@ -0,0 +1,935 @@ + + + + + Login Manager: test basic login autocomplete + + + + + + + + +

+
+
+Test for Login Manager: login autocomplete, with secure connection. This tests autocomplete menu items, its navigation, the selection and deletion of entries as well as sending untrusted events.
+
+This tests the login manager in a secure setting using https. A similar test file exists for using an insecure connection: test_autocomplete_basic_form_insecure.html.
+
+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_formActionOrigin.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_formActionOrigin.html new file mode 100644 index 0000000000..0365d5369c --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_formActionOrigin.html @@ -0,0 +1,79 @@ + + + + + Test that logins with non-matching formActionOrigin appear in autocomplete dropdown + + + + + + + +

+
+
+Login Manager test: logins with non-matching formActionOrigin appear in autocomplete dropdown
+
+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_insecure.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_insecure.html new file mode 100644 index 0000000000..156a89f77a --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_insecure.html @@ -0,0 +1,932 @@ + + + + + Test insecure form field autocomplete + + + + + + + +

+
+
+Test for Login Manager: login autocomplete, with insecure connection. This tests autocomplete menu items, its navigation, the selection and deletion of entries as well as sending untrusted events.
+
+This tests the login manager in a insecure setting using http. A similar test file exists for using a secure connection: test_autocomplete_basic_form.html.
+
+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_related_realms.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_related_realms.html new file mode 100644 index 0000000000..1dcd8b116e --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_basic_form_related_realms.html @@ -0,0 +1,112 @@ + + + + + Test login autocomplete with related realms + + + + + + + +

+
+
+Login Manager test: related realms autocomplete
+
+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_hasBeenTypePassword.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_hasBeenTypePassword.html new file mode 100644 index 0000000000..0eb2beadc7 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_hasBeenTypePassword.html @@ -0,0 +1,93 @@ + + + + + Test that passwords are autocompleted into fields that were previously type=password + + + + + + + +

+
+
+Login Manager test: Test that passwords are autocompleted into fields that were
+previously type=password
+
+Usually the autocomplete login form only operates on password fields which are
+of type `password`. But when a password fields type has been changed to `text`
+via JavaScript, the password manager should still fill this form, because this
+is often used in real world forms to handle masking/unmasking of password
+fields.
+
+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html new file mode 100644 index 0000000000..49cedde0bc --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight.html @@ -0,0 +1,86 @@ + + + + + Test form field autofill highlight + + + + + + + +

+
+
+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight_non_login.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight_non_login.html
new file mode 100644
index 0000000000..eb82e90656
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight_non_login.html
@@ -0,0 +1,91 @@
+
+
+
+  
+  Test form field autofill highlight
+  
+  
+  
+  
+  
+
+
+

+
+
+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight_username_only_form.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight_username_only_form.html
new file mode 100644
index 0000000000..2451f47308
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_highlight_username_only_form.html
@@ -0,0 +1,56 @@
+
+
+
+  
+  Test form field autofill highlight
+  
+  
+  
+  
+  
+
+
+

+
+
+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_downgrade.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_downgrade.html
new file mode 100644
index 0000000000..44d830afe5
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_downgrade.html
@@ -0,0 +1,105 @@
+
+
+
+  
+  Test autocomplete on an HTTPS page using upgraded HTTP logins
+  
+  
+  
+  
+  
+
+
+

+ + +
+ +
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_upgrade.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_upgrade.html new file mode 100644 index 0000000000..a0a81a8c88 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_https_upgrade.html @@ -0,0 +1,191 @@ + + + + + Test autocomplete on an HTTPS page using upgraded HTTP logins + + + + + + + +

+ + +
+ +
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation.html new file mode 100644 index 0000000000..3fd8b1e90b --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation.html @@ -0,0 +1,596 @@ + + + + + Test autofill and autocomplete on autocomplete=new-password fields + + + + + + + +

+
+
+Login Manager test: autofill with password generation on `autocomplete=new-password` fields.
+
+
+
+
+
+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_confirm.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_confirm.html new file mode 100644 index 0000000000..54cb450815 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_confirm.html @@ -0,0 +1,380 @@ + + + + + Test filling generated passwords into confirm password fields + + + + + + + +

+
+
+Login Manager test: filling generated passwords into confirm password fields
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_telemetry.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_telemetry.html new file mode 100644 index 0000000000..4bbba09483 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_generation_telemetry.html @@ -0,0 +1,309 @@ + + + + + Test telemetry on autofill and autocomplete on autocomplete=new-password fields + + + + + + + + +

+
+
+Login Manager test: telemetry events during autofill with password generation on `autocomplete=new-password` fields.
+
+
+
+
+
+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_open.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_open.html new file mode 100644 index 0000000000..e792aa19af --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_password_open.html @@ -0,0 +1,90 @@ + + + + + Test password field autocomplete footer with and without logins + + + + + + + +

+ +
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_sandboxed.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_sandboxed.html new file mode 100644 index 0000000000..229791109a --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_sandboxed.html @@ -0,0 +1,70 @@ + + + + + Test form field autocomplete in sandboxed documents (null principal) + + + + + + + +

+ + +
+ +
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_tab_between_fields.html b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_tab_between_fields.html new file mode 100644 index 0000000000..4a0aaff0b3 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autocomplete_tab_between_fields.html @@ -0,0 +1,167 @@ + + + + + Test autocomplete behavior when tabbing between form fields + + + + + + + +

+ + +
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_autocomplete_types.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_autocomplete_types.html new file mode 100644 index 0000000000..c44d5a25ef --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_autocomplete_types.html @@ -0,0 +1,112 @@ + + + + + Test autofilling with autocomplete types (username, off, cc-type, etc.) + + + + + +Test autofilling with autocomplete types (username, off, cc-type, etc.) + +

+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_different_formActionOrigin.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_different_formActionOrigin.html new file mode 100644 index 0000000000..1ea43f6a8f --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_different_formActionOrigin.html @@ -0,0 +1,91 @@ + + + + + Test autofill on an HTTPS page using upgraded HTTP logins with different formActionOrigin + + + + + + + +

+ + +
+
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_different_subdomain.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_different_subdomain.html new file mode 100644 index 0000000000..66c6ab3536 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_different_subdomain.html @@ -0,0 +1,150 @@ +xcod + + + + Test autofill on an HTTPS page using logins with different eTLD+1 + + + + + + + +

+ + +
+ +
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_from_bfcache.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_from_bfcache.html new file mode 100644 index 0000000000..d0fcb16e18 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_from_bfcache.html @@ -0,0 +1,58 @@ + + + + + Test autofilling documents restored from the back/forward cache (bfcache) + + + + +

+ +
+ +
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_hasBeenTypePassword.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_hasBeenTypePassword.html new file mode 100644 index 0000000000..2139d30e61 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_hasBeenTypePassword.html @@ -0,0 +1,64 @@ + + + + + Test no autofill into a password field that is no longer type=password + + + + + +Login Manager test: Test no autofill into a password field that is no longer type=password + + + +

+ +
+ +

+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight.html
new file mode 100644
index 0000000000..3ca214841c
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight.html
@@ -0,0 +1,58 @@
+
+
+
+  
+  Test form field autofill highlight
+  
+  
+  
+  
+
+
+

+
+
+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight_empty_username.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight_empty_username.html
new file mode 100644
index 0000000000..36fffb480b
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight_empty_username.html
@@ -0,0 +1,60 @@
+
+
+
+  
+  Test that filling an empty username into a form does not highlight the username element
+  
+  
+  
+  
+
+
+
+

+
+
+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight_username_only_form.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight_username_only_form.html
new file mode 100644
index 0000000000..67892a9ea4
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_highlight_username_only_form.html
@@ -0,0 +1,50 @@
+
+
+
+  
+  Test that filling a username into a username-only form does highlight the username element
+  
+  
+  
+  
+
+
+

+
+
+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_downgrade.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_downgrade.html
new file mode 100644
index 0000000000..091f9c8ad6
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_downgrade.html
@@ -0,0 +1,118 @@
+
+
+
+  
+  Test we don't autofill on an HTTP page using HTTPS logins
+  
+  
+  
+  
+
+
+
+

+ + +
+
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_upgrade.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_upgrade.html new file mode 100644 index 0000000000..a8691ebe54 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_https_upgrade.html @@ -0,0 +1,148 @@ + + + + + Test autofill on an HTTPS page using upgraded HTTP logins + + + + + + + +

+ + +
+
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_password-only.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_password-only.html new file mode 100644 index 0000000000..47f53bb65b --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_password-only.html @@ -0,0 +1,133 @@ + + + + + Test password-only forms should prefer a password-only login when present + + + + + +Login Manager test: Bug 444968 + + +

+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_sandboxed.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_sandboxed.html new file mode 100644 index 0000000000..ef4dfdb417 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_sandboxed.html @@ -0,0 +1,100 @@ + + + + + Test form field autofill in sandboxed documents (null principal) + + + + + + + +

+ +
+ +
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_tab_between_fields.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_tab_between_fields.html new file mode 100644 index 0000000000..c88a6713f4 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_tab_between_fields.html @@ -0,0 +1,151 @@ + + + + + Test autocomplete behavior when tabbing between form fields + + + + + + + + +

+ + +
+
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_username-only.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_username-only.html new file mode 100644 index 0000000000..860c317409 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_username-only.html @@ -0,0 +1,107 @@ + + + + + Test autofill on username-form + + + + + +Test autofill on username-form + + + +

+
+

+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofill_username-only_threshold.html b/toolkit/components/passwordmgr/test/mochitest/test_autofill_username-only_threshold.html new file mode 100644 index 0000000000..d9a2e08095 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_autofill_username-only_threshold.html @@ -0,0 +1,83 @@ + + + + + Test autofill on username-form when the number of form exceeds the lookup threshold + + + + + +Test not autofill on username-form when the number of form exceeds the lookup threshold + + + +

+
+

+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_autofocus_js.html b/toolkit/components/passwordmgr/test/mochitest/test_autofocus_js.html
new file mode 100644
index 0000000000..803197c2a2
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_autofocus_js.html
@@ -0,0 +1,114 @@
+
+
+
+  
+  Test login autocomplete is activated when focused by js on load
+  
+  
+  
+  
+  
+
+
+

+ +
+ +
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form.html new file mode 100644 index 0000000000..d13fd1369f --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form.html @@ -0,0 +1,48 @@ + + + + + Test basic autofill + + + + + +Login Manager test: simple form fill + + + +

+ + + +

+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_0pw.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_0pw.html
new file mode 100644
index 0000000000..64450300d6
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_0pw.html
@@ -0,0 +1,70 @@
+
+
+
+  
+  Test forms with no password fields
+  
+  
+  
+  
+
+
+Login Manager test: forms with no password fields
+

+ + + +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html new file mode 100644 index 0000000000..bb91d9cf3e --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw.html @@ -0,0 +1,171 @@ + + + + + Test autofill for forms with 1 password field + + + + + +Login Manager test: forms with 1 password field + +

+ + + +
+
+
+ + 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 new file mode 100644 index 0000000000..d7aaadc895 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_1pw_2.html @@ -0,0 +1,115 @@ + + + + + Test forms with 1 password field, part 2 + + + + + +Login Manager test: forms with 1 password field, part 2 + +

+ + + +
+
+
+ + 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 new file mode 100644 index 0000000000..1d9224a819 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_1.html @@ -0,0 +1,190 @@ + + + + + Test autofill for forms with 2 password fields + + + + + +Login Manager test: forms with 2 password fields + +

+ + + +
+
+
+ + 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 new file mode 100644 index 0000000000..a2c60e5964 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_2pw_2.html @@ -0,0 +1,111 @@ + + + + + Test for form fill with 2 password fields + + + + + + +Login Manager test: form fill, 2 password fields +

+ +
+
+
+ + + + 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 new file mode 100644 index 0000000000..59aec20612 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_3pw_1.html @@ -0,0 +1,259 @@ + + + + + Test autofill for forms with 3 password fields + + + + + +Login Manager test: forms with 3 password fields (form filling) + +

+ + + +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_honor_autocomplete_off.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_honor_autocomplete_off.html new file mode 100644 index 0000000000..42214485c8 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_honor_autocomplete_off.html @@ -0,0 +1,149 @@ + + + + + Test login autofill autocomplete when signon.autofillForms.autocompleteOff is false + + + + + + + +Login Manager test: autofilling when autocomplete=off +

+ + +
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_html5.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_html5.html new file mode 100644 index 0000000000..12aeb0bab3 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_html5.html @@ -0,0 +1,165 @@ + + + + + Test for html5 input types (email, tel, url, etc.) + + + + + +Login Manager test: html5 input types (email, tel, url, etc.) + + +

+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwevent.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwevent.html new file mode 100644 index 0000000000..4a202a7c05 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwevent.html @@ -0,0 +1,50 @@ + + + + + + Test for Bug 355063 + + + + + + +Mozilla Bug 355063 +

+
+forms go here! +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwonly.html b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwonly.html new file mode 100644 index 0000000000..ec9557d2c3 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_basic_form_pwonly.html @@ -0,0 +1,193 @@ + + + + + Test forms and logins without a username + + + + + +Login Manager test: forms and logins without a username. +

+ + + +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_bug_627616.html b/toolkit/components/passwordmgr/test/mochitest/test_bug_627616.html new file mode 100644 index 0000000000..429ec2269c --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_bug_627616.html @@ -0,0 +1,163 @@ + + + + + Test bug 627616 related to proxy authentication + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_bug_776171.html b/toolkit/components/passwordmgr/test/mochitest/test_bug_776171.html new file mode 100644 index 0000000000..f7de66a01d --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_bug_776171.html @@ -0,0 +1,57 @@ + + + + + + Test for Bug 776171 related to HTTP auth + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_case_differences.html b/toolkit/components/passwordmgr/test/mochitest/test_case_differences.html new file mode 100644 index 0000000000..8a8499b584 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_case_differences.html @@ -0,0 +1,100 @@ + + + + + Test autocomplete due to multiple matching logins + + + + + + + +Login Manager test: autocomplete due to multiple matching logins +

+ +
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_dismissed_doorhanger_in_shadow_DOM.html b/toolkit/components/passwordmgr/test/mochitest/test_dismissed_doorhanger_in_shadow_DOM.html new file mode 100644 index 0000000000..87638b1132 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_dismissed_doorhanger_in_shadow_DOM.html @@ -0,0 +1,108 @@ + + + + + Test the password manager dismissed doorhanger can detect username and password fields in a Shadow DOM. + + + + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_formLike_rootElement_with_Shadow_DOM.html b/toolkit/components/passwordmgr/test/mochitest/test_formLike_rootElement_with_Shadow_DOM.html new file mode 100644 index 0000000000..06458893ea --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_formLike_rootElement_with_Shadow_DOM.html @@ -0,0 +1,151 @@ + + + + + Test that FormLike.rootElement points to right element when the page has Shadow DOM + + + + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_form_action_1.html b/toolkit/components/passwordmgr/test/mochitest/test_form_action_1.html new file mode 100644 index 0000000000..21f5f18904 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_form_action_1.html @@ -0,0 +1,140 @@ + + + + + Test for considering form action + + + + + +Login Manager test: Bug 360493 + +

+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_form_action_2.html b/toolkit/components/passwordmgr/test/mochitest/test_form_action_2.html new file mode 100644 index 0000000000..2eae0958ca --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_form_action_2.html @@ -0,0 +1,173 @@ + + + + + Test for considering form action + + + + + +Login Manager test: Bug 360493 + +

+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_form_action_javascript.html b/toolkit/components/passwordmgr/test/mochitest/test_form_action_javascript.html new file mode 100644 index 0000000000..717805f06a --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_form_action_javascript.html @@ -0,0 +1,44 @@ + + + + + Test forms with a JS submit action + + + + + +Login Manager test: form with JS submit action + + +

+ + + +

+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_formless_autofill.html b/toolkit/components/passwordmgr/test/mochitest/test_formless_autofill.html
new file mode 100644
index 0000000000..4d1b7582a9
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_formless_autofill.html
@@ -0,0 +1,140 @@
+
+
+
+  
+  Test autofilling of fields outside of a form
+  
+  
+  
+
+
+
+
+

+ +
+ +
+

+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit.html b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit.html
new file mode 100644
index 0000000000..4e98fd1b9a
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit.html
@@ -0,0 +1,242 @@
+
+
+
+  
+  Test capturing of fields outside of a form
+  
+  
+  
+
+
+
+
+

+ +
+ +
+

+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_form_removal.html b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_form_removal.html
new file mode 100644
index 0000000000..5512c57db2
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_form_removal.html
@@ -0,0 +1,287 @@
+
+
+
+  
+  Test capturing of fields due to form removal
+  
+  
+  
+
+
+
+
+

+ +
+ +
+

+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_form_removal_negative.html b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_form_removal_negative.html
new file mode 100644
index 0000000000..dfd7670a12
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_form_removal_negative.html
@@ -0,0 +1,204 @@
+
+
+
+  
+  Test no capturing of fields outside of a form due to navigation
+  
+  
+  
+
+
+
+
+

+ +
+ +
+

+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation.html b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation.html
new file mode 100644
index 0000000000..348669a85c
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation.html
@@ -0,0 +1,267 @@
+
+
+
+  
+  Test capturing of fields outside of a form due to navigation
+  
+  
+  
+
+
+
+
+

+ +
+ +
+

+
+
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
new file mode 100644
index 0000000000..338cd5d2c1
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation_negative.html
@@ -0,0 +1,148 @@
+
+
+
+  
+  Test no capturing of fields outside of a form due to navigation
+  
+  
+  
+
+
+
+
+

+ +
+ +
+

+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_include_other_subdomains_in_lookup.html b/toolkit/components/passwordmgr/test/mochitest/test_include_other_subdomains_in_lookup.html
new file mode 100644
index 0000000000..4c569463c5
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_include_other_subdomains_in_lookup.html
@@ -0,0 +1,202 @@
+
+
+
+  
+  Test includeOtherSubdomainsInLookup
+  
+  
+  
+  
+  
+
+
+

+
+
+  Test that logins with non-exact match origin appear in autocomplete dropdown.
+
+  The includeOtherSubdomainsInLookup feature offers autocomplete results for
+  subdomain related logins.
+
+  For this testcase, there exists two logins for this origin on different
+  subdomains (old.example.com and new.example.com) but with different
+  passwords, beneath one login for the parent domain (example.com). Both
+  logins should appear in the autocomplete popup.
+
+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_input_events.html b/toolkit/components/passwordmgr/test/mochitest/test_input_events.html new file mode 100644 index 0000000000..2560c212d8 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_input_events.html @@ -0,0 +1,56 @@ + + + + + Test for input events in Login Manager + + + + + + +Login Manager test: input events should fire. +

+ +

+
+
+
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
new file mode 100644
index 0000000000..c6e378a516
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_input_events_for_identical_values.html
@@ -0,0 +1,52 @@
+
+
+
+  
+  Test for input events in Login Manager when username/password are filled in already
+  
+  
+  
+  
+  
+
+
+Login Manager test: input events should fire.
+
+
+
+

+ +
+ +
+

This is form 1.

+ + + + + +
+ +
+

+
+
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
new file mode 100644
index 0000000000..8fcb9df6f6
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_insecure_form_field_no_saved_login.html
@@ -0,0 +1,91 @@
+
+
+
+  
+  Test basic login, contextual inscure password warning without saved logins
+  
+  
+  
+  
+  
+
+
+Login Manager test: contextual inscure password warning without saved logins
+
+
+

+ + +
+ +
+ + + +
+ +
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_maxlength.html b/toolkit/components/passwordmgr/test/mochitest/test_maxlength.html new file mode 100644 index 0000000000..a61812f6d3 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_maxlength.html @@ -0,0 +1,144 @@ + + + + + Test for maxlength attributes + + + + + +Login Manager test: Bug 391514 + +

+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_munged_values.html b/toolkit/components/passwordmgr/test/mochitest/test_munged_values.html new file mode 100644 index 0000000000..d2fdf91d4a --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_munged_values.html @@ -0,0 +1,362 @@ + + + + + Test handling of possibly-manipulated username values + + + + + + + + +

+ +
+
+

+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_one_doorhanger_per_un_pw.html b/toolkit/components/passwordmgr/test/mochitest/test_one_doorhanger_per_un_pw.html
new file mode 100644
index 0000000000..4d8dfd1fee
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_one_doorhanger_per_un_pw.html
@@ -0,0 +1,59 @@
+
+
+
+  
+  Don't repeatedly prompt to save the same username and password
+    combination in the same document
+  
+  
+  
+
+
+
+

+ + + +

+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_onsubmit_value_change.html b/toolkit/components/passwordmgr/test/mochitest/test_onsubmit_value_change.html
new file mode 100644
index 0000000000..18b851c86f
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_onsubmit_value_change.html
@@ -0,0 +1,71 @@
+
+
+
+  
+  Test input value change right after onsubmit event
+  
+  
+  
+  
+
+
+Login Manager test: input value change right after onsubmit event
+
+
+

+ + + +

+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html b/toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html
new file mode 100644
index 0000000000..cb7f759cab
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_password_field_autocomplete.html
@@ -0,0 +1,185 @@
+
+
+
+  
+  Test basic login autocomplete
+  
+  
+  
+  
+  
+
+
+Login Manager test: multiple login autocomplete
+

+ + +
+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_password_length.html b/toolkit/components/passwordmgr/test/mochitest/test_password_length.html new file mode 100644 index 0000000000..724caf236f --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_password_length.html @@ -0,0 +1,145 @@ + + + + + Test handling of different password length + + + + + + + +

+ +
+ +
+

+
+
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
new file mode 100644
index 0000000000..fcaeb0e455
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_passwords_in_type_password.html
@@ -0,0 +1,114 @@
+
+
+
+  
+  Test that passwords only get filled in type=password
+  
+  
+  
+
+
+Login Manager test: Bug 242956
+
+

+ +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_primary_password.html b/toolkit/components/passwordmgr/test/mochitest/test_primary_password.html new file mode 100644 index 0000000000..4da6929b61 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_primary_password.html @@ -0,0 +1,296 @@ + + + + + Test for primary password + + + + + + +Login Manager test: primary password. + +

+ + + +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt.html new file mode 100644 index 0000000000..12d3a7d080 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_prompt.html @@ -0,0 +1,669 @@ + + + + + Test prompter.{prompt,asyncPromptPassword,asyncPromptUsernameAndPassword} + + + + + + +

+ + + +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt_async.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt_async.html new file mode 100644 index 0000000000..41a58cb416 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_prompt_async.html @@ -0,0 +1,621 @@ + + + + + Test for Async Auth Prompt + + + + + + + + + + + + + + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html new file mode 100644 index 0000000000..f6f6e681dc --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_prompt_http.html @@ -0,0 +1,319 @@ + + + + + Test HTTP auth prompts by loading authenticate.sjs + + + + + + +

+ + + +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt_noWindow.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt_noWindow.html new file mode 100644 index 0000000000..19d05e47e5 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_prompt_noWindow.html @@ -0,0 +1,72 @@ + + + + + Test HTTP auth prompts by loading authenticate.sjs with no window + + + + + + +

+ + + +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth.html new file mode 100644 index 0000000000..b82ea67faa --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth.html @@ -0,0 +1,370 @@ + + + + + Test promptAuth prompts + + + + + + +

+ + + +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html b/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html new file mode 100644 index 0000000000..6f78d62f1b --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_prompt_promptAuth_proxy.html @@ -0,0 +1,269 @@ + + + + + Test promptAuth proxy prompts + + + + + + +

+ + + +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_recipe_login_fields.html b/toolkit/components/passwordmgr/test/mochitest/test_recipe_login_fields.html new file mode 100644 index 0000000000..818a4e15bf --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_recipe_login_fields.html @@ -0,0 +1,212 @@ + + + + + Test for recipes overriding login fields + + + + + + + +

+ +
+ // Forms are inserted dynamically +
+

+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_set_stored_logins_during_task.html b/toolkit/components/passwordmgr/test/mochitest/test_set_stored_logins_during_task.html
new file mode 100644
index 0000000000..36db568708
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_set_stored_logins_during_task.html
@@ -0,0 +1,50 @@
+
+
+
+  
+  Login Manager Test Helper: setLoginsDuringTest
+  
+  
+  
+  
+
+
+

+
+
+Testing the test helpers `setStoredLoginsDuringTask` and `setStoredLoginsDuringTest`, which prepares the login storage during a test or task.
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_submit_without_field_modifications.html b/toolkit/components/passwordmgr/test/mochitest/test_submit_without_field_modifications.html new file mode 100644 index 0000000000..c31efe6a98 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_submit_without_field_modifications.html @@ -0,0 +1,311 @@ + + + + + Don't send onFormSubmit message on navigation if the user did not interact + with the login fields + + + + + +

+ +
+ +
+ +

+
+
+
diff --git a/toolkit/components/passwordmgr/test/mochitest/test_username_focus.html b/toolkit/components/passwordmgr/test/mochitest/test_username_focus.html
new file mode 100644
index 0000000000..9c2f9d8e89
--- /dev/null
+++ b/toolkit/components/passwordmgr/test/mochitest/test_username_focus.html
@@ -0,0 +1,166 @@
+
+
+
+
+  
+  Test interaction between autocomplete and focus on username fields
+  
+  
+  
+  
+  
+
+
+

+
+
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_xhr.html b/toolkit/components/passwordmgr/test/mochitest/test_xhr.html new file mode 100644 index 0000000000..811a2e7759 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_xhr.html @@ -0,0 +1,164 @@ + + + + + Test for XHR prompts + + + + + + +Login Manager test: XHR prompt +

+ + + +
+
+
+ + diff --git a/toolkit/components/passwordmgr/test/mochitest/test_xhr_2.html b/toolkit/components/passwordmgr/test/mochitest/test_xhr_2.html new file mode 100644 index 0000000000..16d5e786e0 --- /dev/null +++ b/toolkit/components/passwordmgr/test/mochitest/test_xhr_2.html @@ -0,0 +1,56 @@ + + + + + + Test XHR auth with user and pass arguments + + + + + + + + -- cgit v1.2.3