chromium/third_party/blink/web_tests/fast/forms/file/recover-file-input-in-unposted-form.html

<html>
<head>
<script src="../../../resources/js-test.js"></script>
<script src="resources/file-drag-common.js"></script>
</head>
<body onload="setTimeout(test, 1)">
<form id="form" method="post" enctype="multipart/form-data">
<input id="text-input" type="text" name="posted-text">
<input id="file-input" type="file" name="posted-file">
<input id="multiple-file-input" type="file" multiple="multiple" name="posted-files">
</form>
<div id="manual-instructions">
To run this test manually:
<ul>
<li>Enter something to the text field and choose files with the files choosers.
<li>Click <u><a onclick="navigateAway()">here</a></u> to navigate away from the page.
<li>Click <u><a onclick="navigateBack()">here</a></u> to navigate back to the page.
<li>Check that the state of the form was restored.
</ul>
</div>
<div id="console"></div>
<script>
var jsTestIsAsync = true;

description("Test that the state of a file chooser is recovered when navigating away and navigating back.");

// Structure of the test:
// Start of the test (document.location.search == "")
// - Fill out a form.
// - Navigate to a different location.
// On the different page (document.location.search == "?differentpage")
// - Navigate back.
// Back on the original page (document.location.search == "" && window.name == "wentback")
// - Check the form data.

function test() {
    if (!window.testRunner)
        return;
    if (document.location.search == "" && window.name == "") {
        // Start of the test. Set the values to the input elements.
        document.getElementById("text-input").value = "text to be posted";
        dragFilesOntoInput(document.getElementById("file-input"), ["../resources/test.txt"]);
        dragFilesOntoInput(document.getElementById("multiple-file-input"),
                           ["../resources/test.txt", "../resources/test2.txt"]);
        navigateAway();
    } else if (document.location.search == "?differentpage") {
        // We have navigated to a different page. Now navigate back.
        navigateBack();
    } else if (document.location.search == "" && window.name == "wentback") {
        // We have navigated back. Now check the form values.
        shouldBeEqualToString("document.getElementById('text-input').value", "text to be posted");

        // The real file paths cannot be read from the file chooser element, but
        // we can verify that the path was restored properly by reading the
        // file.
        expectFileContents("file-input", 0, "Hello");
        expectFileContents("multiple-file-input", 0, "Hello");
        expectFileContents("multiple-file-input", 1, "Another");
    }
}

function navigateAway() {
    // Navigate away; do it with a timeout so that it will create a history entry.
    setTimeout(function() {document.location = document.location + "?differentpage";}, 0);
}

function navigateBack() {
    window.name = "wentback";
    history.back();
}

var filesRead = 0;
var fileContents = [];

function verifyFileContents() {
    fileContents.sort((lhs, rhs) => {
        if (lhs.id !== rhs.id) {
            return lhs.id < rhs.id ? -1 : 1;
        }
        return lhs.index - rhs.index;
    });
    shouldBeEqualToString("fileContents[0].actual", fileContents[0].expected);
    shouldBeEqualToString("fileContents[1].actual", fileContents[1].expected);
    shouldBeEqualToString("fileContents[2].actual", fileContents[2].expected);
}

function fileContentsReceived(id, index, expected, evt) {
    var actual = evt.target.result;
    fileContents.push({id, index, expected, actual});
    ++filesRead;
    if (filesRead == 3) {
        verifyFileContents();
        finishJSTest();
    }
}

function expectFileContents(id, index, contents) {
    var reader = new FileReader();
    var file = document.getElementById(id).files[index];
    reader.readAsText(file, "UTF-8");
    reader.onload = fileContentsReceived.bind(undefined, id, index, contents);
}
</script>
</body>
</html>