598 lines
19 KiB
HTML
598 lines
19 KiB
HTML
<!DOCTYPE HTML>
|
|
<html>
|
|
<head>
|
|
<title>Satchel Test for Form Submisstion</title>
|
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<script type="text/javascript" src="satchel_common.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
</head>
|
|
<body>
|
|
<p id="display"></p>
|
|
<iframe id="iframe" src="https://example.com/tests/toolkit/components/satchel/test/subtst_form_submission_1.html"></iframe>
|
|
<div id="content" style="display: none">
|
|
|
|
<!-- ===== Things that should not be saved. ===== -->
|
|
|
|
<form purpose="nothing stored for input autocomplete=off (case-insensitive token)"
|
|
id="form1">
|
|
<input type="text" name="test1" autocomplete=" oFf ">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for form autocomplete=off"
|
|
id="form2" autocomplete="oFf">
|
|
<input type="text" name="test1">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for type=hidden"
|
|
id="form3">
|
|
<input type="hidden" name="test1">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for type=checkbox"
|
|
id="form4">
|
|
<input type="checkbox" name="test1">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for empty values."
|
|
id="form5">
|
|
<input type="text" name="test1" value="originalValue">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for unchanged values when set by a script."
|
|
id="form6">
|
|
<input type="text" name="test1" value="dontSaveThis">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for unchanged values. (.value not touched)"
|
|
id="form7">
|
|
<input type="text" name="test1" value="dontSaveThis">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for no field name or ID"
|
|
id="form8">
|
|
<input type="text">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for nothing to save"
|
|
id="form9">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for input with name too long (300 chars.)"
|
|
id="form10">
|
|
<input type="text" name="12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for input with value too long (300 chars.)"
|
|
id="form11">
|
|
<input type="text" name="test1">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for input with value of one space (which should be trimmed)"
|
|
id="form12">
|
|
<input type="text" name="test1">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for password field"
|
|
id="form13">
|
|
<input type="password" name="test1">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for password field (type toggled to password and back after pageload)"
|
|
id="form14">
|
|
<input type="text" name="test1">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for input with sensitive data (16 digit credit card number)"
|
|
id="form15">
|
|
<script type="text/javascript">
|
|
let form = document.getElementById("form15");
|
|
for (let i = 0; i < 10; i++) {
|
|
const input = form.appendChild(document.createElement("input"));
|
|
input.type = "text";
|
|
input.name = "test" + (i + 1);
|
|
}
|
|
</script>
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for input with sensitive data (15 digit credit card number)"
|
|
id="form16">
|
|
<script type="text/javascript">
|
|
form = document.getElementById("form16");
|
|
for (let i = 0; i < 10; i++) {
|
|
const input = form.appendChild(document.createElement("input"));
|
|
input.type = "text";
|
|
input.name = "test" + (i + 1);
|
|
}
|
|
</script>
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for input with sensitive data (19 digit credit card number)"
|
|
id="form17">
|
|
<input type="text" name="test1">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for input with sensitive data (16 digit hyphenated credit card number)"
|
|
id="form18">
|
|
<input type="text" name="test1">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for input with sensitive data (15 digit whitespace-separated credit card number)"
|
|
id="form19">
|
|
<input type="text" name="test1">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for the invalid form"
|
|
id="form20">
|
|
<input type='email' name='test1'>
|
|
<button type='submit'>Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for the invalid form"
|
|
id="form21">
|
|
<input type='email' value='foo'>
|
|
<input type='text' name='test1'>
|
|
<button type='submit'>Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for the input with name 'searchbar-history'"
|
|
id="form22">
|
|
<input type='text' name='searchbar-history'>
|
|
<button type='submit'>Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for input autocomplete=cc-csc (case-insensitive token)"
|
|
id="form23">
|
|
<input type="text" name="test1" autocomplete=" cc-CSC ">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for input autocomplete=new-password (case-insensitive token)"
|
|
id="form24">
|
|
<input type="text" name="test1" autocomplete=" NEW-password ">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored after user input followed by reset button click"
|
|
id="form25">
|
|
<input type="text" name="test1" defaultValue="do not save me" value="do not save me either">
|
|
<button type="submit">Submit</button>
|
|
<button type="reset">Reset</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored after user input changed by a script"
|
|
id="form26">
|
|
<input type="text" name="test1" defaultValue="do not save me" value="do not save me either">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="nothing stored for input autocomplete=one-time-code"
|
|
id="form27">
|
|
<input type="text" name="test1" autocomplete="one-time-code">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<!-- ===== Things that should be saved ===== -->
|
|
|
|
<!-- Form 100 is submitted into an iframe, not declared here. -->
|
|
|
|
<form purpose="saved input with no default value"
|
|
id="form101">
|
|
<input type="text" name="test1">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="saved input with a default value"
|
|
id="form102">
|
|
<input type="text" name="test2" value="originalValue">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="saved input with id and not name"
|
|
id="form103">
|
|
<input type="text" name="test3">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="saved input with leading and trailing space"
|
|
id="form104">
|
|
<input type="text" name="test4">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="saved input with leading and trailing whitespace"
|
|
id="form105">
|
|
<input type="text" name="test5">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="saved input that looks like sensitive data but doesn't satisfy the requirements (incorrect length)"
|
|
id="form106">
|
|
<input type="text" name="test6">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="input that looks like sensitive data but doesn't satisfy the requirements (Luhn check fails for 16 chars)"
|
|
id="form107">
|
|
<script type="text/javascript">
|
|
form = document.getElementById("form107");
|
|
for (let i = 0; i < 10; i++) {
|
|
let input = form.appendChild(document.createElement("input"));
|
|
input.type = "text";
|
|
input.name = "test7_" + (i + 1);
|
|
}
|
|
</script>
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="input that looks like sensitive data but doesn't satisfy the requirements (Luhn check fails for 15 chars)"
|
|
id="form108">
|
|
<script type="text/javascript">
|
|
form = document.getElementById("form108");
|
|
for (let i = 0; i != 10; i++) {
|
|
let input = form.appendChild(document.createElement("input"));
|
|
input.type = "text";
|
|
input.name = "test8_" + (i + 1);
|
|
}
|
|
</script>
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
<form purpose="form data submitted through HTTPS, when browser.formfill.saveHttpsForms is true"
|
|
id="form109" action="https://www.example.com/">
|
|
<input type="text" name="test9">
|
|
<button type="submit">Submit</button>
|
|
</form>
|
|
|
|
</div>
|
|
<script>
|
|
/* eslint-disable complexity */
|
|
|
|
const ccNumbers = {
|
|
valid15: [
|
|
"930771457288760", "474915027480942",
|
|
"924894781317325", "714816113937185",
|
|
"790466087343106", "474320195408363",
|
|
"219211148122351", "633038472250799",
|
|
"354236732906484", "095347810189325",
|
|
],
|
|
valid16: [
|
|
"3091269135815020", "5471839082338112",
|
|
"0580828863575793", "5015290610002932",
|
|
"9465714503078607", "4302068493801686",
|
|
"2721398408985465", "6160334316984331",
|
|
"8643619970075142", "0218246069710785",
|
|
],
|
|
invalid15: [
|
|
"526931005800649", "724952425140686",
|
|
"379761391174135", "030551436468583",
|
|
"947377014076746", "254848023655752",
|
|
"226871580283345", "708025346034339",
|
|
"917585839076788", "918632588027666",
|
|
],
|
|
invalid16: [
|
|
"9946177098017064", "4081194386488872",
|
|
"3095975979578034", "3662215692222536",
|
|
"6723210018630429", "4411962856225025",
|
|
"8276996369036686", "4449796938248871",
|
|
"3350852696538147", "5011802870046957",
|
|
],
|
|
};
|
|
|
|
function setUserInput(formNumber, inputName, value) {
|
|
const input = SpecialPowers.wrap(getFormElementByName(formNumber, inputName));
|
|
input.setUserInput(value);
|
|
}
|
|
|
|
function setScriptInput(formNumber, inputName, value) {
|
|
getFormElementByName(formNumber, inputName).value = value;
|
|
}
|
|
|
|
function checkSubmitDoesNotSave(formNumber) {
|
|
return new Promise(resolve => {
|
|
const form = document.getElementById("form" + formNumber);
|
|
form.addEventListener("submit", async () => {
|
|
const historyEntriesCount = await countEntries(null, null);
|
|
ok(!historyEntriesCount, form.getAttribute("purpose"));
|
|
resolve();
|
|
}, { once: true });
|
|
|
|
getFormSubmitButton(formNumber).click();
|
|
});
|
|
}
|
|
|
|
function checkInvalidFirstInputDoesNotSave(formNumber) {
|
|
return new Promise((resolve) => {
|
|
const form = document.getElementById("form" + formNumber);
|
|
const input = form.querySelector("input");
|
|
input.addEventListener("invalid", async _e => {
|
|
const historyEntriesCount = await countEntries(null, null);
|
|
ok(!historyEntriesCount, form.getAttribute("purpose"));
|
|
resolve();
|
|
}, { once: true});
|
|
|
|
getFormSubmitButton(formNumber).click();
|
|
});
|
|
}
|
|
|
|
async function checkSubmitSaves(formNumber, inputName, interactiveValue, savedValue, storageEventData = "formhistory-add") {
|
|
setUserInput(formNumber, inputName, interactiveValue);
|
|
const form = document.getElementById("form" + formNumber);
|
|
const storageEventPromise = promiseNextStorageEvent();
|
|
|
|
getFormSubmitButton(formNumber).click();
|
|
|
|
const storageEvent = await storageEventPromise;
|
|
isDeeply(storageEvent, {
|
|
subject: null,
|
|
topic: "satchel-storage-changed",
|
|
data: storageEventData
|
|
}, "expected storage event");
|
|
|
|
const historyEntriesCount = await countEntries(inputName, savedValue);
|
|
is(historyEntriesCount, 1, form.getAttribute("purpose"));
|
|
}
|
|
|
|
preventSubmitOnForms();
|
|
|
|
add_setup(async () => {
|
|
await updateFormHistory([
|
|
{ op: "remove" },
|
|
]);
|
|
const historyEntriesCount = await countEntries(null, null);
|
|
ok(!historyEntriesCount, "checking for initially empty storage");
|
|
});
|
|
|
|
add_task(async function form1_does_not_save() {
|
|
setUserInput(1, "test1", "dontSaveThis");
|
|
await checkSubmitDoesNotSave(1);
|
|
});
|
|
|
|
add_task(async function form2_does_not_save() {
|
|
setUserInput(2, "test1", "dontSaveThis");
|
|
await checkSubmitDoesNotSave(2);
|
|
});
|
|
|
|
add_task(async function form3_does_not_save() {
|
|
setUserInput(3, "test1", "dontSaveThis");
|
|
await checkSubmitDoesNotSave(3);
|
|
});
|
|
|
|
add_task(async function form4_does_not_save() {
|
|
setUserInput(4, "test1", "dontSaveThis");
|
|
await checkSubmitDoesNotSave(4);
|
|
});
|
|
|
|
add_task(async function form5_does_not_save() {
|
|
setUserInput(5, "test1", "");
|
|
await checkSubmitDoesNotSave(5);
|
|
});
|
|
|
|
add_task(async function form6_does_not_save() {
|
|
setScriptInput(6, "test1", "dontSaveThis");
|
|
await checkSubmitDoesNotSave(6);
|
|
});
|
|
|
|
add_task(async function form7_does_not_save() {
|
|
// Form 7 deliberately left untouched.
|
|
await checkSubmitDoesNotSave(7);
|
|
});
|
|
|
|
add_task(async function form8_does_not_save() {
|
|
// Form 8 has an input with no name or input attribute.
|
|
const input = SpecialPowers.wrap(document.getElementById("form8").elements[0]);
|
|
is(input.type, "text", "checking we got unidentified input");
|
|
input.setUserInput("dontSaveThis");
|
|
await checkSubmitDoesNotSave(8);
|
|
});
|
|
|
|
add_task(async function form9_does_not_save() {
|
|
// Form 9 has nothing to modify.
|
|
await checkSubmitDoesNotSave(9);
|
|
});
|
|
|
|
add_task(async function form10_does_not_save() {
|
|
setUserInput(10,
|
|
"12345678901234567890123456789012345678901234567890123456789012345678901234567890123456" +
|
|
"789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456" +
|
|
"789012345678901234567890123456789012345678901234567890123456789012345678901234567890",
|
|
"dontSaveThis");
|
|
await checkSubmitDoesNotSave(10);
|
|
});
|
|
|
|
add_task(async function form11_does_not_save() {
|
|
setUserInput(11, "test1",
|
|
"123456789012345678901234567890123456789012345678901234567890123456789" +
|
|
"012345678901234567890123456789012345678901234567890123456789012345678" +
|
|
"901234567890123456789012345678901234567890123456789012345678901234567" +
|
|
"89012345678901234567890123456789012345678901234567890");
|
|
await checkSubmitDoesNotSave(11);
|
|
});
|
|
|
|
add_task(async function form12_does_not_save() {
|
|
setUserInput(12, "test1", " ");
|
|
await checkSubmitDoesNotSave(12);
|
|
});
|
|
|
|
add_task(async function form13_does_not_save() {
|
|
setUserInput(13, "test1", "dontSaveThis");
|
|
await checkSubmitDoesNotSave(13);
|
|
});
|
|
|
|
add_task(async function form14_does_not_save() {
|
|
const input = SpecialPowers.wrap(document.getElementById("form14").elements[0]);
|
|
input.type = "password";
|
|
input.setUserInput("dontSaveThis");
|
|
// Set it back to type=text to simulate a password visibility toggle.
|
|
input.type = "text";
|
|
await checkSubmitDoesNotSave(14);
|
|
});
|
|
|
|
add_task(async function form15_does_not_save() {
|
|
const testData = ccNumbers.valid16;
|
|
for (let i = 0; i < testData.length; i++) {
|
|
setUserInput(15, "test" + (i + 1), testData[i]);
|
|
}
|
|
await checkSubmitDoesNotSave(15);
|
|
});
|
|
|
|
add_task(async function form16_does_not_save() {
|
|
const testData = ccNumbers.valid15;
|
|
for (let i = 0; i < testData.length; i++) {
|
|
setUserInput(16, "test" + (i + 1), testData[i]);
|
|
}
|
|
await checkSubmitDoesNotSave(16);
|
|
});
|
|
|
|
add_task(async function form17_does_not_save() {
|
|
setUserInput(17, "test1", "6799990100000000019");
|
|
await checkSubmitDoesNotSave(17);
|
|
});
|
|
|
|
add_task(async function form18_does_not_save() {
|
|
setUserInput(18, "test1", "0000-0000-0080-4609");
|
|
await checkSubmitDoesNotSave(18);
|
|
});
|
|
|
|
add_task(async function form19_does_not_save() {
|
|
setUserInput(19, "test1", "0000 0000 0222 331");
|
|
await checkSubmitDoesNotSave(19);
|
|
});
|
|
|
|
add_task(async function form20_does_not_save() {
|
|
setUserInput(20, "test1", "dontSaveThis");
|
|
await checkInvalidFirstInputDoesNotSave(20);
|
|
});
|
|
|
|
add_task(async function form21_does_not_save() {
|
|
setUserInput(21, "test1", "dontSaveThis");
|
|
await checkInvalidFirstInputDoesNotSave(21);
|
|
});
|
|
|
|
add_task(async function form22_does_not_save() {
|
|
setUserInput(22, "searchbar-history", "dontSaveThis");
|
|
await checkSubmitDoesNotSave(22);
|
|
});
|
|
|
|
add_task(async function form23_does_not_save() {
|
|
setUserInput(23, "test1", "987");
|
|
await checkSubmitDoesNotSave(23);
|
|
});
|
|
|
|
add_task(async function form24_does_not_save() {
|
|
setUserInput(24, "test1", "s3cr3t");
|
|
await checkSubmitDoesNotSave(24);
|
|
});
|
|
|
|
add_task(async function form25_does_not_save() {
|
|
setUserInput(25, "test1", "s3cr3t");
|
|
document.querySelector("form[id=form25] button[type=reset]").click();
|
|
await checkSubmitDoesNotSave(25);
|
|
});
|
|
|
|
add_task(async function form26_does_not_save() {
|
|
setUserInput(26, "test1", "s3cr3t");
|
|
document.querySelector("form[id=form26] input[name=test1]").value = "script changed me";
|
|
await checkSubmitDoesNotSave(26);
|
|
});
|
|
|
|
add_task(async function form27_does_not_save() {
|
|
setUserInput(27, "test1", "123456");
|
|
await checkSubmitDoesNotSave(27);
|
|
});
|
|
|
|
add_task(async function form100_saves() {
|
|
const iframe = SpecialPowers.wrap(document.getElementById("iframe"));
|
|
const browsingContext = SpecialPowers.unwrap(iframe.browsingContext);
|
|
const storageEventPromise = promiseNextStorageEvent();
|
|
await SpecialPowers.spawn(browsingContext, [], () => {
|
|
/* eslint-disable no-undef */
|
|
const input = SpecialPowers.wrap(content.document.getElementById("subtest2"));
|
|
input.setUserInput("subtestValue");
|
|
// This will prevent endless loop of tests
|
|
for (const form of content.document.forms) {
|
|
/* eslint-disable-next-line mozilla/balanced-listeners */
|
|
form.addEventListener("submit", e => e.preventDefault());
|
|
}
|
|
content.document.querySelector("button").click();
|
|
/* eslint-enable no-undef */
|
|
});
|
|
|
|
const storageEvent = await storageEventPromise;
|
|
isDeeply(storageEvent, {
|
|
subject: null,
|
|
topic: "satchel-storage-changed",
|
|
data: "formhistory-add"
|
|
}, "expected storage event");
|
|
|
|
const historyEntriesCount = await countEntries("subtest2", "subtestValue");
|
|
is(historyEntriesCount, 1, "saved from iframe");
|
|
});
|
|
|
|
add_task(async function form101_saves() {
|
|
await checkSubmitSaves(101, "test1", "savedValue", "savedValue");
|
|
});
|
|
|
|
add_task(async function form102_saves() {
|
|
await checkSubmitSaves(102, "test2", "savedValue", "savedValue");
|
|
});
|
|
|
|
add_task(async function form103_saves() {
|
|
await checkSubmitSaves(103, "test3", "savedValue", "savedValue");
|
|
});
|
|
|
|
add_task(async function form104_saves() {
|
|
await checkSubmitSaves(104, "test4", " trimTrailingAndLeadingSpace ", "trimTrailingAndLeadingSpace");
|
|
});
|
|
|
|
add_task(async function form105_saves() {
|
|
await checkSubmitSaves(105, "test5", "\t trimTrailingAndLeadingWhitespace\t ", "trimTrailingAndLeadingWhitespace");
|
|
});
|
|
|
|
add_task(async function form106_saves() {
|
|
// passes luhn but too long
|
|
await checkSubmitSaves(106, "test6", "55555555555544445553", "55555555555544445553");
|
|
});
|
|
|
|
add_task(async function form107_saves() {
|
|
for (let i = 0; i != ccNumbers.invalid16.length; i++) {
|
|
const name = "test7_" + (i + 1);
|
|
const value = ccNumbers.invalid16[i];
|
|
await checkSubmitSaves(107, name, value, value, i != 0 ? "formhistory-update" : "formhistory-add");
|
|
}
|
|
});
|
|
|
|
add_task(async function form108_saves() {
|
|
for (let i = 0; i != ccNumbers.invalid15.length; i++) {
|
|
const name = "test8_" + (i + 1);
|
|
const value = ccNumbers.invalid15[i];
|
|
await checkSubmitSaves(108, name, value, value, i != 0 ? "formhistory-update" : "formhistory-add");
|
|
}
|
|
});
|
|
|
|
add_task(async function form109_saves() {
|
|
setUserInput(109, "test9", "savedValue");
|
|
await checkSubmitSaves(109, "test9", "savedValue", "savedValue");
|
|
});
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|