Skip to content

Commit

Permalink
html, xhr: Add tests for 'formdata' event
Browse files Browse the repository at this point in the history
Specification PR: whatwg/html#4239
  • Loading branch information
tkent-google authored and annevk committed Jan 8, 2019
1 parent 3655845 commit 5938dd6
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 1 deletion.
11 changes: 10 additions & 1 deletion html/dom/interfaces.https.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,19 @@ <h1>HTML IDL tests</h1>
return input;
}

function getFormDataEvent() {
let formDataEvent = null;
let form = document.createElement("form");
form.addEventListener('formdata', e => { formDataEvent = e });
new FormData(form);
return formDataEvent;
}

const waitForLoad = new Promise(resolve => { addEventListener('load', resolve); })

idl_test(
['html'],
['SVG', 'cssom', 'touch-events', 'uievents', 'dom'],
['SVG', 'cssom', 'touch-events', 'uievents', 'dom', 'xhr'],
async idlArray => {
idlArray.add_objects({
NodeList: ['document.getElementsByName("name")'],
Expand Down Expand Up @@ -174,6 +182,7 @@ <h1>HTML IDL tests</h1>
HTMLProgressElement: ['document.createElement("progress")'],
HTMLMeterElement: ['document.createElement("meter")'],
ValidityState: ['document.createElement("input").validity'],
FormDataEvent: ['getFormDataEvent()'],
HTMLDetailsElement: ['document.createElement("details")'],
HTMLMenuElement: ['document.createElement("menu")'],
Window: ['window'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
<link rel="help" href="https://fetch.spec.whatwg.org/#concept-bodyinit-extract">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./resources/targetted-form.js"></script>

<iframe name="frame1" id="frame1"></iframe>
<form accept-charset="iso-8859-1" target="frame1" action="/common/blank.html" id="form1">
Expand Down Expand Up @@ -46,4 +47,64 @@
form2.submit.click();
}, 'The button cannot be setted if it is not a submitter.');

test(() => {
let didCallHandler = false;
let wasBubbles = false;
let wasCancelable = true;
let form = populateForm();
document.addEventListener('formdata', e => {
didCallHandler = true;
wasBubbles = e.bubbles;
wasCancelable = e.cancelable;
});
new FormData(form);
assert_true(didCallHandler);
assert_true(wasBubbles);
assert_false(wasCancelable);
}, '"formdata" event bubbles, and is not cancelable.');

test(() => {
let didCallHandler = false;
let form = populateForm();
let orphanRoot = document.createElement('div');
orphanRoot.appendChild(form);
orphanRoot.addEventListener('formdata', e => {
didCallHandler = true;
});
new FormData(form);
assert_true(didCallHandler);
}, '"formdata" event bubbles in an orphan tree.');

test(() => {
let listener1ok = false;
let listeern2ok = false;
let form = populateForm('<input name=n1 value=v1>');
form.addEventListener('formdata', e => {
listener1ok = e.formData.get('n1') == 'v1';
e.formData.append('h1', 'vh1');
e.formData.append('h2', 'vh2');
});
form.addEventListener('formdata', e => {
if (e.formData.get('h1') == 'vh1' && e.formData.get('h2') == 'vh2')
listener2ok = true;
});
form.submit();
assert_true(listener1ok);
assert_true(listener2ok);
}, '"formData" IDL attribute should have entries for form-associated elements' +
' in the first event handler, and the second handler can read entries ' +
'set by the first handler.');

let t1 = async_test('Entries added to "formData" IDL attribute should be submitted.');
t1.step(() => {
let form = populateForm('<input name=n1 value=v1>');
form.addEventListener('formdata', e => {
e.formData.append('h1', 'vh1');
});
let iframe = form.previousSibling;
iframe.onload = t1.step_func_done(() => {
assert_true(iframe.contentWindow.location.search.indexOf('n1=v1&h1=vh1') != -1);
});
form.submit();
});
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<!DOCTYPE html>
<link rel="help" href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="./resources/targetted-form.js"></script>
<body>
<script>
test(() => {
let form = populateForm('<input name=n10 value=v10>');
let counter = 0;
form.addEventListener('formdata', e => {
++counter;
form.submit();
});
form.submit();
assert_equals(counter, 1);
new FormData(form);
assert_equals(counter, 2);
}, 'If constructing entry list flag of form is true, then return');

let test10 = async_test('Cannot navigate (after constructing the entry list)');
test10.step(() => {
let form = populateForm('<input name=n1 value=v1>');
form.onformdata = (e) => { e.target.remove(); };
let wasLoaded = false;
let iframe = form.previousSibling;
// Request to load '/common/dummy.xhtml', and immediately submit the form to
// the same frame. If the form submission is aborted, the first request
// will be completed.
iframe.onload = test10.step_func_done(() => {
wasLoaded = true;
assert_true(iframe.contentWindow.location.search.indexOf('n1=v1') == -1);
});
iframe.src = '/common/dummy.xhtml';
assert_false(wasLoaded, 'Make sure the first loading is ongoing.');
form.submit();
});
</script>
</body>
13 changes: 13 additions & 0 deletions html/semantics/forms/form-submission-0/resources/targetted-form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
let frameCounter = 0;

function populateForm(optionalContentHtml) {
if (!optionalContentHtml)
optionalContentHtml = '';
document.body.insertAdjacentHTML(
'afterbegin',
`<iframe name="form-test-target-${frameCounter}"></iframe>` +
`<form action="/common/blank.html" target="` +
`form-test-target-${frameCounter}">${optionalContentHtml}</form>`);
++frameCounter;
return document.body.firstChild.nextSibling;
}
6 changes: 6 additions & 0 deletions interfaces/html.idl
Original file line number Diff line number Diff line change
Expand Up @@ -1081,6 +1081,11 @@ interface ValidityState {
readonly attribute boolean valid;
};

[Exposed=Window]
interface FormDataEvent : Event {
readonly attribute FormData formData;
};

[Exposed=Window,
HTMLConstructor]
interface HTMLDetailsElement : HTMLElement {
Expand Down Expand Up @@ -1735,6 +1740,7 @@ interface mixin GlobalEventHandlers {
attribute EventHandler onended;
attribute OnErrorEventHandler onerror;
attribute EventHandler onfocus;
attribute EventHandler onformdata;
attribute EventHandler oninput;
attribute EventHandler oninvalid;
attribute EventHandler onkeydown;
Expand Down
32 changes: 32 additions & 0 deletions xhr/formdata.htm
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
<title>XMLHttpRequest: Construct and upload FormData</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/html/semantics/forms/form-submission-0/resources/targetted-form.js"></script>
<link rel="help" href="https://xhr.spec.whatwg.org/#interface-formdata" data-tested-assertations="following::P[1]" />
<link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata" data-tested-assertations=".. following::P[1]" />
<link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata-append" data-tested-assertations=".. following::UL[1]/LI[1] following::UL[1]/LI[2] following::UL[1]/LI[3]" />
<link rel="help" href="https://xhr.spec.whatwg.org/#dom-XMLHttpRequest-send-FormData" data-tested-assertations="following::DD[1]" />
<link rel="help" href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set">

<div id="log"></div>
<form id="form">
<input type="hidden" name="key" value="value">
Expand Down Expand Up @@ -45,4 +48,33 @@
do_test("formdata with named string", create_formdata(['key', new Blob(['value'], {type: 'text/plain'}), 'kv.txt']), '\nkey=kv.txt:text/plain:5,');
do_test("formdata from form", new FormData(document.getElementById('form')), 'key=value,\n');

test(() => {
let form = populateForm('<input name=n1 value=v1>');
let formDataInEvent = null;
form.addEventListener('formdata', e => {
e.formData.append('h1', 'vh1');
formDataInEvent = e.formData;
});
let formData = new FormData(form);
assert_equals(formData.get('h1'), 'vh1');
assert_equals(formData.get('n1'), 'v1');
assert_not_equals(formData, formDataInEvent,
'"formData" attribute should be different from the ' +
'FromData object created by "new"');
}, 'Newly created FormData contains entries added to "formData" IDL ' +
'attribute of FormDataEvent.');

test(() => {
let form = populateForm('<input name=n11 value=v11>');
let counter = 0;
form.addEventListener('formdata', e => {
++counter;
assert_throws('InvalidStateError', () => { new FormData(e.target) });
});
new FormData(form);
assert_equals(counter, 1);

form.submit();
assert_equals(counter, 2);
}, '|new FormData()| in formdata event handler should throw');
</script>

0 comments on commit 5938dd6

Please sign in to comment.