summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/infrastructure/common-dom-interfaces
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:22:09 +0000
commit43a97878ce14b72f0981164f87f2e35e14151312 (patch)
tree620249daf56c0258faa40cbdcf9cfba06de2a846 /testing/web-platform/tests/html/infrastructure/common-dom-interfaces
parentInitial commit. (diff)
downloadfirefox-43a97878ce14b72f0981164f87f2e35e14151312.tar.xz
firefox-43a97878ce14b72f0981164f87f2e35e14151312.zip
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/html/infrastructure/common-dom-interfaces')
-rw-r--r--testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/domstringlist.html61
-rw-r--r--testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/historical.html33
-rw-r--r--testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html334
-rw-r--r--testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html121
-rw-r--r--testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmloptionscollection.html216
-rw-r--r--testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/radionodelist.html78
6 files changed, 843 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/domstringlist.html b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/domstringlist.html
new file mode 100644
index 0000000000..6e6e4312a0
--- /dev/null
+++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/domstringlist.html
@@ -0,0 +1,61 @@
+<!doctype html>
+<title>DOMStringList</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<script>
+
+// Returns a promise that resolves to a DOMStringList with
+// the requested entries. Relies on Indexed DB.
+function createDOMStringList(entries) {
+ return new Promise((resolve, reject) => {
+ const dbname = String(self.location + Math.random());
+ const request = indexedDB.open(dbname);
+ request.onerror = () => reject(request.error);
+ request.onupgradeneeded = () => {
+ const db = request.result;
+ entries.forEach(entry => db.createObjectStore(entry));
+ const dsl = db.objectStoreNames;
+ resolve(dsl);
+ request.transaction.abort();
+ }
+ });
+}
+
+function dsl_test(entries, func, description) {
+ promise_test(t => createDOMStringList(entries).then(dsl => func(t, dsl)),
+ description);
+}
+
+dsl_test(['a', 'b', 'c'], (t, dsl) => {
+ assert_equals(dsl.length, 3, 'length attribute');
+}, 'DOMStringList: length attribute');
+
+dsl_test(['a', 'b', 'c'], (t, dsl) => {
+ assert_equals(dsl.item(0), 'a', 'item method');
+ assert_equals(dsl.item(1), 'b', 'item method');
+ assert_equals(dsl.item(2), 'c', 'item method');
+ assert_equals(dsl.item(3), null, 'item method out of range');
+ assert_equals(dsl.item(-1), null, 'item method out of range');
+ assert_throws_js(TypeError, () => dsl.item(),
+ 'item method should throw if called without enough args');
+}, 'DOMStringList: item() method');
+
+dsl_test(['a', 'b', 'c'], (t, dsl) => {
+ assert_equals(dsl[0], 'a', 'indexed getter');
+ assert_equals(dsl[1], 'b', 'indexed getter');
+ assert_equals(dsl[2], 'c', 'indexed getter');
+ assert_equals(dsl[3], undefined, 'indexed getter out of range');
+ assert_equals(dsl[-1], undefined, 'indexed getter out of range');
+}, 'DOMStringList: indexed getter');
+
+dsl_test(['a', 'b', 'c'], (t, dsl) => {
+ assert_true(dsl.contains('a'), 'contains method matched');
+ assert_true(dsl.contains('b'), 'contains method matched');
+ assert_true(dsl.contains('c'), 'contains method matched');
+ assert_false(dsl.contains(''), 'contains method unmatched');
+ assert_false(dsl.contains('d'), 'contains method unmatched');
+ assert_throws_js(TypeError, () => dsl.contains(),
+ 'contains method should throw if called without enough args');
+}, 'DOMStringList: contains() method');
+
+</script>
diff --git a/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/historical.html b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/historical.html
new file mode 100644
index 0000000000..91142c864e
--- /dev/null
+++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/historical.html
@@ -0,0 +1,33 @@
+<!doctype html>
+<title>Historical HTML*Collection features should not be supported</title>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+<div id=log></div>
+<form id=form><input name=foo></form>
+<select id=select><option name=bar></select>
+<div id=dupe>
+<div id=dupe>
+<script>
+test(function() {
+ var collection = document.getElementById('form').elements;
+ assert_equals(typeof collection, 'object', 'typeof');
+ assert_throws_js(TypeError, function() {
+ collection('foo');
+ });
+}, 'HTMLFormControlsCollection legacycaller should not be supported');
+
+test(function() {
+ var collection = document.getElementById('select').options;
+ assert_equals(typeof collection, 'object', 'typeof');
+ assert_throws_js(TypeError, function() {
+ collection('bar');
+ });
+}, 'HTMLOptionsCollection legacycaller should not be supported');
+
+test(function() {
+ var collection = document.all('dupe', 0);
+ // If the second argument were used, it would return the first item of the
+ // collection instead of the whole collection.
+ assert_equals(collection.length, 2, 'length');
+}, 'HTMLAllCollection legacycaller with two arguments should not be supported');
+</script>
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 0000000000..14faa2128e
--- /dev/null
+++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlallcollection.html
@@ -0,0 +1,334 @@
+<!DOCTYPE HTML>
+<html id="root">
+<head>
+<title>HTMLAllCollection Tests</title>
+<link rel="author" title="Dan Druta" href="mailto:dan.druta@att.com"/>
+<link rel="author" title="Philip Jägenstedt" href="mailto:philip@foolip.org"/>
+<link rel="help" href="https://html.spec.whatwg.org/multipage/infrastructure.html#the-htmlallcollection-interface"/>
+<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>
+<span id="42"></span>
+<span id="043"></span>
+<div id="4294967294"></div>
+<div id="4294967295"></div>
+<div id="4294967296"></div>
+<div id="undefined"></div>
+<div id="null"></div>
+<div name="divwithname"></div>
+<div id="-0"></div>
+<div id="log"></div>
+<script>
+var anchors = document.querySelectorAll("a");
+var divs = document.querySelectorAll("div");
+var scripts = document.querySelectorAll("script");
+var spans = document.querySelectorAll("span");
+
+test(function() {
+ assert_true(document.all instanceof HTMLAllCollection);
+}, "document.all is an HTMLAllCollection");
+
+test(function() {
+ assert_equals(document.all.length, 25);
+}, "length attribute");
+
+// indexed property getter
+
+test(function() {
+ assert_equals(document.all[0], document.documentElement);
+ assert_equals(document.all[-0], document.documentElement);
+ assert_equals(document.all[24], scripts[2]);
+}, "indexed property getter");
+
+test(function() {
+ assert_equals(document.all[-1], undefined);
+ assert_equals(document.all[25], undefined);
+ assert_equals(document.all[42], undefined);
+ assert_equals(document.all[43], undefined);
+ assert_equals(document.all[4294967294], undefined);
+ assert_equals(document.all[4294967295], divs[1]);
+ assert_equals(document.all[4294967296], divs[2]);
+}, "indexed property getter out of range");
+
+// named property getter
+
+test(function() {
+ assert_equals(document.all["root"], document.documentElement);
+ assert_equals(document.all["flags"].content, "TOKENS");
+ assert_equals(document.all["picture"].tagName, "IMG");
+}, "named property getter");
+
+test(function() {
+ assert_equals(document.all.root, document.documentElement);
+ assert_equals(document.all.flags.content, "TOKENS");
+ assert_equals(document.all.picture.tagName, "IMG");
+}, "named property getter with dot syntax");
+
+test(function() {
+ assert_equals(document.all[""], undefined);
+ assert_equals(document.all["noname"], undefined);
+ assert_equals(document.all.noname, undefined);
+ assert_equals(document.all["divwithname"], undefined);
+ assert_equals(document.all.divwithname, undefined);
+}, "named property getter with invalid name");
+
+test(function() {
+ var collection = document.all["foo"];
+ assert_equals(collection.length, 2);
+ assert_equals(collection[0], anchors[0]);
+ assert_equals(collection[1], anchors[1]);
+}, "named property getter returning collection");
+
+test(function() {
+ assert_equals(document.all["0"], document.documentElement);
+ assert_equals(document.all["24"], document.scripts[2]);
+ assert_equals(document.all["25"], undefined);
+ assert_equals(document.all["42"], undefined);
+ assert_equals(document.all["43"], undefined);
+}, "named property getter with \"array index property name\"");
+
+test(function() {
+ assert_equals(document.all["00"], undefined);
+ assert_equals(document.all["042"], undefined);
+ assert_equals(document.all["043"], spans[1]);
+ assert_equals(document.all["4294967294"], undefined);
+ assert_equals(document.all["4294967295"], divs[1]);
+ assert_equals(document.all["4294967296"], divs[2]);
+ assert_equals(document.all["-0"], divs[6]);
+}, "named property getter with invalid \"array index property name\"");
+
+test(function() {
+ assert_equals(document.all[undefined], divs[3]);
+}, "named property getter with undefined");
+
+test(function() {
+ assert_equals(document.all[null], divs[4]);
+}, "named property getter with null");
+
+// namedItem method
+
+test(function() {
+ assert_equals(document.all.namedItem("root"), document.documentElement);
+ assert_equals(document.all.namedItem("flags").content, "TOKENS");
+ assert_equals(document.all.namedItem("picture").tagName, "IMG");
+}, "namedItem method");
+
+test(function() {
+ assert_equals(document.all.namedItem(""), null);
+ assert_equals(document.all.namedItem("noname"), null);
+ assert_equals(document.all.namedItem("divwithname"), null);
+}, "namedItem method with invalid name");
+
+test(function() {
+ var collection = document.all.namedItem("foo");
+ assert_equals(collection.length, 2);
+ assert_equals(collection[0], anchors[0]);
+ assert_equals(collection[1], anchors[1]);
+}, "namedItem method returning collection");
+
+test(function() {
+ assert_equals(document.all.namedItem("0"), null);
+ assert_equals(document.all.namedItem("23"), null);
+ assert_equals(document.all.namedItem("24"), null);
+ assert_equals(document.all.namedItem("42"), spans[0]);
+ assert_equals(document.all.namedItem("43"), null);
+}, "namedItem method with \"array index property name\"");
+
+test(function() {
+ assert_equals(document.all.namedItem("00"), null);
+ assert_equals(document.all.namedItem("042"), null);
+ assert_equals(document.all.namedItem("043"), spans[1]);
+ assert_equals(document.all.namedItem("4294967294"), divs[0]);
+ assert_equals(document.all.namedItem("4294967295"), divs[1]);
+ assert_equals(document.all.namedItem("4294967296"), divs[2]);
+ assert_equals(document.all.namedItem("-0"), divs[6]);
+}, "namedItem method with invalid \"array index property name\"");
+
+test(function() {
+ assert_equals(document.all.namedItem(undefined), divs[3]);
+}, "namedItem method with undefined");
+
+test(function() {
+ assert_equals(document.all.namedItem(null), divs[4]);
+}, "namedItem method with null");
+
+test(function() {
+ assert_equals(document.all.namedItem.length, 1);
+ assert_throws_js(TypeError, function() {
+ document.all.namedItem();
+ });
+}, "namedItem method with no argument");
+
+// legacy caller
+
+test(function() {
+ assert_equals(document.all("root"), document.documentElement);
+ assert_equals(document.all("flags").content, "TOKENS");
+ assert_equals(document.all("picture").tagName, "IMG");
+}, "legacy caller");
+
+test(function() {
+ assert_equals(document.all(""), null);
+ assert_equals(document.all("noname"), null);
+ assert_equals(document.all("divwithname"), null);
+}, "legacy caller with invalid name");
+
+test(function() {
+ var collection = document.all("foo");
+ assert_equals(collection.length, 2);
+ assert_equals(collection[0], anchors[0]);
+ assert_equals(collection[1], anchors[1]);
+}, "legacy caller returning collection");
+
+test(function() {
+ assert_equals(document.all("0"), document.documentElement);
+ assert_equals(document.all("24"), document.scripts[2]);
+ assert_equals(document.all("25"), null);
+ assert_equals(document.all("42"), null);
+ assert_equals(document.all("43"), null);
+}, "legacy caller with \"array index property name\"");
+
+test(function() {
+ assert_equals(document.all(0), document.documentElement);
+ assert_equals(document.all(24), document.scripts[2]);
+ assert_equals(document.all(25), null);
+ assert_equals(document.all(42), null);
+ assert_equals(document.all(43), null);
+}, "legacy caller with \"array index property name\" as number");
+
+test(function() {
+ assert_equals(document.all("00"), null);
+ assert_equals(document.all("042"), null);
+ assert_equals(document.all("043"), spans[1]);
+ assert_equals(document.all("4294967294"), null);
+ assert_equals(document.all("4294967295"), divs[1]);
+ assert_equals(document.all("4294967296"), divs[2]);
+ assert_equals(document.all("-0"), divs[6]);
+}, "legacy caller with invalid \"array index property name\"");
+
+test(function() {
+ assert_equals(document.all(undefined), null);
+}, "legacy caller with undefined");
+
+test(function() {
+ assert_equals(document.all(null), divs[4]);
+}, "legacy caller with null");
+
+test(function() {
+ assert_equals(document.all(), null);
+}, "legacy caller with no argument");
+
+test(function() {
+ assert_throws_js(TypeError, function() {
+ new document.all("picture");
+ }, "New should not work on document.all()");
+
+ // https://esdiscuss.org/topic/isconstructor#content-11
+ assert_throws_js(TypeError, function() {
+ new (new Proxy(document.all, {
+ construct: function() {
+ return {};
+ }
+ }));
+ }, "Proxies should treat document.all() as not-a-constructor");
+}, "legacy caller is not a constructor");
+
+test(function() {
+ [undefined, null, {}, document.body].forEach(function(thisValue) {
+ assert_equals(Function.prototype.call.call(document.all, thisValue, "043"), spans[1]);
+ });
+}, "legacy caller with arbitrary this value");
+
+// item method
+
+test(function() {
+ assert_equals(document.all.item("root"), document.documentElement);
+ assert_equals(document.all.item("flags").content, "TOKENS");
+ assert_equals(document.all.item("picture").tagName, "IMG");
+}, "item method");
+
+test(function() {
+ assert_equals(document.all.item(""), null);
+ assert_equals(document.all.item("noname"), null);
+ assert_equals(document.all.item("divwithname"), null);
+}, "item method with invalid name");
+
+test(function() {
+ var collection = document.all.item("foo");
+ assert_equals(collection.length, 2);
+ assert_equals(collection[0], anchors[0]);
+ assert_equals(collection[1], anchors[1]);
+}, "item method returning collection");
+
+test(function() {
+ assert_equals(document.all.item("0"), document.documentElement);
+ assert_equals(document.all.item("24"), document.scripts[2]);
+ assert_equals(document.all.item("25"), null);
+ assert_equals(document.all.item("42"), null);
+ assert_equals(document.all.item("43"), null);
+}, "item method with \"array index property name\"");
+
+test(function() {
+ assert_equals(document.all.item(0), document.documentElement);
+ assert_equals(document.all.item(24), document.scripts[2]);
+ assert_equals(document.all.item(25), null);
+ assert_equals(document.all.item(42), null);
+ assert_equals(document.all.item(43), null);
+}, "item method with \"array index property name\" as number");
+
+test(function() {
+ assert_equals(document.all.item("00"), null);
+ assert_equals(document.all.item("042"), null);
+ assert_equals(document.all.item("043"), spans[1]);
+ assert_equals(document.all.item("4294967294"), null);
+ assert_equals(document.all.item("4294967295"), divs[1]);
+ assert_equals(document.all.item("4294967296"), divs[2]);
+ assert_equals(document.all.item("-0"), divs[6]);
+}, "item method with invalid \"array index property name\"");
+
+test(function() {
+ assert_equals(document.all.item(undefined), null);
+}, "item method with undefined");
+
+test(function() {
+ assert_equals(document.all.item(null), divs[4]);
+}, "item method with null");
+
+test(function() {
+ assert_equals(document.all.item.length, 0);
+ assert_equals(document.all.item(), null);
+}, "item method with no argument");
+
+// live HTMLCollection
+
+test(function() {
+ var collections = [
+ document.all["foo"],
+ document.all.namedItem("foo"),
+ document.all("foo"),
+ document.all.item("foo"),
+ ];
+ // a new HTMLCollection is created for each call
+ for (var i = 0; i < collections.length; i++) {
+ assert_true(collections[i] instanceof HTMLCollection);
+ for (var j = i + 1; j < collections.length; j++) {
+ assert_not_equals(collections[i], collections[j]);
+ }
+ }
+ for (var c of collections) {
+ assert_equals(c.length, 2);
+ }
+ anchors[0].name = "bar";
+ for (var c of collections) {
+ assert_equals(c.length, 1);
+ }
+}, "collections are new live HTMLCollection instances");
+</script>
+</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 0000000000..5591e190b3
--- /dev/null
+++ b/testing/web-platform/tests/html/infrastructure/common-dom-interfaces/collections/htmlformcontrolscollection.html
@@ -0,0 +1,121 @@
+<!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" name="ra">
+ <keygen id="kg" name="key"></keygen> <!-- we test that it does *not* appear in form.elements -->
+</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, 1, "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_js(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("r1"), document.getElementById("r1"), "Controls can be named by 'id' attribute.");
+ assert_equals(coll1.namedItem("ra"), document.getElementById("r1"), "Controls can be named by 'name' attribute.");
+}, "Controls can be indexed by id or name attribute");
+
+test(function () {
+ assert_equals(coll1.namedItem("kg"), null, "Keygen does not show up when queried by id.");
+ assert_equals(coll1.namedItem("key"), null, "Keygen does not show up when queried by name.");
+}, "Keygen controls do not show up at all");
+
+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", "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 0000000000..130716a9cc
--- /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_js(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 0000000000..fc70d7172c
--- /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>