Tests: Import WPT tests for select, optgroup and option elements

This commit is contained in:
Andreas Kling 2024-11-14 00:01:20 +01:00 committed by Andreas Kling
commit 581597cb34
Notes: github-actions[bot] 2024-11-14 22:07:28 +00:00
75 changed files with 2870 additions and 0 deletions

View file

@ -0,0 +1,8 @@
<!doctype html>
<meta charset=utf-8>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<div id=log></div>
<script src="optgroup-removal.window.js"></script>

View file

@ -0,0 +1,7 @@
test(() => {
const select = document.createElement("select");
select.innerHTML = "<optgroup><option>1</optgroup><optgroup><option>2";
assert_equals(select.value, "1");
select.querySelector("optgroup").remove();
assert_equals(select.value, "2");
}, "<select> needs to be updated when <optgroup> is removed");

View file

@ -0,0 +1,135 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>Option element constructor</title>
<link rel="author" title="Alex Pearson" href="mailto:alex@alexpear.com">
<link rel="help" href="https://html.spec.whatwg.org/#the-option-element">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<div id="parent">
<div id="child" tabindex="0"></div>
</div>
<body>
<script>
"use strict";
test(() => {
const option = new Option();
assert_true(option instanceof HTMLOptionElement);
assert_false(option.hasChildNodes());
assert_false(option.hasAttribute("value"));
assert_false(option.hasAttribute("selected"));
assert_false(option.selected);
assert_equals(option.textContent, "");
assert_equals(option.value, "");
}, "Option constructor with no arguments");
test(() => {
const option = new Option(false, false);
assert_true(option instanceof HTMLOptionElement);
assert_true(option.hasChildNodes());
assert_equals(option.childNodes.length, 1);
assert_equals(option.childNodes[0].nodeType, Node.TEXT_NODE);
assert_equals(option.childNodes[0].data, "false");
assert_equals(option.getAttribute("value"), "false");
assert_false(option.hasAttribute("selected"));
assert_false(option.selected);
assert_equals(option.textContent, "false");
assert_equals(option.value, "false");
}, "Option constructor with falsy arguments");
test(() => {
const option = new Option("text", "value");
assert_true(option.hasChildNodes());
assert_equals(option.childNodes.length, 1);
assert_equals(option.childNodes[0].nodeType, Node.TEXT_NODE);
assert_equals(option.childNodes[0].data, "text");
assert_equals(option.getAttribute("value"), "value");
assert_false(option.hasAttribute("selected"));
assert_false(option.selected);
assert_equals(option.textContent, "text");
assert_equals(option.value, "value");
}, "Option constructor creates HTMLOptionElement with specified text and value");
test(() => {
const notSelected = new Option("text", "value", false);
const selected = new Option("text", "value", true);
assert_false(notSelected.hasAttribute("selected"));
assert_equals(notSelected.getAttribute("selected"), null);
assert_false(notSelected.selected);
assert_equals(selected.getAttribute("selected"), "");
assert_false(selected.selected);
}, "Option constructor handles selectedness correctly when specified with defaultSelected only");
test(() => {
const notSelected = new Option("text", "value", true, false);
const selected = new Option("text", "value", false, true);
assert_equals(notSelected.selected, false);
assert_equals(selected.selected, true);
}, "Option constructor handles selectedness correctly, even when incongruous with defaultSelected");
test(() => {
const option = new Option(undefined, undefined);
assert_false(option.hasChildNodes());
assert_false(option.hasAttribute("value"));
assert_equals(option.textContent, "");
assert_equals(option.value, "");
}, "Option constructor treats undefined text and value correctly");
test(() => {
const option = new Option("", "");
assert_false(option.hasChildNodes());
assert_true(option.hasAttribute("value"));
assert_equals(option.textContent, "");
assert_equals(option.value, "");
}, "Option constructor treats empty text and value correctly");
test(() => {
const option = new Option("text", "value", 0, "");
assert_false(option.hasAttribute("selected"));
assert_false(option.selected);
}, "Option constructor treats falsy selected and defaultSelected correctly");
test(() => {
const option = new Option("text", "value", {}, 1);
assert_true(option.hasAttribute("selected"));
assert_true(option.selected);
}, "Option constructor treats truthy selected and defaultSelected correctly");
test(() => {
const option = new Option("text", "value", false, true);
assert_false(option.hasAttribute("selected"));
assert_true(option.selected);
option.setAttribute("selected", "");
assert_true(option.selected);
option.removeAttribute("selected");
assert_false(option.selected);
}, "Option constructor does not set dirtiness (so, manipulating the selected content attribute still updates the " +
"selected IDL attribute)");
test(function() {
var option = new Option();
assert_equals(Object.getPrototypeOf(option), HTMLOptionElement.prototype);
}, "Prototype of object created with named constructor");
</script>

View file

@ -0,0 +1,32 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLOptionElement.form</title>
<link rel=author title="Sergey Alexandrov" href="mailto:splavgm@gmail.com">
<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-form">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<form id="form">
<select id="select">
<optgroup id="optgroup"></optgroup>
</select>
</form>
<div id=log></div>
<script>
test(function () {
var form = document.getElementById("form");
var select = document.getElementById("select");
var optgroup = document.getElementById("optgroup");
var o1 = document.createElement("option");
assert_equals(o1.form, null);
select.appendChild(o1);
assert_equals(o1.form, select.form);
var o2 = document.createElement("option");
select.appendChild(o2);
assert_equals(o2.form, select.form);
}, "form");
</script>

View file

@ -0,0 +1,54 @@
<!DOCTYPE HTML>
<title>HTMLOptionElement.prototype.index</title>
<link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-option-index">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<select>
<option id="option0">hello</option>
<option id="option1">hello</option>
</select>
<datalist>
<option id="dl-option0">hello</option>
<option id="dl-option1">hello</option>
</datalist>
<option id="doc-option0">hello</option>
<option id="doc-option1">hello</option>
<script>
"use strict";
test(() => {
assert_equals(document.querySelector("#option0").index, 0);
assert_equals(document.querySelector("#option1").index, 1);
}, "option index should work inside the document");
test(() => {
assert_equals(document.querySelector("#dl-option0").index, 0);
assert_equals(document.querySelector("#dl-option1").index, 0);
}, "option index should always be 0 for options in datalists");
test(() => {
assert_equals(document.querySelector("#doc-option0").index, 0);
assert_equals(document.querySelector("#doc-option1").index, 0);
}, "option index should always be 0 for options with no container");
test(() => {
assert_equals(document.createElement("option").index, 0);
assert_equals(document.createElement("option").index, 0);
}, "option index should always be 0 for options not even in the document");
</script>

View file

@ -0,0 +1,82 @@
function test_option(member) {
test(function() {
var option = document.createElement("option");
assert_equals(option[member], "");
}, "No children, no " + member);
test(function() {
var option = document.createElement("option");
option.setAttribute(member, "")
assert_equals(option[member], "");
}, "No children, empty " + member);
test(function() {
var option = document.createElement("option");
option.setAttribute(member, member)
assert_equals(option[member], member);
}, "No children, " + member);
test(function() {
var option = document.createElement("option");
option.setAttributeNS("http://www.example.com/", member, member)
assert_equals(option[member], "");
}, "No children, namespaced " + member);
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" child "));
assert_equals(option[member], "child");
}, "Single child, no " + member);
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" child "));
option.setAttribute(member, "")
assert_equals(option[member], "");
}, "Single child, empty " + member);
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" child "));
option.setAttribute(member, member)
assert_equals(option[member], member);
}, "Single child, " + member);
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" child "));
option.setAttributeNS("http://www.example.com/", member, member)
assert_equals(option[member], "child");
}, "Single child, namespaced " + member);
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" child "));
option.appendChild(document.createTextNode(" node "));
assert_equals(option[member], "child node");
}, "Two children, no " + member);
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" child "));
option.appendChild(document.createTextNode(" node "));
option.setAttribute(member, "")
assert_equals(option[member], "");
}, "Two children, empty " + member);
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" child "));
option.appendChild(document.createTextNode(" node "));
option.setAttribute(member, member)
assert_equals(option[member], member);
}, "Two children, " + member);
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" child "));
option.appendChild(document.createTextNode(" node "));
option.setAttributeNS("http://www.example.com/", member, member)
assert_equals(option[member], "child node");
}, "Two children, namespaced " + member);
}

