diff options
Diffstat (limited to 'testing/web-platform/tests/html/infrastructure')
74 files changed, 1925 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/infrastructure/.gitkeep b/testing/web-platform/tests/html/infrastructure/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/case-sensitivity-and-string-comparison/.gitkeep b/testing/web-platform/tests/html/infrastructure/case-sensitivity-and-string-comparison/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/case-sensitivity-and-string-comparison/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/contains.json b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/contains.json new file mode 100644 index 000000000..b30f1d0d5 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/contains.json @@ -0,0 +1,14 @@ +[ + { + "id": "htmlallcollection", + "original_id": "htmlallcollection" + }, + { + "id": "htmlformcontrolscollection", + "original_id": "htmlformcontrolscollection" + }, + { + "id": "htmloptionscollection", + "original_id": "htmloptionscollection" + } +]
\ No newline at end of file diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html new file mode 100644 index 000000000..9ce8ec350 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html @@ -0,0 +1,47 @@ +<!DOCTYPE HTML> +<html id="root"> +<head> +<title>HTMLAllCollection Tests</title> +<link rel="author" title="Dan Druta" href="mailto:dan.druta@att.com"/> +<link rel="help" href="2.7.2.1 - Common Infrastructure/Common DOM Interfaces/Collections/HTMLAllCollection"/> +<meta name="flags" content="TOKENS" /> +<meta name="assert" content="TEST ASSERTION"/> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +</head> +<body id="tags"> +<img src="../../../../images/green.png" name="picture"> +<a name="foo"></a> +<a name="foo"></a> +<script> +test(function(){ assert_equals(document.all.length,14)}, "Test for HTMLAllCollection size"); + +test(function(){ assert_equals(document.all.item(0).tagName,"HTML")}, "Test lookup by index using ()"); + +test(function(){ assert_equals(document.all[0].tagName,"HTML")}, "Test lookup by index using []"); + +test(function(){ assert_equals(document.all.item("picture").nodeName,"IMG")}, "Test lookup IMG by name"); + +test(function(){ assert_equals(document.all.namedItem("picture").nodeName,"IMG")}, "Test lookup IMG by namedItem "); + +test(function(){ assert_equals(document.all("picture").nodeName,"IMG")}, "Test lookup IMG in collection using ()"); + +test(function(){ assert_equals(document.all["picture"].nodeName,"IMG")}, "Test lookup IMG in collection using []"); + +test(function(){ assert_equals(document.all.picture.nodeName,"IMG")}, "Test lookup IMG in collection using ."); + +test(function(){ assert_equals(document.all.tags.id,"tags")}, "Test lookup tags in collection using ."); + +test(function() { + assert_equals(document.all["root"], document.documentElement); +}, "Should find root element too"); + +test(function() { + assert_equals(document.all["foo"].length, 2); +}, "Should find both anchors and produce a list"); + +test +</script> +<div id="log"></div> +</body> +</html> diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html new file mode 100644 index 000000000..8c8e1dbc1 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html @@ -0,0 +1,116 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>HTML Test: the HTMLFormControlsCollection interface</title> +<link rel="author" title="Intel" href="http://www.intel.com/"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/multipage/common-dom-interfaces.html#htmlformcontrolscollection"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<form id="f1"> + <input type="radio" id="r1"> + <keygen id="kg" name="key"></keygen> +</form> +<form id="f2"> + <table> + <tr> + <td> + <input type="checkbox" id="cb"> + <input type="checkbox" name="cb"> + </td> + </tr> + <tr> + <td> + <button id="btn"></button> + <button name="btn"></button> + </td> + </tr> + </table> +</form> + +<script> + +var coll1, coll2, rdo; + +setup(function () { + rdo = document.getElementById("r1"); + coll1 = document.forms[0].elements; + coll2 = document.forms[1].elements; +}); + +//length +test(function () { + assert_equals(coll1.length, 2, "The length attribute is incorrect."); + assert_equals(coll2.length, 4, "The length attribute is incorrect."); +}, "The length attribute must return the number of elements in the form"); + +//getter - index +test(function () { + assert_equals(coll1.item(0), rdo, "HTMLFormControlsCollection.item(index) should return the 'input' element in radio status."); +}, "HTMLFormControlsCollection.item(index) must return the indexed item"); + +test(function () { + assert_equals(coll1[0], rdo, "HTMLFormControlsCollection[index] should return the 'input' element in radio status."); +}, "HTMLFormControlsCollection[index] must return the indexed item"); + +//getter - name +test(function () { + assert_throws(TypeError(), function() { coll1("r1") }); +}, "HTMLFormControlsCollection is not callable"); + +test(function () { + assert_equals(coll1["r1"], rdo, "HTMLFormControlsCollection[name] should return the 'input' element in radio status."); +}, "HTMLFormControlsCollection[name] must return the named item"); + +//getter - namedItem +test(function () { + assert_equals(coll1.namedItem("r1"), rdo, "HTMLFormControlsCollection.namedItem(name) should return the 'input' element in radio status."); +}, "HTMLFormControlsCollection.namedItem(name) must return the named item"); + +test(function () { + assert_true(coll1.namedItem("r1") instanceof Element, "Can not return 'Element' object."); +}, "The namedItem(name) must return an Element"); + +test(function () { + assert_true(coll2.namedItem("cb") instanceof RadioNodeList, "Can not return 'RadioNodeList' object."); +}, "The namedItem(name) must return RadioNodeList"); + +test(function () { + assert_equals(coll1.namedItem(""), null, "The return value of namedItem() should be null."); +}, "The namedItem(name) must return null if the name is empty"); + +test(function () { + assert_equals(coll1.namedItem("test"), null, "The return value of namedItem() should be null."); +}, "The namedItem(name) must return null if there is no matched element"); + +test(function () { + assert_equals(coll1.namedItem("kg"), document.getElementById("kg"), "Controls can be named by 'id' attribute."); + assert_equals(coll1.namedItem("key"), document.getElementById("kg"), "Controls can be named by 'name' attribute."); +}, "Controls can be indexed by id or name attribute"); + +test(function () { + assert_equals(coll2.namedItem("btn").length, 2, "The length attribute should be 2."); +}, "The namedItem(name) must return the items with id or name attribute"); + +//various controls in fieldset and form +var containers = ["form", "fieldset"], + controls = ["button", "fieldset", "input", "keygen", "object", "output", "select", "textarea"]; +for (var m = 0; m < containers.length; m++) { + test(function () { + var container = document.createElement(containers[m]); + var len = controls.length; + for (var n = 0; n < len; n++) + container.appendChild(document.createElement(controls[n])); + document.body.appendChild(container); + assert_equals(container.elements.length, len, "The length should be " + len + "."); + }, "The HTMLFormControlsCollection interface is used for collections of listed elements in " + containers[m] + " element"); +} + +//Check the controls' order +test(function () { + var opt = document.forms[1].insertBefore(document.createElement("output"), document.forms[1].firstChild); + assert_array_equals(document.forms[1].elements, + [opt, document.getElementsByTagName("input")[1], document.getElementsByTagName("input")[2], + document.getElementsByTagName("button")[0], document.getElementsByTagName("button")[1]]); +}, "The controls in the form element must be sorted in tree order"); + +</script> diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmloptionscollection.html b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmloptionscollection.html new file mode 100644 index 000000000..d39cc460e --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmloptionscollection.html @@ -0,0 +1,216 @@ +<!doctype html> +<title>HTMLOptionsCollection</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<link rel="help" href="https://html.spec.whatwg.org/multipage/#htmloptionscollection-0"> +<select id=a> + <option>1</option> + <option>2</option> + <option>3</option> +<!--Note whitespace is important--> + <option>4</option> + <option>5</option> +</select> + +<select id=b> + <option id=b1>1</option> + <option name=b2>2</option> + <option id=b3>3</option> + <option id=b3>4</option> + <option name=b4>5</option> + <option name=b4>6</option> + <option id=b5>7</option> + <option name=b5>8</option> + <option id=b6 name=b7>9</option> + <option id=b6 name=b6>10</option> + <option id=b8 name=b9>11</option> +</select> + +<script> +var a; +var a_opts; +var a_original_innerHTML; +var b; +var b_opts; + +setup(function() { + a = document.getElementById("a"); + a_opts = a.options; + a_original_innerHTML = a.innerHTML; + a.innerHTML = a_original_innerHTML; + b = document.getElementById("b"); + b_opts = b.options; + b_original_innerHTML = b.innerHTML; + b.innerHTML = b_original_innerHTML; +}) + +function assert_values_equals(coll, expected_values, message) { + actual = []; + for (var i=0; i<coll.length; i++) { + actual.push(coll[i].value); + } + assert_array_equals(actual, expected_values, message); +} + +test(function() { + assert_equals(5, a_opts.length); +}, "Original length"); + +test(function() { + a.innerHTML = a_original_innerHTML; + a_opts.value = "3"; + a_opts.length = 5; + assert_equals(a_opts.length, 5); + assert_equals(a_opts.value, "3"); +}, "Setting length to original value has no effect"); + +test(function() { + a.innerHTML = a_original_innerHTML; + a.value = 3; + a_opts.length = 3; + assert_equals(3, a_opts.length, "Correct length"); + assert_values_equals(a_opts, ["1","2","3"], "Correct elements remain") + assert_equals(a_opts.value, "3", "Correct value set"); + assert_equals(a.childNodes.length, 11, "Correct number of child nodes") +}, "Setting length to shorter value"); + +test(function() { + a.innerHTML = a_original_innerHTML; + a.value = 3; + a_opts.length = 7; + assert_equals(a_opts.length, 7, "Correct length"); + assert_values_equals(a_opts, ["1","2","3","4","5","",""], "Correct elements inserted") + assert_equals(a.value, "3", "Correct value set"); + assert_equals(a.childNodes.length, 15, "Correct number of child nodes") +}, "Setting length to longer value"); + +test(function() { + a.innerHTML = a_original_innerHTML; + var newChild = document.createElement("p"); + var newOption = document.createElement("option"); + newOption.textContent = "6"; + newChild.appendChild(newOption); + a.appendChild(newChild); + a.value = 3; + assert_equals(a_opts.length, 5, "Correct length"); + assert_values_equals(a_opts, ["1","2","3","4","5"], "Correct elements inserted") + assert_equals(a.value, "3", "Correct value set"); +}, "Insert <p><option>6</option></p> into <select>"); + +test(function() { + a.innerHTML = a_original_innerHTML; + var newChild = document.createElement("select"); + var newOption = document.createElement("option"); + newOption.textContent = "6"; + newChild.appendChild(newOption); + a.appendChild(newChild); + a.value = 3; + assert_equals(a_opts.length, 5, "Correct length"); + assert_values_equals(a_opts, ["1","2","3","4","5"], "Correct elements inserted") + assert_equals(a.value, "3", "Correct value set"); +}, "Insert <select><option>6</option></select> into <select>"); + +test(function() { + //This tests the spec but it is probably wrong here; see bug 12665 + a.innerHTML = a_original_innerHTML; + var newChild = document.createElement("optgroup"); + var newOption = document.createElement("option"); + newOption.textContent = "6"; + newChild.appendChild(newOption); + a.appendChild(newChild); + a.value = 3; + assert_equals(a_opts.length, 6, "Correct length"); + assert_values_equals(a_opts, ["1","2","3","4","5", "6"], "Correct elements inserted") + assert_equals(a.value, "3", "Correct value set"); +}, "Insert <optgroup><option>6</option></optgroup> into <select>"); + +test(function() { + a.innerHTML = a_original_innerHTML; + var newChild = document.createElement("optgroup"); + var newChild1 = document.createElement("optgroup"); + var newOption = document.createElement("option"); + newOption.textContent = "6"; + newChild.appendChild(newChild1); + newChild1.appendChild(newOption); + a.appendChild(newChild); + a.value = 3; + assert_equals(a_opts.length, 5, "Correct length"); + assert_values_equals(a_opts, ["1","2","3","4","5"], "Correct elements inserted") + assert_equals(a.value, "3", "Correct value set"); +}, "Insert <optgroup><optgroup><option>6</option></optgroup></optgroup> into <select>"); + +test(function() { + assert_equals(b_opts.namedItem("b1").value, "1"); +}, "namedItem id attribute"); + +test(function() { + assert_equals(b_opts.namedItem("b2").value, "2"); +}, "namedItem name attribute"); + +test(function() { + assert_equals(b_opts.namedItem("c"), null); +}, "namedItem doesn't match anything"); + +test(function() { + assert_equals(b_opts.namedItem("b3").value, "3"); +}, "namedItem multiple IDs"); + +test(function() { + assert_equals(b_opts.namedItem("b4").value, "5"); +}, "namedItem multiple names"); + +test(function() { + assert_equals(b_opts.namedItem("b5").value, "7"); +}, "namedItem multiple name and ID"); + +test(function() { + assert_equals(b_opts.namedItem("b6").value, "9"); +}, "namedItem multiple name and ID with multiple attributes"); + +test(function() { + assert_equals(b_opts.namedItem("b8").value, "11"); +}, "namedItem id attribute multiple attributes one element"); + +test(function() { + assert_equals(b_opts.namedItem("b9").value, "11"); +}, "namedItem name attribute multiple attributes one element"); + +test(function() { + assert_true(b_opts[0] instanceof HTMLOptionElement); + assert_equals(b_opts[0].innerHTML, "1"); +}, "HTMLOptionsCollection [index] method return the item with index"); + +test(function() { + assert_true(b_opts["b2"] instanceof HTMLOptionElement); + assert_equals(b_opts["b2"].innerHTML, "2"); +}, "HTMLOptionsCollection [name] method return the item with name"); + +test(function() { + assert_true(b_opts.item(0) instanceof HTMLOptionElement); + assert_equals(b_opts.item(0).innerHTML, "1"); +}, "HTMLOptionsCollection.item(index) method return the item with index"); + +test(function() { + assert_true(b_opts.item("b2") instanceof HTMLOptionElement); + assert_equals(b_opts.item("b2").innerHTML, "1"); +}, "HTMLOptionsCollection.item(name) method return the item with index 0"); + +test(function() { + var b_opts_length = b_opts.length; + b_opts.add(new Option("2", "2")); + assert_equals(b_opts[b_opts_length].value, "2"); +}, "HTMLOptionsCollection.add method insert HTMLOptionElement Option element"); + +test(function() { + var b_opts_length = b_opts.length; + b_opts.remove(0); + assert_equals(b_opts.length, b_opts_length - 1); +}, "HTMLOptionsCollection.remove method remove Option element by index"); + +test(function() { + var add = document.createElement("p"); + assert_throws(new TypeError(), function() {b_opts.add(add);}); +}, "Add non-option to collection"); + +</script> +<div id=log></div> diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/radionodelist.html b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/radionodelist.html new file mode 100644 index 000000000..fc70d7172 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/radionodelist.html @@ -0,0 +1,78 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>HTML Test: the RadioNodeList interface</title> +<link rel="author" title="Intel" href="http://www.intel.com/"> +<link rel="help" href="https://html.spec.whatwg.org/multipage/multipage/common-dom-interfaces.html#radionodelist"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<form > + <input type="checkbox" name="rdo" value="0" id="r0" checked> + <input type="radio" name="rdo" id="r1"> + <input type="radio" name="rdo" id="r2" value="2"> +</form> +<script> + +var rdoList; + +setup(function () { + rdoList = document.forms[0].elements.namedItem("rdo"); +}); + +//on getting +test(function () { + assert_equals(rdoList.value, "", "The value attribute should be empty."); +}, "The value attribute should be empty if no element is checked"); + +test(function () { + document.getElementById("r2").checked = true; + assert_equals(rdoList.value, "2", "The value attribute should be 2."); +}, "The RadioNodeList.value must be the first checked radio button's value"); + +test(function () { + document.getElementById("r1").checked = true; + assert_equals(rdoList.value, "on", "The value attribute should be on."); + + document.getElementById("r1").value = 1; + assert_equals(rdoList.value, "1", "The value attribute should be 1."); +}, "Check the RadioNodeList.value on getting"); + +//on setting +test(function () { + assert_equals(rdoList.value, document.getElementById("r1").value, + "The value attribute should be equal to the first checked radio input element's value."); + assert_false(document.getElementById("r2").checked, + "The second radio input element should not be checked."); + + rdoList.value = "2"; + assert_equals(rdoList.value, document.getElementById("r2").value, + "The value attribute should be equal to the second radio input element's value."); + assert_true(document.getElementById("r2").checked, + "The second radio input element should be checked."); + + //Do nothing if no element's value is equal to new value. + rdoList.value = "3"; + assert_equals(rdoList.value, document.getElementById("r2").value, + "The value attribute should be the second radio input element's value."); + assert_true(document.getElementById("r2").checked, + "The second radio input element should be checked."); +}, "Check the RadioNodeList.value on setting"); + +//setting to on, specific case +test(function () { + rdoList.value = "on"; + assert_equals(rdoList.value, document.getElementById("r2").value, + "The value attribute should be the second radio input element's value."); + assert_true(document.getElementById("r2").checked, + "The second radio input element should be checked."); + + document.getElementById("r1").removeAttribute("value"); + rdoList.value = "on"; + assert_equals(rdoList.value, document.getElementById("r1").value, + "The value attribute should be the first radio input element's value."); + assert_true(document.getElementById("r1").checked, + "The first radio input element should be checked."); +}, "Check the RadioNodeList.value on setting to 'on'"); + + +</script> diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/domstringmap/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/domstringmap/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/domstringmap/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/garbage-collection/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/garbage-collection/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/garbage-collection/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/reflecting-content-attributes-in-idl-attributes/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/reflecting-content-attributes-in-idl-attributes/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/reflecting-content-attributes-in-idl-attributes/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/safe-passing-of-structured-data/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/safe-passing-of-structured-data/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/safe-passing-of-structured-data/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/transferable-objects/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/transferable-objects/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/transferable-objects/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/boolean-attributes/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/boolean-attributes/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/boolean-attributes/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/colors/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/colors/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/colors/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/comma-separated-tokens/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/comma-separated-tokens/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/comma-separated-tokens/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/common-parser-idioms/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/common-parser-idioms/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/common-parser-idioms/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/dates-and-times/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/dates-and-times/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/dates-and-times/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/dates-and-times/contains.json b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/dates-and-times/contains.json new file mode 100644 index 000000000..5be31eb48 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/dates-and-times/contains.json @@ -0,0 +1,42 @@ +[ + { + "id": "months", + "original_id": "months" + }, + { + "id": "dates", + "original_id": "dates" + }, + { + "id": "yearless-dates", + "original_id": "yearless-dates" + }, + { + "id": "times", + "original_id": "times" + }, + { + "id": "local-dates-and-times", + "original_id": "local-dates-and-times" + }, + { + "id": "time-zones", + "original_id": "time-zones" + }, + { + "id": "global-dates-and-times", + "original_id": "global-dates-and-times" + }, + { + "id": "weeks", + "original_id": "weeks" + }, + { + "id": "durations", + "original_id": "durations" + }, + { + "id": "vaguer-moments-in-time", + "original_id": "vaguer-moments-in-time" + } +]
\ No newline at end of file diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/keywords-and-enumerated-attributes/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/keywords-and-enumerated-attributes/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/keywords-and-enumerated-attributes/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/mq/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/mq/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/mq/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/numbers/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/numbers/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/numbers/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/numbers/contains.json b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/numbers/contains.json new file mode 100644 index 000000000..39a6ea005 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/numbers/contains.json @@ -0,0 +1,26 @@ +[ + { + "id": "signed-integers", + "original_id": "signed-integers" + }, + { + "id": "non-negative-integers", + "original_id": "non-negative-integers" + }, + { + "id": "floating-point-numbers", + "original_id": "floating-point-numbers" + }, + { + "id": "percentages-and-dimensions", + "original_id": "percentages-and-dimensions" + }, + { + "id": "lists-of-integers", + "original_id": "lists-of-integers" + }, + { + "id": "lists-of-dimensions", + "original_id": "lists-of-dimensions" + } +]
\ No newline at end of file diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/space-separated-tokens/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/space-separated-tokens/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/space-separated-tokens/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/syntax-references/.gitkeep b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/syntax-references/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/common-microsyntaxes/syntax-references/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/conformance-requirements/.gitkeep b/testing/web-platform/tests/html/infrastructure/conformance-requirements/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/conformance-requirements/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/conformance-requirements/conformance-classes/.gitkeep b/testing/web-platform/tests/html/infrastructure/conformance-requirements/conformance-classes/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/conformance-requirements/conformance-classes/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/conformance-requirements/dependencies/.gitkeep b/testing/web-platform/tests/html/infrastructure/conformance-requirements/dependencies/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/conformance-requirements/dependencies/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/conformance-requirements/extensibility/.gitkeep b/testing/web-platform/tests/html/infrastructure/conformance-requirements/extensibility/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/conformance-requirements/extensibility/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/conformance-requirements/extensibility/foreign.html b/testing/web-platform/tests/html/infrastructure/conformance-requirements/extensibility/foreign.html new file mode 100644 index 000000000..eaa133bad --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/conformance-requirements/extensibility/foreign.html @@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html lang="en" foo='bar'> + <head foo='bar'> + <meta charset="utf-8" foo='bar'> + <title id='title' foo='bar'>Foreign content</title> + <link rel="author" title="Philippe Le Hegaret" href="mailto:plh@w3.org" foo='bar'> + <link rel="help" href="https://html.spec.whatwg.org/multipage/#extensibility" foo='bar'> + <script src="/resources/testharness.js" foo='bar'></script> + <script src="/resources/testharnessreport.js" foo='bar'></script> + </head> + + <body foo='bar'> + + <p class='assert' foo='bar'>User agents must treat elements and attributes that they do not understand as semantically neutral; leaving them in the DOM (for DOM processors), and styling them according to CSS (for CSS processors), but not inferring any meaning from them.</p> + + <foo foo='bar' echo>Foobar</foo> + + <div id="log">Running test...</div> + + <script> + var t = async_test("foreign content"); + + on_event(window, "load", + t.step_func(function() { + var nodes = document.getElementsByTagName("*"); + var cont = true; + var last = null; + for(var i=0;i<nodes.length && cont; i++) { + var as = nodes.item(i).getAttribute("foo"); + if (!(as === "bar") && (nodes.item(i).getAttribute("id") === "log")) { + cont = false; + } else { + last = nodes.item(i); + assert_equals(as, "bar"); + } + } + + assert_equals(last.nodeName, "FOO"); + assert_equals(last.getAttribute("echo"), ""); + assert_equals(last.getAttribute("charly"), null); + t.done(); + })); + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/infrastructure/fetching-resources/.gitkeep b/testing/web-platform/tests/html/infrastructure/fetching-resources/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/fetching-resources/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/fetching-resources/content-type-sniffing/.gitkeep b/testing/web-platform/tests/html/infrastructure/fetching-resources/content-type-sniffing/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/fetching-resources/content-type-sniffing/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/fetching-resources/cors-enabled-fetch/.gitkeep b/testing/web-platform/tests/html/infrastructure/fetching-resources/cors-enabled-fetch/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/fetching-resources/cors-enabled-fetch/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/fetching-resources/cors-settings-attributes/.gitkeep b/testing/web-platform/tests/html/infrastructure/fetching-resources/cors-settings-attributes/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/fetching-resources/cors-settings-attributes/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/fetching-resources/encrypted-http-and-related-security-concerns/.gitkeep b/testing/web-platform/tests/html/infrastructure/fetching-resources/encrypted-http-and-related-security-concerns/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/fetching-resources/encrypted-http-and-related-security-concerns/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/fetching-resources/extracting-character-encodings-from-meta-elements/.gitkeep b/testing/web-platform/tests/html/infrastructure/fetching-resources/extracting-character-encodings-from-meta-elements/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/fetching-resources/extracting-character-encodings-from-meta-elements/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/fetching-resources/processing-model/.gitkeep b/testing/web-platform/tests/html/infrastructure/fetching-resources/processing-model/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/fetching-resources/processing-model/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/fetching-resources/terminology-1/.gitkeep b/testing/web-platform/tests/html/infrastructure/fetching-resources/terminology-1/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/fetching-resources/terminology-1/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/namespaces/.gitkeep b/testing/web-platform/tests/html/infrastructure/namespaces/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/namespaces/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/terminology/.gitkeep b/testing/web-platform/tests/html/infrastructure/terminology/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/terminology/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/terminology/character-encodings/.gitkeep b/testing/web-platform/tests/html/infrastructure/terminology/character-encodings/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/terminology/character-encodings/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/terminology/dom-trees/.gitkeep b/testing/web-platform/tests/html/infrastructure/terminology/dom-trees/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/terminology/dom-trees/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/terminology/plugins/.gitkeep b/testing/web-platform/tests/html/infrastructure/terminology/plugins/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/terminology/plugins/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/terminology/plugins/sample.txt b/testing/web-platform/tests/html/infrastructure/terminology/plugins/sample.txt new file mode 100644 index 000000000..cedecd6d8 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/terminology/plugins/sample.txt @@ -0,0 +1,3 @@ +This is a sample text/plain document. + +This is not an HTML document. diff --git a/testing/web-platform/tests/html/infrastructure/terminology/plugins/text-plain.html b/testing/web-platform/tests/html/infrastructure/terminology/plugins/text-plain.html new file mode 100644 index 000000000..0ed0ce23b --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/terminology/plugins/text-plain.html @@ -0,0 +1,32 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8"> + <title id='title'>Media Types</title> + <link rel="author" title="Philippe Le Hegaret" href="mailto:plh@w3.org"/> + <link rel="help" href="https://html.spec.whatwg.org/multipage/#plugins"/> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + + <body> + <script> + var t = async_test("A user agent must not consider the type text/plain as having a registered plugin."); + + window.onload = + t.step_func(function() { + assert_equals(document.getElementById("frameContext").contentDocument.body.firstChild.nodeName, "PRE"); + t.done(); + }); + </script> + + <h1>Test of plugin support</h1> + <p class='assert'>A user agent must not consider the types text/plain and application/octet-stream as having a registered plugin.</p> + + <iframe id="frameContext" src="sample.txt"></iframe> + + + <div id="log">Running test...</div> + + </body> +</html> diff --git a/testing/web-platform/tests/html/infrastructure/terminology/resources/.gitkeep b/testing/web-platform/tests/html/infrastructure/terminology/resources/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/terminology/resources/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/terminology/scripting-0/.gitkeep b/testing/web-platform/tests/html/infrastructure/terminology/scripting-0/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/terminology/scripting-0/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/terminology/xml/.gitkeep b/testing/web-platform/tests/html/infrastructure/terminology/xml/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/terminology/xml/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/urls/.gitkeep b/testing/web-platform/tests/html/infrastructure/urls/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/urls/base-urls/.gitkeep b/testing/web-platform/tests/html/infrastructure/urls/base-urls/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/base-urls/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/urls/dynamic-changes-to-base-urls/.gitkeep b/testing/web-platform/tests/html/infrastructure/urls/dynamic-changes-to-base-urls/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/dynamic-changes-to-base-urls/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/urls/dynamic-changes-to-base-urls/dynamic-urls.sub.xhtml b/testing/web-platform/tests/html/infrastructure/urls/dynamic-changes-to-base-urls/dynamic-urls.sub.xhtml new file mode 100644 index 000000000..7302ed6e2 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/dynamic-changes-to-base-urls/dynamic-urls.sub.xhtml @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html> +<html id="h" xmlns="http://www.w3.org/1999/xhtml" xml:base=""> + <head> + <title>HTML Test: Dynamic changes to base URLs</title> + <link rel="author" title="Intel" href="http://www.intel.com/"/> + <link rel="help" href="https://html.spec.whatwg.org/multipage/#dynamic-changes-to-base-urls" /> + <script src="/resources/testharness.js" id="s1"></script> + <script src="/resources/testharnessreport.js"></script> + </head> + <body> + <div id="log"></div> + <div id="div" style="display:none" xml:base=""></div> + <script> + <![CDATA[ + var div = document.getElementById("div"), + html = document.getElementById("h"), + url = document.location.href; + + var testData = [ + {elements: ["a", "link", "area"], set: "href", get: "href"}, + {elements: ["q", "blockquote", "ins", "del"], set: "cite", get: "cite"}, + {elements: ["img", "embed", "video", "iframe", "script", "source", "track"], set: "src", get: "src"}, + {elements: ["form"], set: "action", get: "action"}, + {elements: ["object"], set: "data", get: "data"}, + {elements: ["button"], set: "formaction", get: "formAction"} + ]; + + for (var i in testData) { + var item = testData[i]; + for (var j in item.elements) { + test(function () { + var ele = document.createElement(item.elements[j]); + + ele.setAttribute(item.set, "test.txt"); + div.appendChild(ele); + + html.setAttribute("xml:base", ""); + assert_equals(ele[item.get], url.substr(0, url.lastIndexOf("/")) +"/test.txt", "The '" + item.get + "' attribute is incorrect."); + html.setAttribute("xml:base", "http://{{domains[www]}}:{{ports[http][0]}}"); + assert_equals(ele[item.get], "http://{{domains[www]}}:{{ports[http][0]}}/test.txt", "The '" + item.get + "' attribute is incorrect."); + }, "The '" + item.set + "' attribute of the '" + item.elements[j] + "' element"); + } + } + + test(function () { + var s1 = document.getElementById("s1"); + var val1 = s1.src; + var val2 = div.firstChild.href; + + div.setAttribute("xml:base", "http://{{domains[www2]}}:{{ports[http][0]}}"); + assert_equals(s1.src, val1, "The outer element must not be effected."); + assert_not_equals(div.firstChild.href, val2, "The inner element must be effected."); + assert_equals(div.firstChild.href, "http://{{domains[www2]}}:{{ports[http][0]}}/test.txt"); + }, "Change the base URL must effect the descendant elements only"); + ]]> + </script> + </body> +</html> diff --git a/testing/web-platform/tests/html/infrastructure/urls/interfaces-for-url-manipulation/.gitkeep b/testing/web-platform/tests/html/infrastructure/urls/interfaces-for-url-manipulation/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/interfaces-for-url-manipulation/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/urls/parsing-urls/.gitkeep b/testing/web-platform/tests/html/infrastructure/urls/parsing-urls/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/parsing-urls/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/.gitkeep b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/blank.py b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/blank.py new file mode 100644 index 000000000..6274a4e3c --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/blank.py @@ -0,0 +1,2 @@ +def main(request, response): + return [("Content-Type", "text/html; charset=%s" % (request.GET['encoding']))], "" diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/css-tmpl.py b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/css-tmpl.py new file mode 100644 index 000000000..d7c9bce27 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/css-tmpl.py @@ -0,0 +1,5 @@ +def main(request, response): + encoding = request.GET['encoding'] + tmpl = request.GET['tmpl'] + sheet = tmpl % u'\\0000E5' + return [("Content-Type", "text/css; charset=%s" % encoding)], sheet.encode(encoding) diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/manifest.py b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/manifest.py new file mode 100644 index 000000000..05b47f816 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/manifest.py @@ -0,0 +1,12 @@ +def main(request, response): + id = request.GET['id'] + mode = request.GET['mode'] + fallback_url = "" + if mode == "FALLBACK": + fallback_url = "fallback-namespace/" + manifest = u"""CACHE MANIFEST + +%s: +%s stash.py?q=\u00E5&id=%s&action=put +""" % (mode, fallback_url, id) + return [("Content-Type", "text/cache-manifest; charset=%s" % request.GET['encoding'])], manifest.encode('utf-8') # charset should be ignored for cache manifests diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/page-using-manifest.py b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/page-using-manifest.py new file mode 100644 index 000000000..401d741a4 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/page-using-manifest.py @@ -0,0 +1,12 @@ +def main(request, response): + id = request.GET['id'] + encoding = request.GET['encoding'] + mode = request.GET['mode'] + iframe = "" + if mode == 'NETWORK': + iframe = "<iframe src='stash.py?q=%%C3%%A5&id=%s&action=put'></iframe>" % id + doc = """<!doctype html> +<html manifest="manifest.py?id=%s&encoding=%s&mode=%s"> +%s +""" % (id, encoding, mode, iframe) + return [("Content-Type", "text/html; charset=%s" % encoding)], doc.encode(encoding) diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/resolve-url.js b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/resolve-url.js new file mode 100644 index 000000000..b1b78e7f4 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/resolve-url.js @@ -0,0 +1,932 @@ +setup({explicit_done:true}); +onload = function() { + var encoding = '{{GET[encoding]}}'; + var input_url = 'resources/resource.py?q=\u00E5&encoding=' + encoding + '&type='; + ('html css js worker sharedworker worker_importScripts sharedworker_importScripts worker_worker worker_sharedworker sharedworker_worker '+ + 'sharedworker_sharedworker eventstream png svg xmlstylesheet_css video webvtt').split(' ').forEach(function(str) { + window['input_url_'+str] = input_url + str; + }); + var blank = 'resources/blank.py?encoding=' + encoding; + var stash_put = 'resources/stash.py?q=\u00E5&action=put&id='; + var stash_take = 'resources/stash.py?action=take&id='; + var expected_obj = { + 'utf-8':'%C3%A5', + 'utf-16be':'%C3%A5', + 'utf-16le':'%C3%A5', + 'windows-1252':'%E5', + 'windows-1251':'%3F' + }; + var expected_current = expected_obj[encoding]; + var expected_utf8 = expected_obj['utf-8']; + + function msg(expected, got) { + return 'expected substring '+expected+' got '+got; + } + + function poll_for_stash(test_obj, uuid, expected) { + var start = new Date(); + var poll = test_obj.step_func(function () { + var xhr = new XMLHttpRequest(); + xhr.open('GET', stash_take + uuid); + xhr.onload = test_obj.step_func(function(e) { + if (xhr.response == "") { + if (new Date() - start > 10000) { + // If we set the status to TIMEOUT here we avoid a race between the + // page and the test timing out + test_obj.force_timeout(); + } + setTimeout(poll, 200); + } else { + assert_equals(xhr.response, expected); + test_obj.done(); + } + }); + xhr.send(); + }) + setTimeout(poll, 200); + } + + // background attribute, check with getComputedStyle + function test_background(tag) { + var spec_url = 'https://html.spec.whatwg.org/multipage/multipage/rendering.html'; + spec_url += tag == 'body' ? '#the-page' : '#tables'; + test(function() { + var elm = document.createElement(tag); + document.body.appendChild(elm); + this.add_cleanup(function() { + document.body.removeChild(elm); + }); + elm.setAttribute('background', input_url_png); + var got = getComputedStyle(elm).backgroundImage; + assert_true(got.indexOf(expected_current) > -1, msg(expected_current, got)); + }, 'getComputedStyle <'+tag+' background>', + {help:spec_url}); + } + + 'body, table, thead, tbody, tfoot, tr, td, th'.split(', ').forEach(function(str) { + test_background(str); + }); + + // get a reflecting IDL attributes whose content attribute takes a URL or a list of space-separated URLs + function test_reflecting(tag, attr, idlAttr, multiple) { + idlAttr = idlAttr || attr; + var input = input_url_html; + if (multiple) { + input += ' ' + input; + } + test(function() { + var elm = document.createElement(tag); + assert_true(idlAttr in elm, idlAttr + ' is not supported'); + elm.setAttribute(attr, input); + var got = elm[idlAttr]; + assert_true(got.indexOf(expected_current) > -1, msg(expected_current, got)); + }, 'Getting <'+tag+'>.'+idlAttr + (multiple ? ' (multiple URLs)' : ''), + {help:'https://html.spec.whatwg.org/multipage/multipage/common-dom-interfaces.html#reflecting-content-attributes-in-idl-attributes'}); + } + + ('iframe src, a href, base href, link href, img src, embed src, object data, track src, video src, audio src, input src, form action, ' + + 'input formaction formAction, button formaction formAction, menuitem icon, script src').split(', ').forEach(function(str) { + var arr = str.split(' '); + test_reflecting(arr[0], arr[1], arr[2]); + }); + + 'a ping'.split(', ').forEach(function(str) { + var arr = str.split(' '); + test_reflecting(arr[0], arr[1], arr[2], true); + }); + + function setup_navigation(elm, iframe, id, test_obj) { + iframe.name = id; + elm.target = id; + elm.setAttribute('href', input_url_html); + document.body.appendChild(iframe); + document.body.appendChild(elm); + test_obj.add_cleanup(function() { + document.body.removeChild(iframe); + document.body.removeChild(elm); + }); + } + + // follow hyperlink + function test_follow_link(tag) { + async_test(function() { + var elm = document.createElement(tag); + var iframe = document.createElement('iframe'); + setup_navigation(elm, iframe, 'test_follow_link_'+tag, this); + iframe.onload = this.step_func_done(function() { // when the page navigated to has loaded + assert_equals(iframe.contentDocument.body.textContent, expected_current); + }); + // follow the hyperlink + elm.click(); + // check that navigation succeeded by ...??? XXX + }, 'follow hyperlink <'+tag+' href>', + {help:'https://html.spec.whatwg.org/multipage/multipage/links.html#following-hyperlinks'}); + } + + 'a, area, link'.split(', ').forEach(function(str) { + test_follow_link(str); + }); + + // follow hyperlink with ping attribute + function test_follow_link_ping(tag) { + async_test(function() { + var uuid = token(); + var elm = document.createElement(tag); + // check if ping is supported + assert_true('ping' in elm, 'ping not supported'); + elm.setAttribute('ping', stash_put + uuid); + var iframe = document.createElement('iframe'); + setup_navigation(elm, iframe, 'test_follow_link_ping_'+tag, this); + // follow the hyperlink + elm.click(); + // check that navigation succeeded by ...??? XXX + // check that the right URL was requested for the ping + poll_for_stash(this, uuid, expected_current); + }, 'hyperlink auditing <'+tag+' ping>', + {help:'https://html.spec.whatwg.org/multipage/multipage/links.html#hyperlink-auditing'}); + } + + 'a, area'.split(', ').forEach(function(str) { + test_follow_link_ping(str); + }); + + // navigating with meta refresh + async_test(function() { + var iframe = document.createElement('iframe'); + iframe.src = blank; + document.body.appendChild(iframe); + this.add_cleanup(function() { + document.body.removeChild(iframe); + }); + iframe.onload = this.step_func_done(function() { + var doc = iframe.contentDocument; + var got = doc.body.textContent; + if (got == '') { + doc.write('<meta http-equiv=refresh content="0; URL='+input_url_html+'">REFRESH'); + doc.close(); + return; + } + assert_equals(got, expected_current); + }); + }, 'meta refresh', + {help:'https://html.spec.whatwg.org/multipage/multipage/semantics.html#attr-meta-http-equiv-refresh'}); + + // loading html (or actually svg to support <embed>) + function test_load_nested_browsing_context(tag, attr, spec_url) { + async_test(function() { + var id = 'test_load_nested_browsing_context_'+tag; + var elm = document.createElement(tag); + elm.setAttribute(attr, input_url_svg); + elm.name = id; + document.body.appendChild(elm); + this.add_cleanup(function() { + document.body.removeChild(elm); + }); + elm.onload = this.step_func_done(function() { + assert_equals(window[id].document.documentElement.textContent, expected_current); + }); + + }, 'load nested browsing context <'+tag+' '+attr+'>', + {help:spec_url}); + } + + spec_url_load_nested_browsing_context = { + frame:'https://html.spec.whatwg.org/multipage/multipage/obsolete.html#process-the-frame-attributes', + iframe:'https://html.spec.whatwg.org/multipage/multipage/the-iframe-element.html#process-the-iframe-attributes', + object:'https://html.spec.whatwg.org/multipage/multipage/the-iframe-element.html#the-object-element', + embed:'https://html.spec.whatwg.org/multipage/multipage/the-iframe-element.html#the-embed-element-setup-steps' + }; + + 'frame src, iframe src, object data, embed src'.split(', ').forEach(function(str) { + var arr = str.split(' '); + test_load_nested_browsing_context(arr[0], arr[1], spec_url_load_nested_browsing_context[arr[0]]); + }); + + // loading css with <link> + async_test(function() { + var elm = document.createElement('link'); + elm.href = input_url_css; + elm.rel = 'stylesheet'; + document.head.appendChild(elm); + this.add_cleanup(function() { + document.head.removeChild(elm); + }); + elm.onload = this.step_func_done(function() { + var got = elm.sheet.href; + assert_true(elm.sheet.href.indexOf(expected_current) > -1, 'sheet.href ' + msg(expected_current, got)); + assert_equals(elm.sheet.cssRules[0].style.content, '"'+expected_current+'"', 'sheet.cssRules[0].style.content'); + }); + }, 'loading css <link>', + {help:['https://html.spec.whatwg.org/multipage/multipage/semantics.html#the-link-element', + 'https://html.spec.whatwg.org/multipage/multipage/semantics.html#styling']}); + + // loading js + async_test(function() { + var elm = document.createElement('script'); + elm.src = input_url_js + '&var=test_load_js_got'; + document.head.appendChild(elm); // no cleanup + elm.onload = this.step_func_done(function() { + assert_equals(window.test_load_js_got, expected_current); + }); + }, 'loading js <script>', + {help:'https://html.spec.whatwg.org/multipage/multipage/scripting-1.html#prepare-a-script'}); + + // loading image + function test_load_image(tag, attr, spec_url) { + async_test(function() { + var elm = document.createElement(tag); + if (tag == 'input') { + elm.type = 'image'; + } + elm.setAttribute(attr, input_url_png); + document.body.appendChild(elm); + this.add_cleanup(function() { + document.body.removeChild(elm); + }); + elm.onload = this.step_func_done(function() { + var got = elm.offsetWidth; + assert_equals(got, query_to_image_width[expected_current], msg(expected_current, image_width_to_query[got])); + }); + // <video poster> doesn't notify when the image is loaded so we need to poll :-( + var interval; + var check_video_width = function() { + var width = elm.offsetWidth; + if (width != 300 && width != 0) { + clearInterval(interval); + elm.onload(); + } + } + if (tag == 'video') { + interval = setInterval(check_video_width, 10); + } + }, 'loading image <'+tag+' '+attr+'>', + {help:spec_url}); + } + + var query_to_image_width = { + '%E5':1, + '%C3%A5':2, + '%3F':16, + 'unknown query':256, + 'default intrinsic width':300 + }; + + var image_width_to_query = {}; + (function() { + for (var x in query_to_image_width) { + image_width_to_query[query_to_image_width[x]] = x; + } + })(); + + var spec_url_load_image = { + img:'https://html.spec.whatwg.org/multipage/multipage/embedded-content-1.html#update-the-image-data', + embed:'https://html.spec.whatwg.org/multipage/multipage/the-iframe-element.html#the-embed-element-setup-steps', + object:'https://html.spec.whatwg.org/multipage/multipage/the-iframe-element.html#the-object-element', + input:'https://html.spec.whatwg.org/multipage/multipage/states-of-the-type-attribute.html#image-button-state-(type=image)', + video:'https://html.spec.whatwg.org/multipage/multipage/the-video-element.html#poster-frame' + }; + + 'img src, embed src, object data, input src, video poster'.split(', ').forEach(function(str) { + var arr = str.split(' '); + test_load_image(arr[0], arr[1], spec_url_load_image[arr[0]]); + }); + + // XXX test <img srcset> or its successor + // <menuitem icon> could also be tested but the spec doesn't require it to be loaded... + + // loading video + function test_load_video(tag, use_source_element) { + async_test(function() { + var elm = document.createElement(tag); + var video_ext = ''; + if (elm.canPlayType('video/ogg; codecs="theora,flac"')) { + video_ext = 'ogv'; + } else if (elm.canPlayType('video/mp4; codecs="avc1.42E01E,mp4a.40.2"')) { + video_ext = 'mp4'; + } + assert_not_equals(video_ext, '', 'no supported video format'); + var source; + if (use_source_element) { + source = document.createElement('source'); + elm.appendChild(source); + } else { + source = elm; + } + source.src = input_url_video + '&ext=' + video_ext; + elm.preload = 'auto'; + elm.load(); + this.add_cleanup(function() { + elm.removeAttribute('src'); + if (elm.firstChild) { + elm.removeChild(elm.firstChild); + } + elm.load(); + }); + elm.onloadedmetadata = this.step_func_done(function() { + var got = Math.round(elm.duration); + assert_equals(got, query_to_video_duration[expected_current], msg(expected_current, video_duration_to_query[got])); + }); + }, 'loading video <'+tag+'>' + (use_source_element ? '<source>' : ''), + {help:'https://html.spec.whatwg.org/multipage/multipage/the-video-element.html#concept-media-load-algorithm'}); + } + + var query_to_video_duration = { + '%E5':3, + '%C3%A5':5, + '%3F':30, + 'unknown query':300, + 'Infinity':Infinity, + 'NaN':NaN + }; + + var video_duration_to_query = {}; + (function() { + for (var x in query_to_video_duration) { + video_duration_to_query[query_to_video_duration[x]] = x; + } + })(); + + 'video, audio'.split(', ').forEach(function(str) { + test_load_video(str); + test_load_video(str, true); + }); + + // loading webvtt + async_test(function() { + var video = document.createElement('video'); + var track = document.createElement('track'); + video.appendChild(track); + track.src = input_url_webvtt; + track.track.mode = 'showing'; + track.onload = this.step_func_done(function() { + var got = track.track.cues[0].text; + assert_equals(got, expected_current); + }); + }, 'loading webvtt <track>', + {help:'https://html.spec.whatwg.org/multipage/multipage/the-video-element.html#track-url'}); + + // XXX downloading seems hard to automate + // <a href download> + // <area href download> + + // submit forms + function test_submit_form(tag, attr) { + async_test(function(){ + var elm = document.createElement(tag); + elm.setAttribute(attr, input_url_html); + var form; + var button; + if (tag == 'form') { + form = elm; + button = document.createElement('button'); + } else { + form = document.createElement('form'); + button = elm; + } + form.method = 'post'; + form.appendChild(button); + var iframe = document.createElement('iframe'); + var id = 'test_submit_form_' + tag; + iframe.name = id; + form.target = id; + button.type = 'submit'; + document.body.appendChild(form); + document.body.appendChild(iframe); + this.add_cleanup(function() { + document.body.removeChild(form); + document.body.removeChild(iframe); + }); + button.click(); + iframe.onload = this.step_func_done(function() { + var got = iframe.contentDocument.body.textContent; + if (got == '') { + return; + } + assert_equals(got, expected_current); + }); + }, 'submit form <'+tag+' '+attr+'>', + {help:'https://html.spec.whatwg.org/multipage/multipage/association-of-controls-and-forms.html#concept-form-submit'}); + } + + 'form action, input formaction, button formaction'.split(', ').forEach(function(str) { + var arr = str.split(' '); + test_submit_form(arr[0], arr[1]); + }); + + // <base href> + async_test(function() { + var iframe = document.createElement('iframe'); + iframe.src = blank; + document.body.appendChild(iframe); + this.add_cleanup(function() { + document.body.removeChild(iframe); + }); + iframe.onload = this.step_func_done(function() { + var doc = iframe.contentDocument; + doc.write('<!doctype html><base href="'+input_url+'"><a href></a>'); + doc.close(); + var got_baseURI = doc.baseURI; + assert_true(got_baseURI.indexOf(expected_current) > -1, msg(expected_current, got_baseURI), 'doc.baseURI'); + var got_a_href = doc.links[0].href; + assert_true(got_a_href.indexOf(expected_current) > -1, msg(expected_current, got_a_href), 'a.href'); + }); + }, '<base href>', + {help:['https://html.spec.whatwg.org/multipage/multipage/semantics.html#set-the-frozen-base-url', + 'https://dom.spec.whatwg.org/#dom-node-baseuri', + 'https://html.spec.whatwg.org/multipage/multipage/text-level-semantics.html#the-a-element']}); + + // XXX drag and drop (<a href> or <img src>) seems hard to automate + + // Worker() + async_test(function() { + var worker = new Worker(input_url_worker); + worker.onmessage = this.step_func_done(function(e) { + assert_equals(e.data, expected_current); + }); + }, 'Worker constructor', + {help:'https://html.spec.whatwg.org/multipage/multipage/workers.html#dom-worker'}); + + // SharedWorker() + async_test(function() { + var worker = new SharedWorker(input_url_sharedworker); + worker.port.onmessage = this.step_func_done(function(e) { + assert_equals(e.data, expected_current); + }); + }, 'SharedWorker constructor', + {help:'https://html.spec.whatwg.org/multipage/multipage/workers.html#dom-sharedworker'}); + + // EventSource() + async_test(function() { + var source = new EventSource(input_url_eventstream); + this.add_cleanup(function() { + source.close(); + }); + source.onmessage = this.step_func_done(function(e) { + assert_equals(e.data, expected_current); + }); + }, 'EventSource constructor', + {help:'https://html.spec.whatwg.org/multipage/multipage/comms.html#dom-eventsource'}); + + // EventSource#url + test(function() { + var source = new EventSource(input_url_eventstream); + source.close(); + var got = source.url; + assert_true(source.url.indexOf(expected_current) > -1, msg(expected_current, got)); + }, 'EventSource#url', + {help:'https://html.spec.whatwg.org/multipage/multipage/comms.html#dom-eventsource'}); + + // XMLDocument#load() + async_test(function() { + var doc = document.implementation.createDocument(null, "x"); + doc.load(input_url_svg); + doc.onload = this.step_func_done(function() { + assert_equals(doc.documentElement.textContent, expected_current); + }); + }, 'XMLDocument#load()', + {help:'https://html.spec.whatwg.org/multipage/multipage/dom.html#dom-xmldocument-load'}); + + // window.open + async_test(function() { + var id = 'test_window_open'; + var iframe = document.createElement('iframe'); + iframe.name = id; + document.body.appendChild(iframe); + this.add_cleanup(function() { + document.body.removeChild(iframe); + }); + window.open(input_url_html, id); + iframe.onload = this.step_func(function() { + var got = iframe.contentDocument.body.textContent; + if (got != "") { + assert_equals(got, expected_current); + this.done(); + } + }); + }, 'window.open()', + {help:'https://html.spec.whatwg.org/multipage/multipage/browsers.html#dom-open'}); + + // location + function test_location(func, desc) { + async_test(function() { + var iframe = document.createElement('iframe'); + document.body.appendChild(iframe); + this.add_cleanup(function() { + document.body.removeChild(iframe); + }); + func(iframe.contentWindow, input_url_html); + iframe.onload = this.step_func(function() { + var got = iframe.contentDocument.body.textContent; + if (got != '') { + assert_equals(got, expected_current); + this.done(); + } + }); + }, desc, + {help:'https://html.spec.whatwg.org/multipage/multipage/history.html#the-location-interface'}); + } + [[function(win, input) { win.location = input; }, "location [PutForwards]"], + [function(win, input) { win.location.assign(input); }, "location.assign()"], + [function(win, input) { win.location.replace(input); }, "location.replace()"], + [function(win, input) { win.location.href = input; }, "location.href"]].forEach(function(arr) { + test_location(arr[0], arr[1]); + }); + + // location.search + async_test(function() { + var iframe = document.createElement('iframe'); + iframe.src = input_url_html; + document.body.appendChild(iframe); + this.add_cleanup(function() { + document.body.removeChild(iframe); + }); + var i = 0; + iframe.onload = this.step_func(function() { + i++; + if (i == 1) { + iframe.contentWindow.location.search = '?' + input_url_html.split('?')[1] + '&other=foobar'; + } else { + var got = iframe.contentDocument.body.textContent; + assert_equals(got, expected_current); + this.done(); + } + }); + }, 'location.search', + {help:['https://html.spec.whatwg.org/multipage/multipage/history.html#the-location-interface', + 'http://url.spec.whatwg.org/#dom-url-search']}); + + // a.search, area.search + function test_hyperlink_search(tag) { + test(function() { + var elm = document.createElement(tag); + var input_arr = input_url_html.split('?'); + elm.href = input_arr[0]; + elm.search = '?' + input_arr[1]; + var got_href = elm.getAttribute('href'); + assert_true(got_href.indexOf(expected_current) > -1, 'href content attribute ' + msg(expected_current, got_href)); + var got_search = elm.search; + assert_true(got_search.indexOf(expected_current) > -1, 'getting .search '+msg(expected_current, got_search)); + }, '<'+tag+'>.search', + {help:['https://html.spec.whatwg.org/multipage/multipage/text-level-semantics.html#the-'+tag+'-element', + 'http://url.spec.whatwg.org/#dom-url-search']}); + } + 'a, area'.split(', ').forEach(function(str) { + test_hyperlink_search(str); + }); + + // history.pushState + // history.replaceState + function test_history(prop) { + async_test(function() { + var iframe = document.createElement('iframe'); + iframe.src = blank; + document.body.appendChild(iframe); + this.add_cleanup(function() { + document.body.removeChild(iframe); + }); + iframe.onload = this.step_func_done(function() { + iframe.contentWindow.history[prop](null, null, input_url_html); // this should resolve against the test's URL, not the iframe's URL + var got = iframe.contentWindow.location.href; + assert_true(got.indexOf(expected_current) > -1, msg(expected_current, got)); + assert_equals(got.indexOf('/resources/resources/'), -1, 'url was resolved against the iframe\'s URL instead of the settings object\'s API base URL'); + }); + }, 'history.'+prop, + {help:'https://html.spec.whatwg.org/multipage/multipage/history.html#dom-history-'+prop.toLowerCase()}); + } + + 'pushState, replaceState'.split(', ').forEach(function(str) { + test_history(str); + }); + + // SVG + var ns = {svg:'http://www.w3.org/2000/svg', xlink:'http://www.w3.org/1999/xlink'}; + // a + async_test(function() { + SVGAElement; // check support + var iframe = document.createElement('iframe'); + var id = 'test_svg_a'; + iframe.name = id; + var svg = document.createElementNS(ns.svg, 'svg'); + var a = document.createElementNS(ns.svg, 'a'); + a.setAttributeNS(ns.xlink, 'xlink:href', input_url_html); + a.setAttribute('target', id); + var span = document.createElement('span'); + a.appendChild(span); + svg.appendChild(a); + document.body.appendChild(iframe); + document.body.appendChild(svg); + this.add_cleanup(function() { + document.body.removeChild(iframe); + document.body.removeChild(svg); + }); + span.click(); + iframe.onload = this.step_func_done(function() { + var got = iframe.contentDocument.body.textContent; + if (got != '') { + assert_equals(got, expected_current); + } + }); + }, 'SVG <a>'); + + // feImage, image, use + function test_svg(func, tag) { + async_test(function() { + var uuid = token(); + var id = 'test_svg_'+tag; + var svg = document.createElementNS(ns.svg, 'svg'); + var parent = func(svg, id); + var elm = document.createElementNS(ns.svg, tag); + elm.setAttributeNS(ns.xlink, 'xlink:href', stash_put + uuid + '#foo'); + parent.appendChild(elm); + document.body.appendChild(svg); + this.add_cleanup(function() { + document.body.removeChild(svg); + }); + poll_for_stash(this, uuid, expected_current); + }, 'SVG <' + tag + '>', + {help:'https://www.w3.org/Bugs/Public/show_bug.cgi?id=24148'}); + } + + [[function(svg, id) { + SVGFEImageElement; // check support + var filter = document.createElementNS(ns.svg, 'filter'); + filter.setAttribute('id', id); + svg.appendChild(filter); + var rect = document.createElementNS(ns.svg, 'rect'); + rect.setAttribute('filter', 'url(#'+id+')'); + svg.appendChild(rect); + return filter; + }, 'feImage'], + [function(svg, id) { SVGImageElement; return svg; }, 'image'], + [function(svg, id) { SVGUseElement; return svg; }, 'use']].forEach(function(arr) { + test_svg(arr[0], arr[1]); + }); + + // UTF-8: + // XHR + async_test(function() { + var xhr = new XMLHttpRequest(); + xhr.open('GET', input_url_html); + xhr.onload = this.step_func_done(function() { + assert_equals(xhr.response, expected_utf8); + }); + xhr.send(); + }, 'XMLHttpRequest#open()', + {help:'https://xhr.spec.whatwg.org/#the-open()-method'}); + + // in a worker + async_test(function() { + var worker = new Worker(input_url_worker_importScripts); + worker.onmessage = this.step_func_done(function(e) { + assert_equals(e.data, expected_utf8); + }); + }, 'importScripts() in a dedicated worker', + {help:['https://html.spec.whatwg.org/multipage/multipage/workers.html#set-up-a-worker-script-settings-object', + 'https://html.spec.whatwg.org/multipage/multipage/workers.html#dom-workerglobalscope-importscripts']}); + + async_test(function() { + var worker = new Worker(input_url_worker_worker); + worker.onmessage = this.step_func_done(function(e) { + assert_equals(e.data, expected_utf8); + }); + }, 'Worker() in a dedicated worker', + {help:['https://html.spec.whatwg.org/multipage/multipage/workers.html#set-up-a-worker-script-settings-object', + 'https://html.spec.whatwg.org/multipage/multipage/workers.html#dom-worker']}); + + async_test(function() { + var worker = new Worker(input_url_worker_sharedworker); + worker.onmessage = this.step_func_done(function(e) { + assert_equals(e.data, expected_utf8); + }); + }, 'SharedWorker() in a dedicated worker', + {help:['https://html.spec.whatwg.org/multipage/multipage/workers.html#set-up-a-worker-script-settings-object', + 'https://html.spec.whatwg.org/multipage/multipage/workers.html#dom-sharedworker']}); + + async_test(function() { + var worker = new SharedWorker(input_url_sharedworker_importScripts); + worker.port.onmessage = this.step_func_done(function(e) { + assert_equals(e.data, expected_utf8); + }); + }, 'importScripts() in a shared worker', + {help:['https://html.spec.whatwg.org/multipage/multipage/workers.html#set-up-a-worker-script-settings-object', + 'https://html.spec.whatwg.org/multipage/multipage/workers.html#dom-workerglobalscope-importscripts']}); + + async_test(function() { + var worker = new SharedWorker(input_url_sharedworker_worker); + worker.port.onmessage = this.step_func_done(function(e) { + assert_equals(e.data, expected_utf8); + }); + }, 'Worker() in a shared worker', + {help:['https://html.spec.whatwg.org/multipage/multipage/workers.html#set-up-a-worker-script-settings-object', + 'https://html.spec.whatwg.org/multipage/multipage/workers.html#dom-worker']}); + + async_test(function() { + var worker = new SharedWorker(input_url_sharedworker_sharedworker); + worker.port.onmessage = this.step_func_done(function(e) { + assert_equals(e.data, expected_utf8); + }); + }, 'SharedWorker() in a shared worker', + {help:['https://html.spec.whatwg.org/multipage/multipage/workers.html#set-up-a-worker-script-settings-object', + 'https://html.spec.whatwg.org/multipage/multipage/workers.html#dom-sharedworker']}); + + // WebSocket() + async_test(function(){ + var ws = new WebSocket('ws://{{host}}:{{ports[ws][0]}}/echo-query?\u00E5'); + this.add_cleanup(function() { + ws.close(); + }); + ws.onmessage = this.step_func_done(function(e) { + assert_equals(e.data, expected_utf8); + }); + }, 'WebSocket constructor', + {help:'https://html.spec.whatwg.org/multipage/multipage/network.html#parse-a-websocket-url\'s-components'}); + + // WebSocket#url + test(function(){ + var ws = new WebSocket('ws://{{host}}:{{ports[ws][0]}}/echo-query?\u00E5'); + ws.close(); + var got = ws.url; + assert_true(ws.url.indexOf(expected_utf8) > -1, msg(expected_utf8, got)); + }, 'WebSocket#url', + {help:'https://html.spec.whatwg.org/multipage/multipage/network.html#dom-websocket-url'}); + + // Parsing cache manifest + function test_cache_manifest(mode) { + async_test(function() { + var iframe = document.createElement('iframe'); + var uuid = token(); + iframe.src = 'resources/page-using-manifest.py?id='+uuid+'&encoding='+encoding+'&mode='+mode; + document.body.appendChild(iframe); + this.add_cleanup(function() { + document.body.removeChild(iframe); + }); + poll_for_stash(this, uuid, expected_utf8); + }, 'Parsing cache manifest (' + mode + ')', + {help:'https://html.spec.whatwg.org/multipage/multipage/offline.html#parse-a-manifest'}); + } + + 'CACHE, FALLBACK, NETWORK'.split(', ').forEach(function(str) { + test_cache_manifest(str); + }); + + // CSS + function test_css(tmpl, expected_cssom, encoding, use_style_element) { + var desc = ['CSS', (use_style_element ? '<style>' : '<link> (' + encoding + ')'), tmpl].join(' '); + async_test(function(){ + css_is_supported(tmpl, expected_cssom, this); + var uuid = token(); + var id = 'test_css_' + uuid; + var url = 'url(stash.py?q=%s&action=put&id=' + uuid + ')'; + tmpl = tmpl.replace(/<id>/g, id).replace(/<url>/g, url); + var link; + if (use_style_element) { + link = document.createElement('style'); + link.textContent = tmpl.replace(/%s/g, '\u00E5').replace(/stash\.py/g, 'resources/stash.py'); + } else { + link = document.createElement('link'); + link.rel = 'stylesheet'; + link.href = 'resources/css-tmpl.py?encoding='+encoding+'&tmpl='+encodeURIComponent(tmpl); + } + var div = document.createElement('div'); + div.id = id; + div.textContent='x'; + document.head.appendChild(link); + document.body.appendChild(div); + this.add_cleanup(function() { + document.head.removeChild(link); + document.body.removeChild(div); + }); + poll_for_stash(this, uuid, expected_utf8); + }, desc, + {help:'https://www.w3.org/Bugs/Public/show_bug.cgi?id=23968'}); + } + + // fail fast if the input doesn't parse into the expected cssom + function css_is_supported(tmpl, expected_cssom, test_obj) { + if (expected_cssom === null) { + return; + } + var style = document.createElement('style'); + style.textContent = tmpl.replace(/<id>/g, 'x').replace(/<url>/g, 'url(data:,)'); + document.head.appendChild(style); + test_obj.add_cleanup(function() { + document.head.removeChild(style); + }); + assert_equals(style.sheet.cssRules.length, expected_cssom.length, 'number of style rules'); + for (var i = 0; i < expected_cssom.length; ++i) { + if (expected_cssom[i] === null) { + continue; + } + assert_equals(style.sheet.cssRules[i].style.length, expected_cssom[i], 'number of declarations in style rule #'+i); + } + } + + [['#<id> { background-image:<url> }', [1] ], + ['#<id> { border-image-source:<url> }', [1] ], + ['#<id>::before { content:<url> }', [1] ], + ['@font-face { font-family:<id>; src:<url> } #<id> { font-family:<id> }', [null, 1] ], + ['#<id> { display:list-item; list-style-image:<url> }', [2] ], + ['@import <url>;', null ], + // XXX maybe cursor isn't suitable for automation here if browsers delay fetching it + ['#<id> { cursor:<url>, pointer }', [1] ]].forEach(function(arr) { + var input = arr[0]; + var expected_cssom = arr[1]; + var other_encoding = encoding == 'utf-8' ? 'windows-1252' : 'utf-8'; + test_css(input, expected_cssom, encoding); + test_css(input, expected_cssom, other_encoding); + test_css(input, expected_cssom, null, true); + }); + + // XXX maybe test if they become relevant: + // binding (obsolete?) + // aural: cue-after, cue-before, play-during (not implemented?) + // hyphenate-resource (not implemented?) + // image() (not implemented?) + + // <?xml-stylesheet?> + async_test(function() { + var iframe = document.createElement('iframe'); + iframe.src = input_url_xmlstylesheet_css; + document.body.appendChild(iframe); + this.add_cleanup(function() { + document.body.removeChild(iframe); + }); + iframe.onload = this.step_func_done(function() { + assert_equals(iframe.contentDocument.firstChild.sheet.cssRules[0].style.content, '"' + expected_utf8 + '"'); + }); + }, '<?xml-stylesheet?> (CSS)', + {help:'http://dev.w3.org/csswg/cssom/#requirements-on-user-agents-implementing-the-xml-stylesheet-processing-instruction'}); + + // new URL() + test(function() { + var url = new URL('http://example.org/'+input_url); + var expected = expected_utf8; + assert_true(url.href.indexOf(expected) > -1, 'url.href '+msg(expected, url.href)); + assert_true(url.search.indexOf(expected) > -1, 'url.search '+msg(expected, url.search)); + }, 'URL constructor, url', + {help:'http://url.spec.whatwg.org/#dom-url'}); + + test(function() { + var url = new URL('', 'http://example.org/'+input_url); + var expected = expected_utf8; + assert_true(url.href.indexOf(expected) > -1, 'url.href '+msg(expected, url.href)); + assert_true(url.search.indexOf(expected) > -1, 'url.search '+msg(expected, url.search)); + }, 'URL constructor, base', + {help:'http://url.spec.whatwg.org/#dom-url'}); + + // Test different schemes + function test_scheme(url, utf8) { + test(function() { + var a = document.createElement('a'); + a.setAttribute('href', url); + var got = a.href; + var expected = utf8 ? expected_utf8 : expected_current; + assert_true(got.indexOf(expected) != -1, msg(expected, got)); + }, 'Scheme ' + url.split(':')[0] + ' (getting <a>.href)'); + } + + var test_scheme_urls = ['ftp://example.invalid/?x=\u00E5', + 'file:///?x=\u00E5', + 'gopher://example.invalid/?x=\u00E5', + 'http://example.invalid/?x=\u00E5', + 'https://example.invalid/?x=\u00E5', + ]; + + var test_scheme_urls_utf8 = ['ws://example.invalid/?x=\u00E5', + 'wss://example.invalid/?x=\u00E5', + 'mailto:example@invalid?x=\u00E5', + 'data:text/plain;charset='+encoding+',?x=\u00E5', + 'javascript:"?x=\u00E5"', + 'ftps://example.invalid/?x=\u00E5', + 'httpbogus://example.invalid/?x=\u00E5', + 'bitcoin:foo?x=\u00E5', + 'geo:foo?x=\u00E5', + 'im:foo?x=\u00E5', + 'irc:foo?x=\u00E5', + 'ircs:foo?x=\u00E5', + 'magnet:foo?x=\u00E5', + 'mms:foo?x=\u00E5', + 'news:foo?x=\u00E5', + 'nntp:foo?x=\u00E5', + 'sip:foo?x=\u00E5', + 'sms:foo?x=\u00E5', + 'smsto:foo?x=\u00E5', + 'ssh:foo?x=\u00E5', + 'tel:foo?x=\u00E5', + 'urn:foo?x=\u00E5', + 'webcal:foo?x=\u00E5', + 'wtai:foo?x=\u00E5', + 'xmpp:foo?x=\u00E5', + 'web+http:foo?x=\u00E5', + ]; + + test_scheme_urls.forEach(function(url) { + test_scheme(url); + }); + + test_scheme_urls_utf8.forEach(function(url) { + test_scheme(url, true); + }); + + done(); +}; diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py new file mode 100644 index 000000000..a1736f0d7 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/resource.py @@ -0,0 +1,131 @@ +import os +import re + +def main(request, response): + type = request.GET['type'] + encoding = request.GET['encoding'] + # We want the raw input for 'q' + q = re.search(r'q=([^&]+)', request.url_parts.query).groups()[0] + if type == 'html': + return [("Content-Type", "text/html; charset=utf-8")], q + elif type == 'css': + return [("Content-Type", "text/css; charset=utf-8")], "#test::before { content:'%s' }" % q + elif type == 'js': + return [("Content-Type", "text/javascript; charset=utf-8")], "%s = '%s';" % (request.GET['var'], q) + elif type == 'worker': + return [("Content-Type", "text/javascript")], "postMessage('%s'); close();" % q + elif type == 'sharedworker': + return [("Content-Type", "text/javascript")], "onconnect = function(e) { e.source.postMessage('%s'); close(); };" % q + elif type == 'worker_importScripts': + return ([("Content-Type", "text/javascript; charset=%s" % encoding)], # charset should be ignored for workers + """try { + var x = 'importScripts failed to run'; + importScripts('?q=\\u00E5&type=js&var=x&encoding=%s'); + postMessage(x); + close(); + } catch(ex) { + postMessage(String(ex)); + }""" % encoding) + elif type == 'worker_worker': + return ([("Content-Type", "text/javascript; charset=%s" % encoding)], # charset should be ignored for workers + """try { + var worker = new Worker('?q=\\u00E5&type=worker&encoding=%s'); + worker.onmessage = function(e) { + postMessage(e.data); + close(); + }; + } catch(ex) { + postMessage(String(ex)); + }""" % encoding) + elif type =='worker_sharedworker': + return ([("Content-Type", "text/javascript; charset=%s" % encoding)], # charset should be ignored for workers + """try { + var worker = new SharedWorker('?q=\\u00E5&type=sharedworker&encoding=%s'); + worker.port.onmessage = function(e) { + postMessage(e.data); + close(); + }; + } catch(ex) { + postMessage(String(ex)); + }""" % encoding) + elif type == 'sharedworker_importScripts': + return ([("Content-Type", "text/javascript; charset=%s" % request.GET['encoding'])], # charset should be ignored for workers + """onconnect = function(e) { + var connect_port = e.source; + try { + var x = 'importScripts failed to run'; + importScripts('?q=\\u00E5&type=js&var=x&encoding=%s'); + connect_port.postMessage(x); + close(); + } catch(ex) { + connect_port.postMessage(String(ex)); + } + };""" % encoding) + elif type == 'sharedworker_worker': + return ([("Content-Type", "text/javascript; charset=%s" % encoding)], # charset should be ignored for workers + """onconnect = function(e) { + var connect_port = e.source; + try { + var worker = new Worker('?q=\\u00E5&type=worker&encoding=%s'); + worker.onmessage = function(e) { + connect_port.postMessage(e.data); + close(); + }; + } catch(ex) { + connect_port.postMessage(String(ex)); + } + };""" % encoding) + elif type == 'sharedworker_sharedworker': + return ([("Content-Type", "text/javascript; charset=%s" % encoding)], # charset should be ignored for workers + """onconnect = function(e) { + var connect_port = e.source; + try { + onerror = function(msg) { + connect_port.postMessage(msg); + close(); + return false; + }; + var worker = new SharedWorker('?q=\\u00E5&type=sharedworker&encoding=%s'); + worker.port.onmessage = function(e) { + connect_port.postMessage(e.data); + close(); + }; + } catch(ex) { + connect_port.postMessage(String(ex)); + } + };""" % encoding) + elif type == 'eventstream': + return [("Content-Type", "text/event-stream")], "data: %s\n\n" % q + elif type == 'svg': + return [("Content-Type", "image/svg+xml")], "<svg xmlns='http://www.w3.org/2000/svg'>%s</svg>" % q + elif type == 'xmlstylesheet_css': + return ([("Content-Type", "application/xhtml+xml; charset=%s" % encoding)], + (u"""<?xml-stylesheet href="?q=å&type=css&encoding=%s"?><html xmlns="http://www.w3.org/1999/xhtml"/>""" % encoding) + .encode(encoding)) + elif type == 'png': + if q == '%E5': + image = 'green-1x1.png' + elif q == '%C3%A5': + image = 'green-2x2.png' + elif q == '%3F': + image = 'green-16x16.png' + else: + image = 'green-256x256.png' + rv = open(os.path.join(request.doc_root, "images", image), "rb").read() + return [("Content-Type", "image/png")], rv + elif type == 'video': + ext = request.GET['ext'] + if q == '%E5': + video = 'A4' # duration: 3 + elif q == '%C3%A5': + video = 'movie_5' # duration: 5 + elif q == '%3F': + video = 'green-at-15' # duration: 30 + else: + video = 'movie_300' # duration: 300 + rv = open(os.path.join(request.doc_root, "media", "%s.%s" % (video, ext)), "rb").read() + if ext == 'ogv': + ext = 'ogg' + return [("Content-Type", "video/%s" % ext)], rv + elif type == 'webvtt': + return [("Content-Type", "text/vtt")], "WEBVTT\n\n00:00:00.000 --> 00:00:01.000\n%s" % q diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/stash.py b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/stash.py new file mode 100644 index 000000000..d6e3dd5ea --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/resources/stash.py @@ -0,0 +1,16 @@ +import time +import re + +def main(request, response): + key = request.GET['id'] + action = request.GET['action'] + if action == 'put': + # We want the raw input for 'q' + q = re.search(r'q=([^&]+)', request.url_parts.query).groups()[0] + request.server.stash.put(key, q) + return [("Content-Type", "text/html")], 'Put %s' % q + else: + q = request.server.stash.take(key) + if q != None: + return [("Content-Type", "text/html")], q + return [], "" diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/utf-16be.html b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/utf-16be.html Binary files differnew file mode 100644 index 000000000..06558fe38 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/utf-16be.html diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/utf-16le.html b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/utf-16le.html Binary files differnew file mode 100644 index 000000000..86510b685 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/utf-16le.html diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/utf-8.html b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/utf-8.html new file mode 100644 index 000000000..fcf43e0a9 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/utf-8.html @@ -0,0 +1,9 @@ +<!doctype html> +<meta charset=utf-8> +<title>Resolving URLs, URL character encoding, utf-8</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<div id=log></div> +<script src="resources/resolve-url.js?encoding=utf-8&pipe=sub"></script> diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html new file mode 100644 index 000000000..23d33f9f7 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/windows-1251.html @@ -0,0 +1,9 @@ +<!doctype html> +<meta charset=windows-1251> +<title>Resolving URLs, URL character encoding, windows-1251</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<div id=log></div> +<script src="resources/resolve-url.js?encoding=windows-1251&pipe=sub"></script> diff --git a/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252.html b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252.html new file mode 100644 index 000000000..642c82ab4 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/resolving-urls/query-encoding/windows-1252.html @@ -0,0 +1,9 @@ +<!doctype html> +<meta charset=windows-1252> +<title>Resolving URLs, URL character encoding, windows-1252</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/utils.js"></script> +<div id=log></div> +<script src="resources/resolve-url.js?encoding=windows-1252&pipe=sub"></script> diff --git a/testing/web-platform/tests/html/infrastructure/urls/terminology-0/.gitkeep b/testing/web-platform/tests/html/infrastructure/urls/terminology-0/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/terminology-0/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/urls/terminology-0/document-base-url.html b/testing/web-platform/tests/html/infrastructure/urls/terminology-0/document-base-url.html new file mode 100644 index 000000000..ee9d72648 --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/terminology-0/document-base-url.html @@ -0,0 +1,93 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>HTML Test: document base URL</title> +<link rel="author" title="Intel" href="http://www.intel.com/"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<style> + iframe { display: none } +</style> +<body onload="on_load()"> + <div id="log"></div> + <script> + function assert_resolve_url(doc, base) { + var img = doc.createElement("img"); + img.src = "foo"; + var actual = img.src; + var expected = base + "/foo"; + assert_equals(actual, expected, "img src should resolve correctly"); + } + + var t1 = async_test("The document base URL of a document containing one or more base elements with href attributes is the frozen base URL of the first base element in the document that has an href attribute, in tree order."); + + function on_load() { + t1.step(function () { + var base = document.createElement("base"); + base.setAttribute("href", "/foo/bar"); + document.head.appendChild(base); + t1.add_cleanup(function () { + document.head.removeChild(base); + }); + + assert_resolve_url(document, location.href.replace(location.pathname, "/foo")); + assert_equals(document.baseURI, base.href, "The document base URL should be URL of the first base element that has an href attribute."); + }); + t1.done(); + } + + async_test(function() { + var iframe = document.createElement("iframe"); + iframe.onload = this.step_func_done(function () { + assert_resolve_url(iframe.contentDocument, location.href.replace(location.pathname, "/common")); + assert_equals(iframe.contentDocument.baseURI, iframe.contentDocument.location.href, "The document base URL should be the document's address."); + }); + iframe.setAttribute("src", "/common/blank.html"); + document.body.appendChild(iframe); + }, "The fallback base URL of a document containing no base element is the document's address."); + + async_test(function () { + var iframe = document.createElement("iframe"); + iframe.onload = this.step_func_done(function () { + assert_resolve_url(iframe.contentDocument, location.href.replace("/document-base-url.html", "")); + assert_equals(iframe.contentDocument.baseURI, document.baseURI, "The document base URL should be the creator document's base URL."); + }); + iframe.setAttribute("src", "about:blank"); + document.body.appendChild(iframe); + }, "The fallback base URL of a document whose address is about:blank is the document base URL of the creator document."); + + async_test(function () { + var iframe = document.createElement("iframe"); + iframe.onload = this.step_func_done(function () { + var doc = iframe.contentDocument; + var base = doc.body.appendChild(doc.createElement("base")); + base.href = "sub/"; + assert_resolve_url(doc, location.href.replace("/document-base-url.html", "/sub")); + assert_equals(doc.baseURI, document.baseURI.replace("/document-base-url.html", "/sub/")); + }); + iframe.setAttribute("src", "about:blank"); + document.body.appendChild(iframe); + }, "about:blank with a base element."); + + async_test(function () { + var iframe = document.createElement("iframe"); + iframe.onload = this.step_func_done(function () { + assert_resolve_url(iframe.contentDocument, location.href.replace("/document-base-url.html", "")); + assert_equals(iframe.contentDocument.baseURI, document.baseURI, "The document base URL should be the containing document's base URL."); + }); + iframe.setAttribute("srcdoc", "<p>foobar</p>"); + document.body.appendChild(iframe); + }, "The fallback base URL of an iframe srcdoc document is the document base URL of the document's browsing context's browsing context container's document."); + + async_test(function () { + var iframe = document.createElement("iframe"); + iframe.onload = this.step_func_done(function () { + var doc = iframe.contentDocument; + assert_resolve_url(doc, location.href.replace("/document-base-url.html", "/sub")); + assert_equals(doc.baseURI, document.baseURI.replace("/document-base-url.html", "/sub/"), + "The srcdoc document's base URL should be set by the <base> tag."); + }); + iframe.setAttribute("srcdoc", "<base href='sub/'><p>foobar</p>"); + document.body.appendChild(iframe); + }, "The base URL of an iframe srcdoc document with a <base> tag should be set by that tag."); + </script> +</body> diff --git a/testing/web-platform/tests/html/infrastructure/urls/terminology-0/multiple-base.sub.html b/testing/web-platform/tests/html/infrastructure/urls/terminology-0/multiple-base.sub.html new file mode 100644 index 000000000..49c428c5b --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/terminology-0/multiple-base.sub.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>document base URL: multiple base elements</title> +<base target="_blank" > +<base href="http://{{domains[www]}}:{{ports[http][0]}}/"> +<base href="http://{{domains[www1]}}:{{ports[http][0]}}/"> +<base href="http://{{domains[www2]}}:{{ports[http][0]}}/"> +<link rel="author" title="Denis Ah-Kang" href="mailto:denis@w3.org"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="log"></div> +<script> + test(function(){ + var base = document.querySelectorAll("base"); + assert_equals(document.baseURI, document.querySelectorAll("base[href]")[0].href); + }, "If there are multiple <base> elements, the document base URL is the frozen base URL of the first one that has an href attribute"); +</script> diff --git a/testing/web-platform/tests/html/infrastructure/urls/url-manipulation-and-creation/.gitkeep b/testing/web-platform/tests/html/infrastructure/urls/url-manipulation-and-creation/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/urls/url-manipulation-and-creation/.gitkeep diff --git a/testing/web-platform/tests/html/infrastructure/utf-8/.gitkeep b/testing/web-platform/tests/html/infrastructure/utf-8/.gitkeep new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/testing/web-platform/tests/html/infrastructure/utf-8/.gitkeep |