summaryrefslogtreecommitdiffstats
path: root/toolkit/components/passwordmgr/test/mochitest/test_formless_submit_navigation_negative.html
blob: 338cd5d2c1997691bb9d67c3647cdffbb5730f8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<!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.formlessCapture.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 = {
  PUSHSTATE: `history.pushState({}, "Pushed state", "?pushed");`,
  WINDOW_LOCATION: `window.location = "data:text/html;charset=utf-8,window.location";`,
  WINDOW_LOCATION_RELOAD: `window.location.reload();`,
  HISTORY_BACK: `history.back();`,
  HISTORY_GO_MINUS1: `history.go(-1);`,
};
const TESTCASES = [
  // Begin test cases that shouldn't trigger capture.
  {
    // 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) {
  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;
  frameDoc.documentElement.innerHTML = tc.document;
  // We eliminate no user input as a reason for not capturing by modifying the value
  setUserInputValues(frameDoc.documentElement, tc.selectorValues);

  info("Running " + scriptName + " script to check for a submission");
  frameDoc.defaultView.eval(SCRIPTS[scriptName]);

  // Wait to see if the promise above resolves.
  await new Promise(resolve => setTimeout(resolve, waitTime));
  ok(true, "Done waiting for captures");
}

let count = 0;
for (let tc of TESTCASES) {
  for (let scriptName of Object.keys(SCRIPTS)) {
    if (tc.wouldCapture && ["PUSHSTATE", "WINDOW_LOCATION"].includes(scriptName)) {
      // Don't run scripts that should actually capture for this testcase.
      continue;
    }
    let taskName = `testcase-${count}-${scriptName}`;
    let tmp = {
      async [taskName]() {
        info("Starting testcase with script " + scriptName + ": " + JSON.stringify(tc));
        await testFormlesSubmitNavigationNegative(tc, scriptName);
      },
    };
    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>