View file

@ -0,0 +1,12 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLOptionElement.label</title>
<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-label">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<script src=option-label-value.js></script>
<div id=log></div>
<script>
test_option("label")
</script>

View file

@ -0,0 +1,61 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLOptionElement.selected</title>
<link rel=author title="Corey Farwell" href="mailto:coreyf@rwell.org">
<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-selected">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<div id=log></div>
<script>
test(function () {
var elem = document.createElement("option");
assert_equals(elem.selected, false);
elem.setAttribute("selected", "");
assert_equals(elem.selected, true);
elem.removeAttribute("selected");
assert_equals(elem.selected, false);
elem.defaultSelected = true
assert_equals(elem.selected, true);
elem.defaultSelected = false;
assert_equals(elem.selected, false);
}, "not dirty");
test(function () {
testDirty(true);
}, "dirty, selected");
test(function () {
testDirty(false);
}, "dirty, not selected");
function testDirty(isSelected) {
var elem = document.createElement("option");
elem.selected = isSelected; // After this assignment, dirtiness=true
assertDirty(elem, isSelected);
elem.selected = !isSelected; // Change the value, still dirty
assertDirty(elem, !isSelected);
};
function assertDirty(elem, expect) {
assert_equals(elem.selected, expect);
elem.setAttribute("selected", "");
assert_equals(elem.selected, expect);
elem.removeAttribute("selected");
assert_equals(elem.selected, expect);
elem.defaultSelected = true;
assert_equals(elem.selected, expect);
elem.defaultSelected = false;
assert_equals(elem.selected, expect);
}
</script>

View file

@ -0,0 +1,15 @@
<!doctype html>
<meta charset=EUC-JP>
<title>Test for the backslash sign in option.text</title>
<script src=../../../../resources/testharness.js></script>
<script src=../../../../resources/testharnessreport.js></script>
<div id=log></div>
<select id=test><option>\</option></select>
<script>
test(function() {
var select = document.getElementById("test");
var option = select.firstChild;
assert_equals(option.text, "\\");
assert_equals(option.textContent, "\\");
});
</script>

View file

@ -0,0 +1,23 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLOptionElement.text</title>
<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-text">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<div id=log></div>
<script>
test(function() {
var option = document.createElement("option");
option.setAttribute("label", "label");
option.textContent = "text";
assert_equals(option.text, "text");
}, "Option with non-empty label.");
test(function() {
var option = document.createElement("option");
option.setAttribute("label", "");
option.textContent = "text";
assert_equals(option.text, "text");
}, "Option with empty label.");
</script>

View file

@ -0,0 +1,92 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLOptionElement.text</title>
<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-text">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<div id=log></div>
<script>
test(function() {
var option = document.createElement("option");
option.appendChild(document.createElement("font"))
.appendChild(document.createTextNode(" font "));
assert_equals(option.text, "font");
}, "option.text should recurse");
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" before "));
option.appendChild(document.createElement("script"))
.appendChild(document.createTextNode(" script "));
option.appendChild(document.createTextNode(" after "));
assert_equals(option.text, "before after");
}, "option.text should not recurse into HTML script elements");
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" before "));
option.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "script"))
.appendChild(document.createTextNode(" script "));
option.appendChild(document.createTextNode(" after "));
assert_equals(option.text, "before after");
}, "option.text should not recurse into SVG script elements");
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" before "));
option.appendChild(document.createElementNS("http://www.w3.org/1998/Math/MathML", "script"))
.appendChild(document.createTextNode(" script "));
option.appendChild(document.createTextNode(" after "));
assert_equals(option.text, "before script after");
}, "option.text should recurse into MathML script elements");
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode(" before "));
option.appendChild(document.createElementNS(null, "script"))
.appendChild(document.createTextNode(" script "));
option.appendChild(document.createTextNode(" after "));
assert_equals(option.text, "before script after");
}, "option.text should recurse into null script elements");
test(function() {
var option = document.createElement("option");
var span = option.appendChild(document.createElement("span"));
span.appendChild(document.createTextNode(" Some "));
span.appendChild(document.createElement("script"))
.appendChild(document.createTextNode(" script "));
option.appendChild(document.createTextNode(" Text "));
assert_equals(option.text, "Some Text");
}, "option.text should work if a child of the option ends with a script");
test(function() {
var script = document.createElement("script");
var option = script.appendChild(document.createElement("option"));
option.appendChild(document.createTextNode("text"));
assert_equals(option.text, "text");
}, "option.text should work if the option is in an HTML script element");
test(function() {
var script = document.createElementNS("http://www.w3.org/2000/svg", "script");
var option = script.appendChild(document.createElement("option"));
option.appendChild(document.createTextNode("text"));
assert_equals(option.text, "text");
}, "option.text should work if the option is in an SVG script element");
test(function() {
var script = document.createElementNS("http://www.w3.org/1998/Math/MathML", "script");
var option = script.appendChild(document.createElement("option"));
option.appendChild(document.createTextNode("text"));
assert_equals(option.text, "text");
}, "option.text should work if the option is in a MathML script element");
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode("te"));
option.appendChild(document.createComment("comment"));
option.appendChild(document.createTextNode("xt"));
assert_equals(option.text, "text");
}, "option.text should ignore comment children");
test(function() {
var option = document.createElement("option");
option.appendChild(document.createTextNode("te"));
option.appendChild(document.createProcessingInstruction("target", "data"));
option.appendChild(document.createTextNode("xt"));
assert_equals(option.text, "text");
}, "option.text should ignore PI children");
</script>

View file

@ -0,0 +1,24 @@
<!doctype html>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<form>
<select>
<option value='foo'>bar</option>
</select>
</form>
<script>
test(() => {
var option = document.querySelector('option');
var textChild = option.firstChild;
assert_equals(textChild.nodeValue, "bar", "Verify that text child node's value equals the option value.");
assert_true(textChild.isConnected, 'Verify that text child node is in the document.');
option.text = "baz";
assert_equals(textChild.nodeValue, "bar", 'Verify that the text child node does not have an updated value.');
assert_false(textChild.isConnected, 'Verify that the text child node is not in the document.');
assert_not_equals(textChild, option.firstChild, 'Verify that text child node was replaced by a different text child node.');
assert_equals(option.firstChild.nodeValue, "baz", 'Verify that the new text child node does equal the updated value.');
assert_equals(option.text, "baz", 'Verify that option text getter returns the updated value.');
option.text = "";
assert_equals(option.firstChild, null, 'Verify that after setting to empty string there are no child text nodes.');
}, 'Verify that using HTMLOptionElement.text setter does not update the existing text child node.');
</script>

View file

@ -0,0 +1,75 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLOptionElement.text</title>
<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-text">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<div id=log></div>
<script>
test(function() {
var spaces = ["\u0020", "\u0009", "\u000A", "\u000C", "\u000D"];
spaces.forEach(function(space) {
test(function() {
var option = document.createElement("option");
option.textContent = space + "text";
assert_equals(option.text, "text");
}, "option.text should strip leading space characters (" +
format_value(space) + ")");
});
spaces.forEach(function(space) {
test(function() {
var option = document.createElement("option");
option.textContent = "text" + space;
assert_equals(option.text, "text");
}, "option.text should strip trailing space characters (" +
format_value(space) + ")");
});
spaces.forEach(function(space) {
test(function() {
var option = document.createElement("option");
option.textContent = space + "text" + space;
assert_equals(option.text, "text");
}, "option.text should strip leading and trailing space characters (" +
format_value(space) + ")");
});
spaces.forEach(function(space) {
test(function() {
var option = document.createElement("option");
option.textContent = "before" + space + "after";
assert_equals(option.text, "before after");
}, "option.text should replace single internal space characters (" +
format_value(space) + ")");
});
spaces.forEach(function(space1) {
spaces.forEach(function(space2) {
test(function() {
var option = document.createElement("option");
option.textContent = "before" + space1 + space2 + "after";
assert_equals(option.text, "before after");
}, "option.text should replace multiple internal space characters (" +
format_value(space1) + ", " + format_value(space2) + ")");
});
});
test(function() {
var option = document.createElement("option");
option.textContent = "\u00a0text";
assert_equals(option.text, "\u00a0text");
}, "option.text should leave leading NBSP alone.");
test(function() {
var option = document.createElement("option");
option.textContent = "text\u00a0";
assert_equals(option.text, "text\u00a0");
}, "option.text should leave trailing NBSP alone.");
test(function() {
var option = document.createElement("option");
option.textContent = "before\u00a0after";
assert_equals(option.text, "before\u00a0after");
}, "option.text should leave a single internal NBSP alone.");
test(function() {
var option = document.createElement("option");
option.textContent = "before\u00a0\u00a0after";
assert_equals(option.text, "before\u00a0\u00a0after");
}, "option.text should leave two internal NBSPs alone.");
});
</script>

