Update web-platform-tests to revision 0d318188757a9c996e20b82db201fd04de5aa255

This commit is contained in:
James Graham 2015-03-27 09:15:38 +00:00
parent b2a5225831
commit 1a81b18b9f
12321 changed files with 544385 additions and 6 deletions

View file

@ -0,0 +1,14 @@
[
{
"id": "htmlallcollection",
"original_id": "htmlallcollection"
},
{
"id": "htmlformcontrolscollection",
"original_id": "htmlformcontrolscollection"
},
{
"id": "htmloptionscollection",
"original_id": "htmloptionscollection"
}
]

View file

@ -0,0 +1,33 @@
<!DOCTYPE HTML>
<html>
<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>
<img src="../../../../images/green.png" name="picture">
<script>
test(function(){ assert_equals(document.all.length,12)}, "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.tags("script").length,3)}, "Test for multiple occurence 3 <script> found");
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 []");
</script>
<div id="log"></div>
</body>
</html>

View file

@ -0,0 +1,112 @@
<!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>
<button id="btn"></button>
<button name="btn"></button>
</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_equals(coll1("r1"), rdo, "HTMLFormControlsCollection(name) should return the 'input' element in radio status.");
}, "HTMLFormControlsCollection(name) must return the named item");
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>

View file

@ -0,0 +1,184 @@
<!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() {
var add = document.createElement("p");
assert_throws(new TypeError(), function() {b_opts.add(add);});
}, "Add non-option to collection");
</script>
<div id=log></div>

View file

@ -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>

View file

@ -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"
}
]

View file

@ -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"
}
]

View file

@ -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>

View file

@ -0,0 +1,3 @@
This is a sample text/plain document.
This is not an HTML document.

View file

@ -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>

View file

@ -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>

View file

@ -0,0 +1,2 @@
def main(request, response):
return [("Content-Type", "text/html; charset=%s" % (request.GET['encoding']))], ""

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -0,0 +1,952 @@
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, div itemid').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,vorbis"')) {
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 itemid is exposed in JSON drag-and-drop but seems hard to automate
// microdata values
function test_microdata_values(tag, attr) {
test(function() {
var elm = document.createElement(tag);
elm.setAttribute('itemprop', '');
elm.setAttribute(attr, input_url_html);
var got = elm.itemValue;
assert_not_equals(got, undefined, 'itemValue not supported');
assert_true(got.indexOf(expected_current) > -1, msg(expected_current, got));
}, 'microdata values <'+tag+' '+attr+'>',
{help:'https://html.spec.whatwg.org/multipage/multipage/microdata.html#concept-property-value'});
}
'audio src, embed src, iframe src, img src, source src, track src, video src, a href, area href, link href, object data'.split(', ').forEach(function(str) {
var arr = str.split(' ');
test_microdata_values(arr[0], arr[1]);
});
// 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();
};

View file

@ -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=&#x00E5;&amp;type=css&amp;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)).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))).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

View file

@ -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 [], ""

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -0,0 +1,52 @@
<!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>
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);
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_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_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 () {
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.");
</script>
</body>

View file

@ -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>