diff options
Diffstat (limited to 'toolkit/components/passwordmgr/test/mochitest/test_formless_submit_form_removal_negative.html')
-rw-r--r-- | toolkit/components/passwordmgr/test/mochitest/test_formless_submit_form_removal_negative.html | 204 |
1 files changed, 204 insertions, 0 deletions
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 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <title>Test no capturing of fields outside of a form due to navigation</title> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <script src="pwmgr_common.js"></script> + <link rel="stylesheet" href="/tests/SimpleTest/test.css" /> +</head> +<body> +<script type="application/javascript"> +SimpleTest.requestFlakyTimeout("Testing that a message doesn't arrive"); + +let loadPromise = new Promise(resolve => { + document.addEventListener("DOMContentLoaded", () => { + document.getElementById("loginFrame").addEventListener("load", (evt) => { + resolve(); + }); + }); +}); + +function submissionProcessed(...args) { + ok(false, "No formSubmissionProcessed should occur in this test"); + info("got: " + JSON.stringify(args)); +} + +add_setup(async () => { + await SpecialPowers.pushPrefEnv({ + set: [ + ["signon.formRemovalCapture.enabled", true], + ], + }); + + info("Waiting for page and frame loads"); + await loadPromise; + + PWMGR_COMMON_PARENT.addMessageListener("formSubmissionProcessed", submissionProcessed); + + SimpleTest.registerCleanupFunction(() => { + PWMGR_COMMON_PARENT.removeMessageListener("formSubmissionProcessed", submissionProcessed); + }); +}); + +const DEFAULT_ORIGIN = "http://test1.mochi.test:8888"; +const SCRIPTS = { + // Test form submission is not triggered when there is no user interaction and + // no ajax request fired previously. + REMOVE_TOP: `let e = document.querySelector("html"); e.parentNode.removeChild(e);`, + + // Test the following scripts don't trigger form submissions because of the + // form removal heuristics + PUSHSTATE: `history.pushState({}, "Pushed state", "?pushed");`, + WINDOW_LOCATION: `window.location = "data:text/html;charset=utf-8,window.location";`, + WINDOW_LOCATION_RELOAD: `window.location.reload();`, + HISTORY_BACK: `history.back();`, + HISTORY_GO_MINUS1: `history.go(-1);`, +}; + +const HEURISTICS = [ + { + userInput: true, + ajaxSuccess: true, + }, + { + userInput: false, + ajaxSuccess: true, + }, + { + userInput: true, + ajaxSuccess: false, + }, + { + userInput: false, + ajaxSuccess: false, + }, +]; + +const TESTCASES = [ + // Begin test cases that shouldn't trigger capture. + { + // Empty password field in a form + document: `<form><input type=password value="xxx"></form>`, + selectorValues: { + "[type=password]": "", + }, + }, + { + // Empty password field + document: `<input type=password value="">`, + selectorValues: { + "[type=password]": "", + }, + }, + { + // Test with an input that would normally be captured but with SCRIPTS that + // shouldn't trigger capture. + document: `<input type=password value="">`, + selectorValues: { + "[type=password]": "pass2", + }, + wouldCapture: true, + }, + { + // Test with an input that would normally be captured but with SCRIPTS that + // shouldn't trigger capture. + document: `<form><input type=password value=""></form>`, + selectorValues: { + "[type=password]": "pass2", + }, + wouldCapture: true, + }, +]; + +async function testFormlesSubmitNavigationNegative(tc, scriptName, heuristic) { + let loginFrame = document.getElementById("loginFrame"); + let waitTime; + let android = navigator.appVersion.includes("Android"); + if (android) { + // intermittent failures on Android Debug at 5 seconds + waitTime = 10000; + } else { + waitTime = 5000; + } + + let loadedPromise = new Promise((resolve) => { + loginFrame.addEventListener("load", function() { + resolve(); + }, {once: true}); + }); + + loginFrame.src = DEFAULT_ORIGIN + "/tests/toolkit/components/passwordmgr/test/mochitest/blank.html"; + await loadedPromise; + + let frameDoc = SpecialPowers.wrap(loginFrame.contentWindow).document; + let formsProcessed = promiseFormsProcessed(); + frameDoc.documentElement.innerHTML = tc.document; + await formsProcessed; + + // We eliminate no user input as a reason for not capturing by modifying the value + setUserInputValues(frameDoc.documentElement, tc.selectorValues, heuristic.userInput); + + if (heuristic.ajaxSuccess) { + await SpecialPowers.spawn(frameDoc.defaultView, [], async () => { + await content.fetch("http://test1.mochi.test:8888/tests/toolkit/components/passwordmgr/test/mochitest/blank.html"); + }); + } + + info("Running " + scriptName + " script to check for a submission"); + frameDoc.defaultView.eval(SCRIPTS[scriptName]); + + info("Running " + scriptName + " script to check for a submission 1"); + // Wait to see if the promise above resolves. + await new Promise(resolve => setTimeout(resolve, waitTime)); + info("Running " + scriptName + " script to check for a submission 2"); + ok(true, "Done waiting for captures"); + +} + +let count = 0; +for (let tc of TESTCASES) { + for (let scriptName of Object.keys(SCRIPTS)) { + for (let heuristic of HEURISTICS) { + let shouldCaptureAFormRemoval = heuristic.ajaxSuccess && heuristic.userInput; + // Only run the following scripts when we are going to observeform removal change + // to save some time running this whole test. + if (["PUSHSTATE", "WINDOW_LOCATION", "WINDOW_LOCATION_RELOAD", "HISTORY_BACK", "HISTORY_GO_MINUS1"].includes(scriptName)) { + if(!shouldCaptureAFormRemoval) { + continue; + } + + if (tc.wouldCapture && ["PUSHSTATE", "WINDOW_LOCATION"].includes(scriptName)) { + // Don't run scripts that should actually capture for this testcase. + continue; + } + } else if (["REMOVE_TOP"].includes(scriptName)) { + if (shouldCaptureAFormRemoval) { + // Don't run scripts that should actually capture for this testcase. + continue; + } + } + + let taskName = `testcase-${count}-${scriptName}`; + let tmp = { + async [taskName]() { + info("Starting testcase with script " + scriptName + ": " + JSON.stringify(tc) + ": " + JSON.stringify(heuristic)); + await testFormlesSubmitNavigationNegative(tc, scriptName, heuristic); + }, + }; + add_task(tmp[taskName]); + } + } +} + + +</script> + +<p id="display"></p> + +<div id="content"> + <iframe id="loginFrame" src="http://test1.mochi.test:8888/tests/toolkit/components/passwordmgr/test/mochitest/blank.html"></iframe> +</div> +<pre id="test"></pre> +</body> +</html> |