View file

@ -0,0 +1,12 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLOptionElement.value</title>
<link rel=author title=Ms2ger href="mailto:Ms2ger@gmail.com">
<link rel=help href="https://html.spec.whatwg.org/multipage/#dom-option-label">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<script src=option-label-value.js></script>
<div id=log></div>
<script>
test_option("value")
</script>

View file

@ -0,0 +1,9 @@
features:
- name: constraint-validation
files:
- select-setcustomvalidity.html
- select-validity.html
- select-willvalidate-readonly-attribute.html
- name: show-picker-select
files:
- show-picker-*

View file

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title id='title'>HTMLOptionsCollection</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<select id="selly">
<option id="id1" name="name1">1</option>
<option id="id2" name="name2">2</option>
<option id="id3" name="name3">3</option>
<option id="id4" name="name4">4</option>
<optgroup id="og1">
<option name="nameonly">n1</option>
<option id="id5">5</option>
</optgroup>
<optgroup id="og2">
<option name="nameonly">n2</option>
<option id="id6">6</option>
</optgroup>
</select>
<script>
var selly;
setup(function() {
selly = document.getElementById('selly');
});
test(function () {
var option = document.getElementById('id1');
var optgroup = document.getElementById('og1');
selly.options.add(option, option);
selly.options.add(optgroup, optgroup);
assert_equals(selly.children.length, 6);
assert_equals(selly.length, 8);
}, "if before and node are the same element nothing should be done");
test(function () {
var o1 = document.createElement("option");
o1.value = "a";
var o2 = document.createElement("option");
o2.value = "b";
var o3 = document.createElement("option");
o3.value = "c";
var optgroup = document.getElementById('og1');
selly.options.add(o1, null);
selly.options.add(o2, optgroup);
selly.options.add(o3, 0);
var elarray = [];
for (var i = 0; i < selly.length; i++) {
elarray.push(selly[i].value);
}
assert_array_equals(elarray, ["c", "1", "2", "3", "4", "b", "n1", "5", "n2", "6", "a"]);
}, "add method should add option elements correctly");
test(function () {
var og1 = document.createElement("optgroup");
var o1 = document.createElement("option");
o1.value = "a";
o1.appendChild(og1);
var og2 = document.createElement("optgroup");
var o2 = document.createElement("option");
o2.value = "b";
o2.appendChild(og2);
var og3 = document.createElement("optgroup");
var o3 = document.createElement("option");
o3.value = "c";
o3.appendChild(og3);
var optgroup = document.getElementById('og1');
selly.options.add(og1, null);
selly.options.add(og2, optgroup);
selly.options.add(og3, 0);
var elarray = [];
for (var i = 0; i < selly.length; i++) {
elarray.push(selly[i].value);
}
assert_array_equals(elarray, ["c", "1", "2", "3", "4", "b", "n1", "5", "n2", "6", "a"]);
}, "add method should add option groups correctly");
</script>
</body>
</html>

View file

@ -0,0 +1,54 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title id='title'>HTMLOptionsCollection</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<select id="selly">
<option id="id1" name="name1">1</option>
<option id="id2" name="name2">2</option>
<option id="id3" name="name3">3</option>
<option id="id4" name="name4">4</option>
<option name="nameonly">nameonly</option>
<option id="id3">duplicate ID</option>
<option name="name4">duplicate name</option>
<option id="mixed1">mixed ID</option>
<option name="mixed1">mixed name</option>
</select>
<script>
var selly;
setup(function() {
selly = document.getElementById('selly');
});
test(function () {
assert_equals(selly.namedItem('nameonly')["value"], "nameonly");
}, "if only one item has a *name* or id value matching the parameter, return that object and stop");
test(function () {
assert_equals(selly.namedItem('id2')["value"], "2");
}, "if only one item has a name or *id* value matching the parameter, return that object and stop");
test(function () {
assert_equals(selly.namedItem('thisdoesnotexist'), null);
}, "if no item has a name or id value matching the parameter, return null and stop");
test(function () {
assert_equals(selly.namedItem('id3')["value"], "3");
}, "if multiple items have a name or *id* value matching the parameter, return the first object and stop");
test(function () {
assert_equals(selly.namedItem('name4')["value"], "4");
}, "if multiple items have a *name* or id value matching the parameter, return the first object and stop");
test(function () {
assert_equals(selly.namedItem('mixed1')["value"], "mixed ID");
}, "if multiple items have a *name* or *id* value matching the parameter, return the first object and stop");
</script>
</body>
</html>

View file

@ -0,0 +1,117 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title id='title'>HTMLOptionsCollection</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<div id="log"></div>
<select id="selly">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
<script>
var selly;
setup(function() {
selly = document.getElementById('selly');
});
test(function () {
assert_equals(selly.length, 4);
}, "On getting, the length attribute must return the number of nodes represented by the collection.");
test(function () {
selly.length = 7;
assert_equals(selly.length, 7,
"Number of nodes in collection should have changed");
assert_equals(selly.children.length, 7,
"Number of children should have changed");
for (var i = 4; i < 7; ++i) {
var child = selly.children[i];
assert_equals(child.localName, "option",
"new child should be an option");
assert_equals(child.namespaceURI, "http://www.w3.org/1999/xhtml",
"new child should be an HTML element");
assert_equals(child.attributes.length, 0,
"new child should not have attributes");
assert_equals(child.childNodes.length, 0,
"new child should not have child nodes");
}
}, "Changing the length adds new nodes; The number of new nodes = new length minus old length");
test(function () {
var elarray = [];
for (var i = 0; i < selly.length; i++) {
elarray.push(selly[i].value);
}
assert_array_equals(elarray, ["1", "2", "3", "4", "", "", ""]);
}, "New nodes have no value");
test(function () {
selly.length = 7;
assert_equals(selly.length, 7,
"Number of nodes in collection should not have changed");
assert_equals(selly.children.length, 7,
"Number of children should not have changed");
}, "Setting a length equal to existing length changes nothing");
test(function () {
selly.length = 4;
assert_equals(selly[6], undefined,
"previously set node is now undefined");
assert_equals(selly.length, 4,
"Number of nodes in collection is correctly changed");
assert_equals(selly.children.length, 4,
"Number of children should have changed");
}, "Setting a length lower than the old length trims nodes from the end");
test(function () {
var opts = selly.options;
opts[3] = null;
assert_equals(selly[3], undefined,
"previously set node is now undefined");
assert_equals(selly.length, 3,
"Number of nodes in collection is correctly changed");
assert_equals(selly.children.length, 3,
"Number of children should have changed");
}, "Setting element to null by index removed the element");
test(function () {
var opts = selly.options;
var new_option = document.createElement("option");
var replace_option = new_option.cloneNode(true);
new_option.value = "-1";
replace_option.value = "a";
opts[5] = new_option;
opts[0] = replace_option;
var elarray = [];
for (var i = 0; i < selly.length; i++) {
elarray.push(selly[i].value);
}
assert_array_equals(elarray, ["a", "2", "3", "", "", "-1"]);
}, "Setting element by index should correctly append and replace elements");
test(function () {
var selection = document.createElementNS("http://www.w3.org/1999/xhtml", "foo:select");
selection.length = 5;
assert_equals(selection.length, 5,
"Number of nodes in collection should have changed");
for (var i = 0; i < 5; ++i) {
var child = selection.children[i];
assert_equals(child.localName, "option",
"new child should be an option");
assert_equals(child.namespaceURI, "http://www.w3.org/1999/xhtml",
"new child should be an HTML element");
assert_equals(child.prefix, null,
"new child should not copy select's prefix");
}
}, "Changing the length adds new nodes; The new nodes will not copy select's prefix");
</script>

