diff options
Diffstat (limited to 'testing/web-platform/tests/html/semantics/forms/the-select-element')
32 files changed, 1642 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-add.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-add.html new file mode 100644 index 0000000000..cf4306e271 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-add.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html new file mode 100644 index 0000000000..c5c8510a47 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection-namedItem.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html new file mode 100644 index 0000000000..737e9be876 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/common-HTMLOptionsCollection.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/inserted-or-removed.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/inserted-or-removed.html new file mode 100644 index 0000000000..0db2bf0e77 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/inserted-or-removed.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/reset-algorithm-rendering-ref.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/reset-algorithm-rendering-ref.html new file mode 100644 index 0000000000..acf192d1d5 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/reset-algorithm-rendering-ref.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<body> + +<form> +<select> +<option>Default</option> +<option>Another</option> +</select> + +<select> +<option>Another</option> +<option selected>Default</option> +</select> + +<select multiple> +<option>option 1</option> +<option>option 2</option> +</select> +</form> + +</body> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/reset-algorithm-rendering.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/reset-algorithm-rendering.html new file mode 100644 index 0000000000..67da173ff2 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/reset-algorithm-rendering.html @@ -0,0 +1,39 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<title>Invalidation test on resetting <select></title> +<link rel="help" href="https://html.spec.whatwg.org/C/#the-select-element:concept-form-reset-control"> +<link rel="help" href="http://crbug.com/1087031"> +<link rel="match" href="reset-algorithm-rendering-ref.html"> +<body> + +<form> +<select> +<option>Default</option> +<option>Another</option> +</select> + +<select> +<option>Another</option> +<option selected>Default</option> +</select> + +<select multiple> +<option>option 1</option> +<option>option 2</option> +</select> +</form> + +<script> +const selects = document.querySelectorAll('select'); +selects[0].selectedIndex = 1; +selects[1].selectedIndex = 0; +selects[2].options[1].selected = true; + +document.documentElement.addEventListener('TestRendered', e => { + document.querySelector('form').reset(); + e.target.removeAttribute('class'); +}); +</script> + +</body> +</html> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/resources/show-picker-child-iframe.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/resources/show-picker-child-iframe.html new file mode 100644 index 0000000000..bba3989824 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/resources/show-picker-child-iframe.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<title>Test showPicker() in an iframe</title> +<script type=module> + const urlParams = new URLSearchParams(location.search); + const documentDomain = urlParams.get('documentDomain'); + if (documentDomain) { + document.domain = documentDomain; + } + + let securityErrors = []; + const select = document.createElement("select"); + try { + select.showPicker(); + } catch (error) { + if (error instanceof DOMException && error.name == 'SecurityError') { + securityErrors.push("select"); + } + } + parent.postMessage(securityErrors.join(','), "*"); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/resources/stylable-select-styles.css b/testing/web-platform/tests/html/semantics/forms/the-select-element/resources/stylable-select-styles.css new file mode 100644 index 0000000000..a7e9a87cdf --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/resources/stylable-select-styles.css @@ -0,0 +1,18 @@ +.stylable-select-datalist { + box-shadow: 0px 12.8px 28.8px rgba(0, 0, 0, 0.13), 0px 0px 9.2px rgba(0, 0, 0, 0.11); + box-sizing: border-box; + overflow: auto; + border: 1px solid rgba(0, 0, 0, 0.15); + border-radius: 0.25em; + padding: 0.25em 0; + background-color: Field; + margin: 0; + inset: auto; + min-inline-size: anchor-size(self-inline); + min-block-size: 1lh; + inset-block-start: anchor(self-end); + inset-inline-start: anchor(self-start); + + font-family: Arial; + font-size: 13.3333px; +} diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-add-optgroup.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-add-optgroup.html new file mode 100644 index 0000000000..fab5332f26 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-add-optgroup.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-add-option-crash.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-add-option-crash.html new file mode 100644 index 0000000000..78e9e7de53 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-add-option-crash.html @@ -0,0 +1,13 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=1178128"> + +<script> +function iframeloadhandler() { + selectid[5] = optionid; +} +</script> +<option id="optionid" selected> + <select id="selectid"> + <select> + <iframe onload="iframeloadhandler()"> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-add.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-add.html new file mode 100644 index 0000000000..910be348ae --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-add.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-ask-for-reset.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-ask-for-reset.html new file mode 100644 index 0000000000..822114fb26 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-ask-for-reset.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist-ref.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist-ref.html new file mode 100644 index 0000000000..46bbd0ccd0 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist-ref.html @@ -0,0 +1,12 @@ +<!DOCTYPE html> +<link rel=stylesheet href="resources/stylable-select-styles.css"> + +<button popovertarget=popover id=button>button</button> +<div id=popover popover=auto anchor=button class=stylable-select-datalist> + <option>one</option> + <option>two</option> +</div> + +<script> +document.getElementById('popover').showPopover(); +</script> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist.tentative.html new file mode 100644 index 0000000000..b74957feed --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-child-button-and-datalist.tentative.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/whatwg/html/issues/9799"> +<link rel=match href="select-child-button-and-datalist-ref.html"> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> + +<select> + <button type=popover>button</button> + <datalist> + <option>one</option> + <option>two</option> + </datalist> +</select> + +<script> +document.querySelector('button').click(); +</script> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-in-table-crash.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-in-table-crash.html new file mode 100644 index 0000000000..d1f1cee217 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-in-table-crash.html @@ -0,0 +1,4 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=1519397"> +<table><select>A0A0AA<<datalist><title></title><table><table><td> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-multiple.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-multiple.html new file mode 100644 index 0000000000..e348064151 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-multiple.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-named-getter.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-named-getter.html new file mode 100644 index 0000000000..da43da9d92 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-named-getter.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-parsing.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-parsing.tentative.html new file mode 100644 index 0000000000..31133446d4 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-parsing.tentative.html @@ -0,0 +1,112 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://github.com/whatwg/html/issues/9799"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<body> + +<select id=s1> + <div>div 1</div> + <button>button</button> + <div>div 2</div> + <datalist> + <option>option</option> + </datalist> + <div>div 3</div> +</select> + +<select id=s2> + <button>button +</select> + +<select id=s3> + <datalist>datalist +</select> + +<select id=s4> + <button> + <select></select> + </button> +</select> + +<select id=s5> + <button> + <div> + <select> +</select> + +<select id=s6> +<button> +<button></button> +</button> +<datalist> +<datalist></datalist> +</datalist> +</select> + +<div id=afterlast> + keep this div after the last test case +</div> + +<script> +test(() => { + // The document.body check here and in the other tests is to make sure that a + // previous test case didn't leave the HTML parser open on another element. + assert_equals(document.getElementById('s1').parentNode, document.body); + assert_equals(document.getElementById('s1').innerHTML, ` + div 1 + <button>button</button> + div 2 + <datalist> + <option>option</option> + </datalist> + div 3 +`); +}, '<button>s and <datalist>s should be allowed in <select>.'); + +test(() => { + assert_equals(document.getElementById('s2').parentNode, document.body); + assert_equals(document.getElementById('s2').innerHTML, ` + <button>button +</button>`); +}, '</select> should close <button>.'); + +test(() => { + assert_equals(document.getElementById('s3').parentNode, document.body); + assert_equals(document.getElementById('s3').innerHTML, ` + <datalist>datalist +</datalist>`); +}, '</select> should close <datalist>.'); + +test(() => { + assert_equals(document.getElementById('s4').parentNode, document.body); + assert_equals(document.getElementById('s4').innerHTML, ` + <button> + </button>`); +}, '<select> in <button> in <select> should remove inner <select>.'); + +test(() => { + assert_equals(document.getElementById('s5').parentNode, document.body); + assert_equals(document.getElementById('s5').innerHTML, ` + <button> + <div> + </div></button>`); +}, '<select> in <select><button><div> should remove inner <select>.'); + +test(() => { + assert_equals(document.getElementById('s6').parentNode, document.body); + assert_equals(document.getElementById('s6').innerHTML, ` +<button> +</button> + +<datalist> +</datalist> + +`); +}, 'Nested <button>s or <datalist>s in <select> should be dropped.'); + +test(() => { + assert_equals(document.getElementById('afterlast').parentNode, document.body); +}, 'The last test should not leave any tags open after parsing.'); +</script> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-remove.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-remove.html new file mode 100644 index 0000000000..cf2128bd15 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-remove.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-selectedOptions.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-selectedOptions.html new file mode 100644 index 0000000000..bd5984a6b2 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-selectedOptions.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-setcustomvalidity.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-setcustomvalidity.html new file mode 100644 index 0000000000..15308c1a8f --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-setcustomvalidity.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-validity.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-validity.html new file mode 100644 index 0000000000..9f044879d9 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-validity.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-value.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-value.html new file mode 100644 index 0000000000..d8d5263e3e --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-value.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/select-willvalidate-readonly-attribute.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-willvalidate-readonly-attribute.html new file mode 100644 index 0000000000..d3f4ce43cf --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/select-willvalidate-readonly-attribute.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/selected-index.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/selected-index.html new file mode 100644 index 0000000000..7f7fd9a1a2 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/selected-index.html @@ -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> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-being-cv-hidden.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-being-cv-hidden.html new file mode 100644 index 0000000000..8990734f93 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-being-cv-hidden.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<title>Test showPicker() being rendered requirement with content-visibility</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<div style="content-visibility: hidden"> + <select id="select"> + <option>Item 1</option> + </select> +</div> +<script> +promise_test(async t => { + await test_driver.bless('show picker'); + assert_throws_dom('NotSupportedError', () => { select.showPicker(); }); + + // Test that dynamically changing to actually being rendered works. + await test_driver.bless('show picker'); + select.parentElement.style.contentVisibility = 'visible'; + select.showPicker(); + select.blur(); +}, 'select showPicker() throws when content-visibility hidden'); +</script> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-being-rendered.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-being-rendered.html new file mode 100644 index 0000000000..e7be4aea52 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-being-rendered.html @@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title>Test showPicker() being rendered requirement</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<select id="select" style="display: none;"> + <option>Item 1</option> +</select> +<script> +promise_test(async t => { + await test_driver.bless('show picker'); + assert_throws_dom('NotSupportedError', () => { select.showPicker(); }); + + // Test that dynamically changing to actually being rendered works. + await test_driver.bless('show picker'); + select.style.display = 'inline-block'; + select.showPicker(); + select.blur(); +}, 'select showPicker() throws when not being rendered'); +</script> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-cross-origin-iframe.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-cross-origin-iframe.tentative.html new file mode 100644 index 0000000000..3f710b39c6 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-cross-origin-iframe.tentative.html @@ -0,0 +1,79 @@ +<!DOCTYPE html> +<title>Test showPicker() called from cross-origin iframe</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<body> +<iframe id="iframe1"></iframe> +<iframe id="iframe2"></iframe> +<iframe id="iframe3"></iframe> +<iframe id="iframe4"></iframe> +</body> +<script> + function waitForSecurityErrors() { + return new Promise((resolve) => { + window.addEventListener("message", (event) => resolve(event.data), { + once: true, + }); + }); + } + + promise_test(async (t) => { + iframe1.src = + new URL("resources/", self.location).pathname + + "show-picker-child-iframe.html"; + + // Wait for the iframe to report security errors when calling showPicker(). + const securityErrors = await waitForSecurityErrors(); + assert_equals( + securityErrors, + "", + "In same-origin iframes, showPicker() does not throw a SecurityError." + ); + }); + + promise_test(async (t) => { + iframe2.src = + get_host_info().HTTP_NOTSAMESITE_ORIGIN + + new URL("resources/", self.location).pathname + + "show-picker-child-iframe.html"; + + // Wait for the iframe to report security errors when calling showPicker(). + const securityErrors = await waitForSecurityErrors(); + assert_equals( + securityErrors, + "select", + "In cross-origin iframes, showPicker() throws a SecurityError." + ); + }); + + promise_test(async (t) => { + iframe3.src = + new URL("resources/", self.location).pathname + + "show-picker-child-iframe.html?documentDomain=" + get_host_info().ORIGINAL_HOST; + + // Wait for the iframe to report security errors when calling showPicker(). + const securityErrors = await waitForSecurityErrors(); + assert_equals( + securityErrors, + "", + "In same-origin but cross-origin-domain iframes, showPicker() does not throw a SecurityError." + ); + }); + + promise_test(async (t) => { + document.domain = get_host_info().ORIGINAL_HOST; + iframe4.src = + get_host_info().HTTP_REMOTE_ORIGIN + + new URL("resources/", self.location).pathname + + "show-picker-child-iframe.html?documentDomain=" + get_host_info().ORIGINAL_HOST; + + // Wait for the iframe to report security errors when calling showPicker(). + const securityErrors = await waitForSecurityErrors(); + assert_equals( + securityErrors, + "select", + "In cross-origin but same-origin-domain iframes, showPicker() throws a SecurityError." + ); + }); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-disabled.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-disabled.tentative.html new file mode 100644 index 0000000000..f20bc2cf61 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-disabled.tentative.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<title>Test showPicker() disabled requirement</title> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<select id="select" disabled> + <option>Item 1</option> +</select> +<script> + test(() => { + assert_throws_dom('InvalidStateError', () => { select.showPicker(); }); + }, 'select showPicker() throws when disabled'); +</script>
\ No newline at end of file diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-multiple.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-multiple.tentative.html new file mode 100644 index 0000000000..c38e98ee4e --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-multiple.tentative.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>Test showPicker() on multiple selects</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<select id="select" multiple> + <option>Item 1</option> +</select> +<script> +promise_test(async t => { + await test_driver.bless('show picker'); + select.showPicker(); + select.blur(); +}, `select showPicker() does not throw when called on a <select multiple>`); +</script> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-size.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-size.tentative.html new file mode 100644 index 0000000000..b9b10c42a9 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-size.tentative.html @@ -0,0 +1,17 @@ +<!DOCTYPE html> +<title>Test showPicker() on sized selects</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<select id="select" size="4"> + <option>Item 1</option> +</select> +<script> +promise_test(async t => { + await test_driver.bless('show picker'); + select.showPicker(); + select.blur(); +}, `select showPicker() does not throw when called on a <select size="4">`); +</script> diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-user-gesture.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-user-gesture.tentative.html new file mode 100644 index 0000000000..e917fe2a61 --- /dev/null +++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/show-picker-user-gesture.tentative.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<title>Test showPicker() user gesture requirement</title> +<meta name="timeout" content="long"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/testdriver.js"></script> +<script src="/resources/testdriver-vendor.js"></script> +<body></body> +<script type=module> + test(() => { + const select = document.createElement("select"); + + assert_throws_dom('NotAllowedError', () => { select.showPicker(); }); + }, `select showPicker() requires a user gesture`); + + promise_test(async t => { + const select = document.createElement("select"); + document.body.append(select) + + await test_driver.bless('show picker'); + select.showPicker(); + select.blur(); + }, `select showPicker() does not throw when user activation is active`); +</script>
\ No newline at end of file |