diff options
Diffstat (limited to 'browser/components/sessionstore/test/browser_formdata_face.js')
-rw-r--r-- | browser/components/sessionstore/test/browser_formdata_face.js | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/browser/components/sessionstore/test/browser_formdata_face.js b/browser/components/sessionstore/test/browser_formdata_face.js new file mode 100644 index 0000000000..5c38338871 --- /dev/null +++ b/browser/components/sessionstore/test/browser_formdata_face.js @@ -0,0 +1,168 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * This test ensures that collecting form data for form-associated custom + * elements works as expected. + */ +add_task(async function test_face_restore() { + const URL = `data:text/html;charset=utf-8,<!DOCTYPE html> + <h1>mozilla</h1> + <script> + restoredStates = {}; + customElements.define("c-e", class extends HTMLElement { + static formAssociated = true; + constructor() { + super(); + this.internals = this.attachInternals(); + } + formStateRestoreCallback(state, reason) { + if (reason == "restore") { + restoredStates[this.id] = state; + } + } + }); + </script> + <form> + <c-e id="test1"></c-e> + <c-e id="test2"></c-e> + <c-e id="test3"></c-e> + <c-e id="test4"></c-e> + <c-e id="test5"></c-e> + <c-e id="test6"></c-e> + </form>`; + + // Load a tab with a FACE. + let tab = (gBrowser.selectedTab = BrowserTestUtils.addTab(gBrowser, URL)); + let browser = tab.linkedBrowser; + await promiseBrowserLoaded(browser); + + // Set the FACE state and value. + await SpecialPowers.spawn(browser, ["c-e"], selector => { + function formDataWith(...entries) { + const formData = new content.FormData(); + for (let [key, value] of entries) { + formData.append(key, value); + } + return formData; + } + const states = [ + "test state", + new content.File(["state"], "state.txt"), + formDataWith(["1", "state"], ["2", new content.Blob(["state_blob"])]), + null, + undefined, + null, + ]; + const values = [ + "test value", + new content.File(["value"], "value.txt"), + formDataWith(["1", "value"], ["2", new content.Blob(["value_blob"])]), + "null state", + "both value and state", + null, + ]; + + [...content.document.querySelectorAll(selector)].forEach((node, i) => { + node.internals.setFormValue(values[i], states[i]); + }); + }); + + // Close and restore the tab. + await promiseRemoveTabAndSessionState(tab); + + { + let [ + { + state: { formdata }, + }, + ] = ss.getClosedTabDataForWindow(window); + + is(formdata.id.test1.value, "test value", "String value should be stored"); + is(formdata.id.test1.state, "test state", "String state should be stored"); + + let storedFile = formdata.id.test2.value; + is(storedFile.name, "value.txt", "File value name should be stored"); + is(await storedFile.text(), "value", "File value text should be stored"); + storedFile = formdata.id.test2.state; + is(storedFile.name, "state.txt", "File state name should be stored"); + is(await storedFile.text(), "state", "File state text should be stored"); + + let storedFormData = formdata.id.test3.value; + is( + storedFormData.get("1"), + "value", + "FormData value string should be stored" + ); + is( + await storedFormData.get("2").text(), + "value_blob", + "Form value blob should be stored" + ); + storedFormData = formdata.id.test3.state; + is( + storedFormData.get("1"), + "state", + "FormData state string should be stored" + ); + is( + await storedFormData.get("2").text(), + "state_blob", + "Form state blob should be stored" + ); + + is(formdata.id.test4.state, null, "Null state stored"); + is(formdata.id.test4.value, "null state", "Value with null state stored"); + + is( + formdata.id.test5.value, + "both value and state", + "Undefined state should be set to value" + ); + is( + formdata.id.test5.state, + "both value and state", + "Undefined state should be set to value" + ); + + ok( + !("test6" in formdata.id), + "Completely null values should not be stored" + ); + } + + tab = ss.undoCloseTab(window, 0); + browser = tab.linkedBrowser; + await promiseTabRestored(tab); + + // Check that the FACE state was restored. + await SpecialPowers.spawn(browser, ["restoredStates"], async prop => { + let restoredStates = content.wrappedJSObject[prop]; + is(restoredStates.test1, "test state", "String should be stored"); + + let storedFile = restoredStates.test2; + is(storedFile.name, "state.txt", "File name should be stored"); + is(await storedFile.text(), "state", "File text should be stored"); + + const storedFormData = restoredStates.test3; + is(storedFormData.get("1"), "state", "Form data string should be stored"); + is( + await storedFormData.get("2").text(), + "state_blob", + "Form data blob should be stored" + ); + + ok(!("test4" in restoredStates), "Null values don't get restored"); + + is( + restoredStates.test5, + "both value and state", + "Undefined state should be set to value" + ); + }); + + // Cleanup. + gBrowser.removeTab(tab); +}); |