View file

@ -0,0 +1,103 @@
<!DOCTYPE html>
<link rel="help" href="https://html.spec.whatwg.org/C/#the-select-element:nodes-are-inserted">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<body>
<select id="by-parser">
<option selected>First</option>
<option selected>Second</option>
</select>
<select id="by-parser-optgroup">
<optgroup>
<option selected>First</option>
<option selected>Second</option>
</optgroup>
</select>
<select id="by-dom"></select>
<select id="by-innerHTML"></select>
<script>
test(() => {
const target = document.querySelector("#by-parser");
assert_equals(target.selectedOptions[0].textContent, 'Second');
const target2 = document.querySelector("#by-parser-optgroup");
assert_equals(target2.selectedOptions[0].textContent, 'Second');
}, 'The last selected OPTION should win; Inserted by parser');
test(() => {
const target = document.querySelector("#by-dom");
const option1 = document.createElement('option');
option1.defaultSelected = true;
option1.textContent = 'First';
const option2 = document.createElement('option');
option2.defaultSelected = true;
option2.textContent = 'Second';
target.appendChild(option1);
target.appendChild(option2);
assert_equals(target.selectedOptions[0].textContent, 'Second');
target.innerHTML = '';
const optgroup = document.createElement('optgroup');
const option3 = document.createElement('option');
option3.defaultSelected = true;
option3.textContent = 'First';
const option4 = document.createElement('option');
option4.defaultSelected = true;
option4.textContent = 'Second';
optgroup.appendChild(option3);
optgroup.appendChild(option4);
target.appendChild(optgroup);
assert_equals(target.selectedOptions[0].textContent, 'Second');
}, 'The last selected OPTION should win; Inserted by DOM API');
test(() => {
const target = document.querySelector("#by-dom");
target.innerHTML = '';
const inner = `<option value="one" selected>First</option>
<option value="two" selected>Second</option>`;
// Emulate what jQuery 1.x/2.x does in append(inner).
const fragment = document.createDocumentFragment();
const div = document.createElement('div');
div.innerHTML = '<select multiple>' + inner + '</select>';
while (div.firstChild.firstChild)
fragment.appendChild(div.firstChild.firstChild);
target.appendChild(fragment);
assert_equals(target.selectedOptions[0].textContent, 'Second');
}, 'The last selected OPTION should win; Inserted by jQuery append()');
test(() => {
const target = document.querySelector("#by-innerHTML");
target.innerHTML = '<option selected>First</option>' +
'<option selected>Second</option>';
assert_equals(target.selectedOptions[0].textContent, 'Second');
target.innerHTML = '<option selected>First</option>' +
'<optgroup><option selected>Second</option>' +
'<option selected>Third</option></optgroup>' +
'<option selected>Fourth</option>';
assert_equals(target.selectedOptions[0].textContent, 'Fourth');
}, 'The last selected OPTION should win; Inserted by innerHTML');
test (() => {
for (let insert_location = 0; insert_location < 3; ++insert_location) {
const target = document.querySelector('#by-innerHTML');
target.innerHTML = '<option>A</option>' +
'<option selected>C</option>' +
'<option>D</option>';
const refNode = target.querySelectorAll('option')[insert_location];
const opt = document.createElement('option');
opt.selected = true;
opt.textContent = 'B';
target.insertBefore(opt, refNode);
assert_equals(target.selectedOptions[0].textContent, 'B');
}
}, 'If an OPTION says it is selected, it should be selected after it is inserted.');
</script>
</body>

View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@chromium.org">
<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=1477785">
<link rel=help href="https://html.spec.whatwg.org/multipage/common-dom-interfaces.html#dom-htmloptionscollection-add">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<select>
<option id=opt1>opt1</option>
<optgroup label=group1>
<option id=opt2>opt2</option>
</optgroup>
</select>
<script>
test(() => {
const select = document.querySelector('select');
const optgroup = document.querySelector('optgroup');
const newOption = document.createElement('option');
newOption.textContent = 'new option';
select.options.add(newOption, 1);
assert_equals(select.options.length, 3);
assert_equals(select.options[0], opt1, 'First item should be opt1.');
assert_equals(select.options[1], newOption, 'Second item should be newOption.');
assert_equals(select.options[2], opt2, 'Third item should be opt2.');
assert_equals(newOption.parentNode, optgroup, 'The new option should be inside the optgroup.');
}, 'select.add() with an index should work when the target is inside an optgroup.');
</script>

View file

@ -0,0 +1,36 @@
<!DOCTYPE html>
<meta charset="utf-8">
<title>HTMLSelectElement Test: add()</title>
<link rel="author" title="Intel" href="http://www.intel.com/">
<link rel="help" href="https://html.spec.whatwg.org/multipage/form-elements.html#dom-select-add-dev">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<form style="display:none">
<option id="testoption">
<select id="testselect1">
</select>
<select id="testselect2">
<option>TEST</option>
</select>
</option>
</form>
<script>
test(() => {
let testselect1 = document.getElementById("testselect1");
let opt1 = new Option("Marry","1");
testselect1.add(opt1);
assert_equals(testselect1.options[0].value, "1");
}, "test that HTMLSelectElement.add method can add option element");
test(() => {
let testselect2 = document.getElementById("testselect2");
let opt2 = document.getElementById("testoption");
assert_throws_dom("HierarchyRequestError", () => {
testselect2.add(opt2);
});
}, "test that HierarchyRequestError exception must be thrown when element is an ancestor of the element into which it is to be inserted");
</script>

View file

@ -0,0 +1,97 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLSelectElement ask for reset</title>
<link rel="author" title="Dongie Agnir" href="dongie.agnir@gmail.com">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<div id=log></div>
<script>
test(function() {
var select = makeSelect(5);
select.children[4].selected = true;
unselectedExcept(select, 4);
select.children[4].remove();
unselectedExcept(select, 0); // remove selected node, should default to first
select.children[3].selected = true;
select.children[0].remove();
unselectedExcept(select, 2); // last node still selected
select.size = 2;
select.children[2].remove();
unselectedExcept(select, null);
}, "ask for reset on node remove, non multiple.");
test(function() {
var select = makeSelect(3);
select.children[1].selected = true;
// insert selected option, should remain selected
var opt4 = document.createElement("option");
opt4.selected = true;
select.appendChild(opt4);
unselectedExcept(select, 3);
// insert unselected, 3 should remain selected
var opt5 = document.createElement("option");
select.appendChild(opt5);
unselectedExcept(select, 3);
}, "ask for reset on node insert, non multiple.");
test(function() {
var select = makeSelect(3);
var options = select.children;
// select options from first to last
for (var i = 0; i < options.length; ++i) {
options[i].selected = true;
unselectedExcept(select, i);
}
// select options from last to first
for (var i = options.length - 1; i >= 0; --i) {
options[i].selected = true;
unselectedExcept(select, i);
}
options[2].selected = true;
options[2].selected = false; // none selected
unselectedExcept(select, 0);
// disable first so option at index 1 is first eligible
options[0].disabled = true;
options[2].selected = true;
options[2].selected = false; // none selected
unselectedExcept(select, 1);
select.size = 2;
options[1].selected = false;
unselectedExcept(select, null); // size > 1 so should not default to any
}, "change selectedness of option, non multiple.");
function unselectedExcept(sel, opt) {
for (var i = 0; i < sel.children.length; ++i) {
if (i != opt) {
assert_false(sel.children[i].selected, "option should not be selected.");
}
if (opt != null) {
assert_true(sel.children[opt].selected, "option should be selected.");
}
}
}
function makeSelect(n) {
var sel = document.createElement("select");
for (var i = 0; i < n; ++i) {
opt = document.createElement("option");
sel.appendChild(opt);
}
return sel;
}
</script>

View file

@ -0,0 +1,48 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLSelectElement ask for reset</title>
<link rel="author" title="Sebastian Mayr" href="wpt@smayr.name">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<select multiple id="initial-selected">
<option selected>Test 1</option>
<option selected>Test 2</option>
</select>
<select multiple id="scripted-select">
<option selected>Test 1</option>
<option>Test 2</option>
</select>
<div id=log></div>
<script>
"use strict";
test(() => {
const select = document.getElementById("initial-selected");
assert_true(select.options[0].selected, "first option should be selected.");
assert_true(select.options[1].selected, "second option should be selected.");
}, "multiple selected options exist, both set from markup");
test(() => {
const select = document.getElementById("initial-selected");
select.options[1].selected = true;
assert_true(select.options[0].selected, "first option should be selected.");
assert_true(select.options[1].selected, "second option should be selected.");
}, "multiple selected options exist, one set from script");
// crbug.com/1245443
test(() => {
let select = document.createElement("select");
select.length = 4;
let o1 = select.options.item(1);
select.multiple = true;
select.selectedIndex = 2;
o1.selected = true;
select.multiple = false;
assert_equals(select.selectedOptions.length, 1);
}, "Removing multiple attribute reduces the number of selected OPTIONs to 1");
</script>

View file

@ -0,0 +1,46 @@
<!doctype html>
<meta charset=utf-8>
<title>Absence of a named getter on HTMLSelectElement</title>
<script src=../../../../resources/testharness.js></script>
<script src=../../../../resources/testharnessreport.js></script>
<div id=log></div>
<select id=select>
<option id=op1>A</option>
<option name=op2>B</option>
<option id=op3 name=op4>C</option>
<option id=>D</option>
<option name=>D</option>
</select>
<script>
test(function() {
var select = document.getElementById("select");
assert_equals(select.op1, undefined);
assert_false("op1" in select);
assert_equals(select.namedItem("op1"), select.children[0]);
}, "Option with id")
test(function() {
var select = document.getElementById("select");
assert_equals(select.op2, undefined);
assert_false("op2" in select);
assert_equals(select.namedItem("op2"), select.children[1]);
}, "Option with name")
test(function() {
var select = document.getElementById("select");
assert_equals(select.op3, undefined);
assert_false("op3" in select);
assert_equals(select.namedItem("op3"), select.children[2]);
assert_equals(select.op4, undefined);
assert_false("op4" in select);
assert_equals(select.namedItem("op4"), select.children[2]);
}, "Option with name and id")
test(function() {
var select = document.getElementById("select");
assert_equals(select[""], undefined);
assert_false("" in select);
assert_equals(select.namedItem(""), null);
}, "Empty string name");
</script>

View file

@ -0,0 +1,64 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLSelectElement.remove</title>
<link rel="author" title="Ms2ger" href="Ms2ger@gmail.com">
<link rel="help" href="https://dom.spec.whatwg.org/#dom-childnode-remove">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-select-remove">
<link rel="help" href="https://html.spec.whatwg.org/multipage/#dom-htmloptionscollection-remove">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<div id=log></div>
<script>
function testRemove(getter, desc) {
test(function() {
var div = document.createElement("div");
var select = document.createElement("select");
div.appendChild(select);
assert_equals(select.parentNode, div);
var options = [];
for (var i = 0; i < 3; ++i) {
var option = document.createElement("option");
option.textContent = String(i);
select.appendChild(option);
options.push(option);
}
getter(select).remove(-1);
assert_array_equals(select.options, options, "After remove(-1)");
assert_equals(select.parentNode, div);
getter(select).remove(3);
assert_array_equals(select.options, options, "After remove(3)");
assert_equals(select.parentNode, div);
getter(select).remove(0);
assert_array_equals(select.options, [options[1], options[2]], "After remove(0)");
assert_equals(select.parentNode, div);
}, desc)
}
testRemove(function(select) { return select; }, "select.remove(n) should work");
testRemove(function(select) { return select.options; }, "select.options.remove(n) should work");
test(function() {
var div = document.createElement("div");
var select = document.createElement("select");
div.appendChild(select);
assert_equals(select.parentNode, div);
assert_equals(div.firstChild, select);
select.remove();
assert_equals(select.parentNode, null);
assert_equals(div.firstChild, null);
}, "remove() should work on select elements.")
test(function() {
var div = document.createElement("div");
var select = document.createElement("select");
div.appendChild(select);
assert_equals(select.parentNode, div);
assert_equals(div.firstChild, select);
Element.prototype.remove.call(select);
assert_equals(select.parentNode, null);
assert_equals(div.firstChild, null);
}, "Element#remove() should work on select elements.")
</script>

View file

@ -0,0 +1,65 @@
<!DOCTYPE html>
<html lang="en">
<title>HTMLselectElement Test: required attribute</title>
<link rel="author" title="Ionel Popescu" href="mailto:iopopesc@microsoft.com">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<style>
select:required {
border: 3px dashed rgb(255, 0, 0);
}
select:optional {
border: 1px solid rgb(128, 128, 128);
}
select, ::picker(select) {
appearance: base-select;
}
</style>
<select id="select0" required>
<option>one</option>
<option>two</option>
<option>three</option>
</select>
<select id="select1">
<option>one</option>
<option>two</option>
<option>three</option>
</select>
<select id="select2">
<option>one</option>
<option>two</option>
<option>three</option>
</select>
<script>
function checkRequired(style) {
assert_equals(style.borderWidth, '3px');
assert_equals(style.borderStyle, 'dashed');
assert_equals(style.borderColor, 'rgb(255, 0, 0)');
}
function checkOptional(style) {
assert_equals(style.borderWidth, '1px');
assert_equals(style.borderStyle, 'solid');
assert_equals(style.borderColor, 'rgb(128, 128, 128)');
}
test(() => {
const select0 = document.getElementById("select0");
const select1 = document.getElementById("select1");
const select2 = document.getElementById("select2");
checkRequired(window.getComputedStyle(select0));
checkOptional(window.getComputedStyle(select1));
checkOptional(window.getComputedStyle(select2));
select2.required = true;
checkRequired(window.getComputedStyle(select2));
}, "Test required attribute");
</script>

View file

@ -0,0 +1,143 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>HTMLSelectElement.selectedOptions</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/forms.html#dom-select-selectedoptions">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
</head>
<body>
<div id="log"></div>
<select id="select-none-selected">
<option>One</option>
<option>Two</option>
<option>Three</option>
</select>
<select id="select-one-selected">
<option>One</option>
<option selected>Two</option>
<option>Three</option>
</select>
<select multiple id="multiple-select-none-selected">
<option>One</option>
<option>Two</option>
<option>Three</option>
</select>
<select multiple id="multiple-select-two-selected">
<option>One</option>
<option selected>Two</option>
<option selected>Three</option>
</select>
<select id="select-named-selected">
<option>One</option>
<option>Two</option>
<option id="named-option" selected>Three</option>
</select>
<select id="invalid-select">
<option selected>One</option>
<option selected>Two</option>
<option>Three</option>
</select>
<select id="select-same-object">
<option>One</option>
<option selected>Two</option>
<option>Three</option>
</select>
<select multiple id="select-same-object-change">
<option selected>One</option>
<option selected>Two</option>
<option selected>Three</option>
</select>
<script>
"use strict";
test(() => {
const select = document.getElementById("select-none-selected");
assert_array_equals(select.selectedOptions, [select.children[0]]);
assert_equals(select.selectedOptions.length, 1);
}, ".selectedOptions with no selected option");
test(() => {
const select = document.getElementById("select-one-selected");
assert_array_equals(select.selectedOptions, [select.children[1]]);
assert_equals(select.selectedOptions.length, 1);
}, ".selectedOptions with one selected option");
test(() => {
const select = document.getElementById("multiple-select-none-selected");
assert_equals(select.selectedOptions.item(0), null);
assert_equals(select.selectedOptions.length, 0);
}, ".selectedOptions using the 'multiple' attribute with no selected options");
test(() => {
const select = document.getElementById("multiple-select-two-selected");
assert_equals(select.selectedOptions.item(0), select.children[1]);
assert_equals(select.selectedOptions.item(1), select.children[2]);
assert_equals(select.selectedOptions.length, 2);
}, ".selectedOptions using the 'multiple' attribute with two selected options");
// "A select element whose multiple attribute is not specified must not have
// more than one descendant option element with its selected attribute set."
// - https://html.spec.whatwg.org/multipage/forms.html#the-option-element:the-select-element-6
// "If two or more option elements in the select element's list of options
// have their selectedness set to true, set the selectedness of all but
// the last option element with its selectedness set to true in the list of
// options in tree order to false."
// - https://html.spec.whatwg.org/multipage/forms.html#the-select-element:the-option-element-21
test(() => {
const select = document.getElementById("invalid-select");
assert_array_equals(select.selectedOptions, [select.children[1]]);
assert_equals(select.selectedOptions.length, 1);
}, ".selectedOptions without the 'multiple' attribute but " +
"more than one selected option should return the last one");
test(() => {
const select = document.getElementById("select-named-selected");
assert_equals(select.selectedOptions.constructor, HTMLCollection);
assert_equals(select.selectedOptions.namedItem("named-option"), select.children[2]);
}, ".selectedOptions should return `HTMLCollection` instance");
test(() => {
const select = document.getElementById("select-same-object");
const selectAgain = document.getElementById("select-same-object");
assert_equals(select.selectedOptions, selectAgain.selectedOptions);
}, ".selectedOptions should always return the same value - [SameObject]");
test(() => {
const select = document.getElementById("select-same-object-change");
const before = select.selectedOptions;
assert_equals(before.length, 3);
select.selectedOptions[1].selected = false;
const after = select.selectedOptions;
assert_equals(before, after);
assert_equals(before.length, 2);
assert_equals(after.length, 2);
}, ".selectedOptions should return the same object after selection changes - [SameObject]");
</script>
</body>
</html>

View file

@ -0,0 +1,17 @@
<!DOCTYPE HTML>
<title>select setCustomValidity</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<select id='select_test'></select>
<script>
test(() => {
let elem = document.getElementById("select_test");
assert_false(elem.validity.customError);
elem.setCustomValidity("custom error");
assert_true(elem.validity.customError);
}, "select setCustomValidity is correct")
</script>

View file

@ -0,0 +1,124 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLSelectElement.checkValidity</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/forms.html#the-select-element:attr-select-required-4">
<script src=../../../../resources/testharness.js></script>
<script src=../../../../resources/testharnessreport.js></script>
<div id=log></div>
<script>
test(function() {
var select = document.createElement('select');
assert_true(select.willValidate, "A select element is a submittable element that is a candidate for constraint validation.");
var placeholder = document.createElement('option');
select.appendChild(placeholder);
assert_true(select.checkValidity(), "Always valid when the select isn't a required value.");
select.required = true;
assert_true(placeholder.selected, "If display size is 1, multiple is absent and no options have selectedness true, the first option is selected.");
assert_equals(select.value, "", "The placeholder's value should be the select's value right now");
assert_false(select.checkValidity(), "A selected placeholder option should invalidate the select.");
var emptyOption = document.createElement('option');
select.appendChild(emptyOption);
emptyOption.selected = true;
assert_equals(select.value, "", "The empty value should be set.");
assert_true(select.checkValidity(), "An empty non-placeholder option should be a valid choice.");
var filledOption = document.createElement('option');
filledOption.value = "test";
select.appendChild(filledOption);
filledOption.selected = true;
assert_equals(select.value, "test", "The non-empty value should be set.");
assert_true(select.checkValidity(), "A non-empty non-placeholder option should be a valid choice.");
select.removeChild(placeholder);
select.appendChild(emptyOption); // move emptyOption to second place
emptyOption.selected = true;
assert_equals(select.value, "", "The empty value should be set.");
assert_true(select.checkValidity(), "Only the first option can be seen as a placeholder.");
placeholder.disabled = true;
select.insertBefore(placeholder, filledOption);
placeholder.selected = true;
assert_equals(select.value, "", "A disabled first placeholder option should result in an empty value.");
assert_false(select.checkValidity(), "A disabled first placeholder option should invalidate the select.");
}, "Placeholder label options within a select");
test(function() {
var select = document.createElement('select');
select.required = true;
var optgroup = document.createElement('optgroup');
var emptyOption = document.createElement('option');
optgroup.appendChild(emptyOption);
select.appendChild(optgroup);
emptyOption.selected = true;
assert_equals(select.value, "", "The empty value should be set.");
assert_true(select.checkValidity(), "The first option is not considered a placeholder if it is located within an optgroup.");
var otherEmptyOption = document.createElement('option');
otherEmptyOption.value = "";
select.appendChild(otherEmptyOption);
otherEmptyOption.selected = true;
assert_equals(select.value, "", "The empty value should be set.");
assert_true(select.checkValidity(), "The empty option should be accepted as it is not the first option in the tree ordered list.");
}, "Placeholder label-like options within optgroup");
test(function() {
var select = document.createElement('select');
select.required = true;
select.size = 2;
var emptyOption = document.createElement('option');
select.appendChild(emptyOption);
assert_false(emptyOption.selected, "Display size is not 1, so the first option should not be selected.");
assert_false(select.checkValidity(), "If no options are selected the select must be seen as invalid.");
emptyOption.selected = true;
assert_true(select.checkValidity(), "If one option is selected, the select should be considered valid.");
var otherEmptyOption = document.createElement('option');
otherEmptyOption.value = "";
select.appendChild(otherEmptyOption);
otherEmptyOption.selected = true;
assert_false(emptyOption.selected, "Whenever an option has its selectiveness set to true, the other options must be set to false.");
otherEmptyOption.selected = false;
assert_false(otherEmptyOption.selected, "It should be possible to set the selectiveness to false with a display size more than one.");
assert_false(select.checkValidity(), "If no options are selected the select must be seen as invalid.");
}, "Validation on selects with display size set as more than one");
test(function() {
var select = document.createElement('select');
select.required = true;
select.multiple = true;
var emptyOption = document.createElement('option');
select.appendChild(emptyOption);
assert_false(select.checkValidity(), "If no options are selected the select must be seen as invalid.");
emptyOption.selected = true;
assert_true(select.checkValidity(), "If one option is selected, the select should be considered valid.");
var optgroup = document.createElement('optgroup');
optgroup.appendChild(emptyOption); // Move option to optgroup
select.appendChild(optgroup);
assert_true(select.checkValidity(), "If one option within an optgroup or not is selected, the select should be considered valid.");
}, "Validation on selects with multiple set");
test(function() {
var select = document.createElement('select');
select.required = true;
var option = document.createElement('option');
option.value = 'test';
option.disabled = true;
option.selected = true;
select.appendChild(option);
assert_true(select.checkValidity(), "When a required select has an option that is selected and disabled, the select should be considered valid.");
}, "Validation on selects with non-empty disabled option");
test(function() {
var select = document.createElement('select');
select.required = true;
var placeholder = document.createElement('option');
select.appendChild(placeholder);
var nonPlaceholder = document.createElement('option');
nonPlaceholder.textContent = "non-placeholder-option";
select.appendChild(nonPlaceholder);
assert_false(select.checkValidity(), "If the placeholder label option is selected, required select element shouldn't be valid.");
placeholder.remove();
assert_true(select.checkValidity(), "If the placeholder label option is removed, required select element should become valid.");
select.prepend(placeholder);
assert_false(select.checkValidity(), "If the placeholder label option is selected, required select element shouldn't be valid.");
}, "Remove and add back the placeholder label option");
</script>

View file

@ -0,0 +1,94 @@
<!DOCTYPE html>
<html lang="en">
<title>HTMLselectElement Test: validity</title>
<link rel="author" title="Ionel Popescu" href="mailto:iopopesc@microsoft.com">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<select id="select1" required>
<option>one</option>
<option>two</option>
<option>three</option>
<option>four</option>
</select>
<form>
<select id="select2" required>
</select>
</form>
<style>
select, ::picker(select) {
appearance: base-select;
}
</style>
<script>
test(() => {
let select = document.createElement('select');
assert_true(select.willValidate, "A select element is a submittable element that is a candidate for constraint validation.");
let option = document.createElement('option');
select.appendChild(option);
assert_true(select.checkValidity(), "Always valid when the select isn't a required value.");
select.required = true;
assert_equals(select.value, "");
assert_false(select.checkValidity(), "A selected placeholder option should invalidate the select.");
let emptyOption = document.createElement('option');
select.appendChild(emptyOption);
assert_false(select.checkValidity(), "A selected placeholder option should invalidate the select even if there are multiple options.");
emptyOption.selected = true;
assert_true(select.checkValidity(), "An empty non-placeholder option should be a valid choice.");
let filledOption = document.createElement('option');
filledOption.value = "test";
select.appendChild(filledOption);
filledOption.selected = true;
assert_equals(select.value, "test", "The non-empty value should be set.");
assert_true(select.checkValidity(), "A non-empty non-placeholder option should be a valid choice.");
select.removeChild(option);
select.appendChild(emptyOption);
emptyOption.selected = true;
assert_equals(select.value, "", "The empty value should be set.");
assert_true(select.checkValidity(), "Only the first option can be seen as a placeholder.");
select.removeChild(filledOption);
assert_false(select.checkValidity(), "A selected placeholder option should invalidate the select.");
emptyOption.value = "test2";
assert_equals(select.value, "test2");
assert_true(select.checkValidity(), "A non-empty option value should be a valid choice.");
emptyOption.removeAttribute("value");
assert_equals(select.value, "");
assert_false(select.checkValidity());
emptyOption.innerText = "test";
assert_equals(select.value, "test");
assert_true(select.checkValidity(), "A non-empty option should be a valid choice.");
const select1 = document.getElementById('select1');
assert_equals(select1.value, "one");
assert_true(select1.checkValidity(), "A select with non-empty placeholder option should be valid.");
}, "Validation for placeholder option");
test(() => {
const select2 = document.getElementById('select2');
assert_equals(select2.value, "");
assert_false(select2.checkValidity());
let form = document.querySelector('form');
let invalidControl = form.querySelector('select:invalid');
assert_equals(select2, invalidControl);
let didDispatchInvalid = false;
invalidControl.addEventListener('invalid', e => { didDispatchInvalid = true; });
let didDispatchSubmit = false;
form.addEventListener('submit', event => { event.preventDefault(); didDispatchSubmit = true; });
form.requestSubmit();
assert_true(didDispatchInvalid);
assert_false(didDispatchSubmit);
}, "Check form not submitted for invalid select");
</script>

View file

@ -0,0 +1,26 @@
<!DOCTYPE html>
<link rel=author href="mailto:jarhar@chromium.org">
<link rel=help href="https://github.com/openui/open-ui/issues/664">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<select id=select>
<option id=optone>innertext one</option>
<option id=opttwo value=valueattribute>innertext two</option>
</select>
<style>
select, ::picker(select) {
appearance: base-select;
}
</style>
<script>
test(() => {
assert_equals(select.value, 'innertext one',
'The first option should be selected initially.');
select.value = 'valueattribute';
assert_equals(select.value, 'valueattribute',
'Assigning value should look at the options value, not innertext');
}, 'select.value should reflect option.value');
</script>

View file

@ -0,0 +1,230 @@
<!DOCTYPE html>
<title>HTMLselectElement Test: value and selectedOption</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<select id="select0"></select>
<select id="select1">
<option>one</option>
<option>two</option>
<div>I'm a div with no part attr</div>
<option id="select1-option3">three</option>
<option>four</option>
</select>
<select id="select2">
<div behavior="option">one</div>
<div behavior="option">two</div>
<div>I'm a div with no part attr</div>
<div behavior="option">three</div>
<div behavior="option">four</div>
</select>
<select id="select3">
<div>I'm a div with no part attr</div>
<option id="select3-child1">one</option>
<option id="select3-child2">two</option>
<option id="select3-child3">three</option>
</select>
<select id="select4">
<button>
<selectedoption id="select4-custom-selected-value">Default custom selected-value text</selectedoption>
</button>
<option id="select4-option1">one</option>
<option id="select4-option2">two</option>
</select>
<select id="select5">
<button>
<selectedoption id="select5-custom-selected-value">Default custom selected-value text</selectedoption>
</button>
<div>
<option id="select5-option1">one</option>
<option id="select5-option2">two</option>
</div>
</select>
<select id="select6">
<option id="select6-option1">one</option>
<option id="select6-option2" selected>two</option>
<option id="select6-option3">three</option>
</select>
<select id="select7">
<option id="select7-option1">one</option>
<option id="select7-option2" selected value="test">two</option>
<option>three</option>
</select>
<style>
select, ::picker(select) {
appearance: base-select;
}
</style>
<script>
test(() => {
const select0 = document.getElementById("select0");
assert_equals(select0.value, "");
assert_equals(select0.selectedOption, null);
select0.value = "something";
assert_equals(select0.value, "", "If there is no matching option, select should be cleared");
assert_equals(select0.selectedOption, null);
}, "Test that HTMLselect with no options has empty string for value and null for selectedOption");
test(() => {
const select1 = document.getElementById("select1");
assert_equals(select1.value, "one", "value should start with the text of the first option part");
select1.value = "three";
assert_equals(select1.value, "three", "value can be set to the text of an option part");
assert_equals(select1.selectedOption, document.getElementById("select1-option3"));
select1.value = "I'm a div with no part attr";
assert_equals(select1.value, "", "If there is no matching option select should be cleared");
assert_equals(select1.selectedOption, null);
}, "Test value and selectedOption with HTMLOptionElement element option parts");
test(() => {
const select1 = document.getElementById("select1");
select1.value = "one";
assert_equals(select1.value, "one");
select1.value = null;
assert_equals(select1.value, "");
assert_equals(select1.selectedOption, null);
}, "Test value and selectedOption when value is null");
test(() => {
const select1 = document.getElementById("select1");
select1.value = "one";
assert_equals(select1.value, "one");
select1.value = undefined;
assert_equals(select1.value, "");
assert_equals(select1.selectedOption, null);
}, "Test value and selectedOption when value is undefined");
test(() => {
const select2 = document.getElementById("select2");
assert_equals(select2.value, "", "Non-HTMLOptionElements shouldn't be treated as option parts");
assert_equals(select2.selectedOption, null);
select2.value = "three";
assert_equals(select2.value, "", "value can't be set when there are no option parts'");
assert_equals(select2.selectedOption, null);
}, "Test value with non-HTMLOptionElement elements labeled as parts");
test(() => {
const select3 = document.getElementById("select3");
assert_equals(select3.value, "one", "value should start with the text of the first option part");
assert_equals(select3.selectedOption, document.getElementById("select3-child1"));
document.getElementById("select3-child3").remove();
assert_equals(select3.value, "one", "Removing a non-selected option should not change the value");
assert_equals(select3.selectedOption, document.getElementById("select3-child1"));
document.getElementById("select3-child1").remove();
assert_equals(select3.value, "two", "When the selected option is removed, the new first option should become selected");
assert_equals(select3.selectedOption, document.getElementById("select3-child2"));
document.getElementById("select3-child2").remove();
assert_equals(select3.value, "", "When all options are removed, value should be the empty string");
assert_equals(select3.selectedOption, null);
}, "Test that value and selectedOption are updated when options are removed");
test(() => {
const select4 = document.getElementById("select4");
let customSelectedValuePart = document.getElementById("select4-custom-selected-value");
assert_equals(select4.value, "one", "value should start with the text of the first option part");
assert_equals(select4.selectedOption, document.getElementById("select4-option1"));
assert_equals(customSelectedValuePart.innerText, "one", "Custom selected value part should be set to initial value of select");
select4.value = "two";
assert_equals(customSelectedValuePart.innerText, "two", "Custom selected value part should be updated when value of select changes");
assert_equals(select4.selectedOption, document.getElementById("select4-option2"));
}, "Test that slotted-in selected-value part is updated to value of select");
test(() => {
const select5 = document.getElementById("select5");
let customSelectedValuePart = document.getElementById("select5-custom-selected-value");
assert_equals(select5.value, "one", "value should start with the text of the first option part");
assert_equals(select5.selectedOption, document.getElementById("select5-option1"));
assert_equals(customSelectedValuePart.innerText, "one", "Custom selected value part should be set to initial value of select");
select5.value = "two";
assert_equals(customSelectedValuePart.innerText, "two", "Custom selected value part should be updated when value of select changes");
assert_equals(select5.selectedOption, document.getElementById("select5-option2"));
}, "Test that option parts in a slotted-in listbox are reflected in the value property");
test(() => {
let select = document.createElement('select');
assert_equals(select.value, "");
let option = document.createElement('option');
option.innerText = "one";
select.appendChild(option);
assert_equals(select.value, "one");
assert_equals(select.selectedOption, option);
let newOption = document.createElement('option');
newOption.innerText = 'two';
select.appendChild(newOption);
select.value = "two";
assert_equals(select.value, "two");
assert_equals(select.selectedOption, newOption);
option.click();
assert_equals(select.value, "one");
assert_equals(select.selectedOption, option);
}, "Test that value and selectedOption are correctly updated");
test(() => {
const select = document.getElementById("select6");
let selectOption1 = document.getElementById("select6-option1");
assert_equals(select.value, "two");
assert_equals(select.selectedOption, document.getElementById("select6-option2"));
assert_false(selectOption1.selected);
selectOption1.selected = true;
assert_equals(select.value, "one");
assert_equals(select.selectedOption, selectOption1);
let newOption = document.createElement("option");
newOption.innerText = "four";
newOption.selected = true;
select.appendChild(newOption);
assert_equals(select.value, "four");
assert_equals(select.selectedOption, newOption);
assert_false(selectOption1.selected);
select.value = "three";
assert_equals(select.selectedOption, document.getElementById("select6-option3"));
assert_false(newOption.selected);
}, "Test that HTMLOption.selected updates select.value and select.selectedOption");
test(() => {
const select = document.getElementById("select7");
let selectOption1 = document.getElementById("select7-option1");
assert_equals(select.value, "test");
assert_equals(select.selectedOption, document.getElementById("select7-option2"));
assert_false(selectOption1.selected);
selectOption1.selected = true;
assert_equals(select.value, "one");
assert_equals(select.selectedOption, selectOption1);
selectOption1.value = "new test";
assert_equals(select.value, "new test");
assert_equals(select.selectedOption, selectOption1);
selectOption1.removeAttribute("value");
assert_equals(select.value, "one");
assert_equals(select.selectedOption, selectOption1);
selectOption1.value = "";
assert_equals(select.value, "");
assert_equals(select.selectedOption, selectOption1);
}, "Test that HTMLOption.value updates select.value");
</script>

View file

@ -0,0 +1,56 @@
<!doctype html>
<meta charset="utf-8">
<title>HTMLSelectElement.value</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/forms.html#dom-select-value">
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<div id=log></div>
<select id=sel1>
<option value=0></option>
<option selected value=1></option>
</select>
<select id=sel2>
<optgroup>
<option value=0></option>
</optgroup>
<optgroup></optgroup>
<optgroup>
<option></option>
<option value=1></option>
<option selected value=2></option>
</optgroup>
</select>
<select id=sel3>
<option selected value=1></option>
</select>
<select id=sel4></select>
<script>
test(function() {
var select = document.getElementById('sel1');
assert_equals(select.value, '1');
}, 'options');
test(function() {
var select = document.getElementById('sel2');
assert_equals(select.value, '2');
}, 'optgroups');
test(function() {
var select = document.getElementById('sel3');
var option = select.options[0];
var div = document.createElement('div');
select.appendChild(div);
div.appendChild(option);
assert_equals(select.value, '');
}, 'option is child of div');
test(function() {
var select = document.getElementById('sel4');
assert_equals(select.value, '');
}, 'no options');
</script>

View file

@ -0,0 +1,24 @@
<!DOCTYPE HTML>
<meta charset="utf-8">
<title>Select element with "readonly" attribute shouldn't be barred from constraint validation</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<select id="singleSelect" readonly>
<option>1
<option>2
</select>
<select id="multiSelect" readonly multiple>
<option>a
<option>b
<option>c
<option>d
</select>
<script>
test(() => {
assert_true(singleSelect.willValidate);
assert_true(multiSelect.willValidate);
});
</script>

View file

@ -0,0 +1,143 @@
<!doctype html>
<meta charset=utf-8>
<title>HTMLSelectElement selectedIndex</title>
<script src="../../../../resources/testharness.js"></script>
<script src="../../../../resources/testharnessreport.js"></script>
<div id=log></div>
<form id=form>
<select id=empty></select>
<select id=default>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
</select>
<select id=disabled>
<option disabled></option>
<option></option>
</select>
<select id=selected>
<option></option>
<option selected></option>
</select>
<select id=display-none>
<option style="display:none"></option>
<option></option>
</select>
<select id=minus-one>
<option value=1>1</option>
<option value=2>2</option>
</select>
</form>
<script>
function assertSelectedIndex(select, value) {
assert_equals(select.selectedIndex, value);
assert_equals(select.options.selectedIndex, value);
}
function assertSelectValue(select, value) {
assert_equals(select.value, value);
}
test(function () {
var select = document.getElementById('empty');
assertSelectedIndex(select, -1);
}, "get empty");
test(function () {
var select = document.getElementById('default');
assertSelectedIndex(select, 0);
}, "get default");
test(function () {
var select = document.getElementById('disabled');
assertSelectedIndex(select, 1);
}, "get disabled");
test(function () {
var select = document.getElementById('selected');
assertSelectedIndex(select, 1);
}, "get unselected");
test(function () {
var select = document.getElementById('empty');
select.selectedIndex = 1;
assertSelectedIndex(select, -1);
}, "set empty (HTMLSelectElement)");
test(function () {
var select = document.getElementById('empty');
select.options.selectedIndex = 1;
assertSelectedIndex(select, -1);
}, "set empty (HTMLOptionsCollection)");
test(function () {
var select = document.getElementById('default');
assertSelectedIndex(select, 0);
select.selectedIndex = 2;
assertSelectedIndex(select, 2);
this.add_cleanup(() => { select.selectedIndex = 0; });
}, "set (HTMLSelectElement)");
test(function () {
var select = document.getElementById('default');
assertSelectedIndex(select, 0);
select.options.selectedIndex = 2;
assertSelectedIndex(select, 2);
this.add_cleanup(() => { select.selectedIndex = 0; });
}, "set (HTMLOptionsCollection)");
test(function () {
var select = document.getElementById('selected');
var form = document.getElementById('form');
assertSelectedIndex(select, 1);
select.selectedIndex = 0;
assertSelectedIndex(select, 0);
form.reset();
assertSelectedIndex(select, 1);
}, "set and reset (HTMLSelectElement)");
test(function () {
var select = document.getElementById('selected');
var form = document.getElementById('form');
assertSelectedIndex(select, 1);
select.options.selectedIndex = 0;
assertSelectedIndex(select, 0);
form.reset();
assertSelectedIndex(select, 1);
}, "set and reset (HTMLOptionsCollection)");
test(function () {
var select = document.getElementById('display-none');
assertSelectedIndex(select, 0);
}, "get display:none");
test(function () {
var select = document.getElementById('display-none');
select.offsetTop; // force rendering
assertSelectedIndex(select, 0);
select.options[1].selected = true;
assertSelectedIndex(select, 1);
select.options[1].selected = false;
assertSelectedIndex(select, 0);
}, "reset to display:none");
test(function() {
var select = document.getElementById("minus-one");
assertSelectedIndex(select, 0);
select.selectedIndex = -1;
assertSelectedIndex(select, -1);
assertSelectValue(select, "");
}, "set selectedIndex=-1");
</script>