summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select')
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/resources/select-reset-non-interoperable-styles.css5
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/resources/stylable-select-styles.css37
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-custom-button-no-datalist.tentative.html22
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-custom-datalist-ref.html14
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-custom-datalist.tentative.html23
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-no-datalist.tentative.html21
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist-invalidation.tentative.html32
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist-ref.html25
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist.tentative.html27
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-datalist-options-idl.tentative.html84
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-keyboard-behavior.tentative.html208
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-mouse-behavior.tentative.html62
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-parsing.tentative.html112
-rw-r--r--testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/selectedoption.tentative.html82
14 files changed, 754 insertions, 0 deletions
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/resources/select-reset-non-interoperable-styles.css b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/resources/select-reset-non-interoperable-styles.css
new file mode 100644
index 0000000000..d2b9d9df26
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/resources/select-reset-non-interoperable-styles.css
@@ -0,0 +1,5 @@
+/* TODO(crbug.com/1511354): linux.css sets background-color on select, consider
+ * removing it. */
+select {
+ background-color: Field;
+}
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/resources/stylable-select-styles.css b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/resources/stylable-select-styles.css
new file mode 100644
index 0000000000..042de838d1
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/resources/stylable-select-styles.css
@@ -0,0 +1,37 @@
+/* These are UA styles for select and stylable select. */
+
+.stylable-select-container {
+ background-color: Field;
+ border: 1px solid rgba(0, 0, 0, 0);
+ border-radius: 0;
+ box-sizing: border-box;
+ display: inline-block;
+}
+
+.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;
+}
+
+/* These are the UA styles for <option> in chromium.
+ * They will either have to be specced or also added to the main test file.
+ * TODO(crbug.com/1511354): Spec these UA styles. */
+.stylable-select-option {
+ min-height: 1.2em;
+ padding: 0px 2px 1px;
+ white-space: nowrap;
+}
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-custom-button-no-datalist.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-custom-button-no-datalist.tentative.html
new file mode 100644
index 0000000000..94d7fd53b3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-custom-button-no-datalist.tentative.html
@@ -0,0 +1,22 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://github.com/whatwg/html/issues/9799">
+<link rel=match href="select-appearance-no-button-custom-datalist-ref.html">
+<link rel=stylesheet href="resources/select-reset-non-interoperable-styles.css">
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<select style="appearance:base-select">
+ <button type=popover>one</button>
+ <option>one</option>
+ <option>two</option>
+</select>
+
+<script>
+(async () => {
+ await test_driver.bless();
+ document.querySelector('select').showPicker();
+ document.documentElement.classList.remove('reftest-wait');
+})();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-custom-datalist-ref.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-custom-datalist-ref.html
new file mode 100644
index 0000000000..8e5eadaf57
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-custom-datalist-ref.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<link rel=stylesheet href="resources/stylable-select-styles.css">
+
+<div id=container class=stylable-select-container>
+ <button popovertarget=popover id=button>one</button>
+ <div id=popover popover=auto anchor=container class=stylable-select-datalist>
+ <div class=stylable-select-option>one</div>
+ <div class=stylable-select-option>two</div>
+ </div>
+</div>
+
+<script>
+document.getElementById('popover').showPopover();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-custom-datalist.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-custom-datalist.tentative.html
new file mode 100644
index 0000000000..87425cf7a3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-custom-datalist.tentative.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://github.com/whatwg/html/issues/9799">
+<link rel=match href="select-appearance-no-button-custom-datalist-ref.html">
+<link rel=stylesheet href="resources/select-reset-non-interoperable-styles.css">
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<select style="appearance:base-select">
+ <datalist>
+ <option>one</option>
+ <option>two</option>
+ </datalist>
+</select>
+
+<script>
+(async () => {
+ await test_driver.bless();
+ document.querySelector('select').showPicker();
+ document.documentElement.classList.remove('reftest-wait');
+})();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-no-datalist.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-no-datalist.tentative.html
new file mode 100644
index 0000000000..b2a6b5a6d3
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-appearance-no-button-no-datalist.tentative.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://github.com/whatwg/html/issues/9799">
+<link rel=match href="select-appearance-no-button-custom-datalist-ref.html">
+<link rel=stylesheet href="resources/select-reset-non-interoperable-styles.css">
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<select style="appearance:base-select">
+ <option>one</option>
+ <option>two</option>
+</select>
+
+<script>
+(async () => {
+ await test_driver.bless();
+ document.querySelector('select').showPicker();
+ document.documentElement.classList.remove('reftest-wait');
+})();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist-invalidation.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist-invalidation.tentative.html
new file mode 100644
index 0000000000..b6d85ac90a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist-invalidation.tentative.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html class=reftest-wait>
+<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">
+<link rel=stylesheet href="resources/select-reset-non-interoperable-styles.css">
+
+<style>
+.blue {
+ color: blue;
+}
+</style>
+
+<select>
+ <button type=popover>button</button>
+ <datalist>
+ <option>
+ <span class=blue>option</span> one
+ </option>
+ <option>
+ <span class=blue>option</span> two
+ </option>
+ </datalist>
+</select>
+
+<script>
+requestAnimationFrame(() => {
+ document.querySelector('select').style = 'appearance:base-select';
+ document.querySelector('button').click();
+ document.documentElement.classList.remove('reftest-wait');
+});
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist-ref.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist-ref.html
new file mode 100644
index 0000000000..e99ca4d57a
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist-ref.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+<link rel=stylesheet href="resources/stylable-select-styles.css">
+
+<style>
+.blue {
+ color: blue;
+}
+</style>
+
+<div id=container class=stylable-select-container>
+ <button popovertarget=popover id=button>button</button>
+ <div id=popover popover=auto anchor=container class=stylable-select-datalist>
+ <div tabindex=0 class=stylable-select-option>
+ <span class=blue>option</span> one
+ </div>
+ <div tabindex=0 class=stylable-select-option>
+ <span class=blue>option</span> two
+ </div>
+ </div>
+</div>
+
+<script>
+document.getElementById('popover').showPopover();
+document.querySelector('div.stylable-select-option').focus();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist.tentative.html
new file mode 100644
index 0000000000..610861aad8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-child-button-and-datalist.tentative.html
@@ -0,0 +1,27 @@
+<!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">
+<link rel=stylesheet href="resources/select-reset-non-interoperable-styles.css">
+
+<style>
+.blue {
+ color: blue;
+}
+</style>
+
+<select style="appearance:base-select">
+ <button type=popover>button</button>
+ <datalist>
+ <option>
+ <span class=blue>option</span> one
+ </option>
+ <option>
+ <span class=blue>option</span> two
+ </option>
+ </datalist>
+</select>
+
+<script>
+document.querySelector('button').click();
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-datalist-options-idl.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-datalist-options-idl.tentative.html
new file mode 100644
index 0000000000..92eabdc5d8
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-datalist-options-idl.tentative.html
@@ -0,0 +1,84 @@
+<!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>
+
+<select>
+ <datalist>
+ <option class=one>one</option>
+ <div>
+ <option class=two>two</option>
+ </div>
+ <option class=three>three</option>
+ </datalist>
+ <datalist>
+ <option>ignored since not in first datalist</option>
+ </datalist>
+</select>
+
+<script>
+const select = document.querySelector('select');
+
+function runTest() {
+ const datalist = select.querySelector('datalist');
+ const firstOption = select.querySelector('option.one');
+ const secondOption = select.querySelector('option.two');
+ const thirdOption = select.querySelector('option.three');
+ const datalistChildDiv = datalist.querySelector('div');
+
+ let selectChildDiv = document.querySelector('select > div');
+ if (!selectChildDiv) {
+ selectChildDiv = document.createElement('div');
+ select.appendChild(selectChildDiv);
+ }
+
+ assert_equals(select.length, 3, 'select.length');
+ assert_equals(select.options.length, 3, 'select.options.length');
+ assert_equals(select.options[0], firstOption, 'select.options[0]');
+ assert_equals(select.options[1], secondOption, 'select.options[1]');
+ assert_equals(select.options[2], thirdOption, 'select.options[2]');
+
+ assert_equals(select.value, 'one', 'initial select.value');
+ select.value = 'two';
+ assert_equals(select.value, 'two', 'select.value after modifying');
+
+ secondOption.remove();
+ assert_equals(select.length, 2, 'select.length after removing an option');
+ assert_equals(select.options.length, 2, 'select.options.length after removing an option');
+ assert_equals(select.options[0], firstOption, 'select.options[0] after removing an option');
+ assert_equals(select.options[1], thirdOption, 'select.options[1] after removing an option');
+
+ datalist.appendChild(secondOption);
+ assert_equals(select.length, 3, 'select.length after re-adding an option');
+ assert_equals(select.options.length, 3, 'select.options.length after re-adding an option');
+ assert_equals(select.options[0], firstOption, 'select.options[0] after re-adding an option');
+ assert_equals(select.options[1], thirdOption, 'select.options[1] after re-adding an option');
+ assert_equals(select.options[2], secondOption, 'select.options[2] after re-adding an option');
+
+ selectChildDiv.appendChild(secondOption);
+ assert_equals(select.length, 2, 'select.length after moving option to child div');
+ assert_equals(select.options.length, 2, 'select.options.length after moving option to child div');
+ assert_equals(select.options[0], firstOption, 'select.options[0] after moving option to child div');
+ assert_equals(select.options[1], thirdOption, 'select.options[1] after moving option to child div');
+
+ // reset back to normal for the next test
+ datalistChildDiv.appendChild(secondOption);
+ select.value = 'one';
+}
+
+test(() => {
+ runTest();
+}, 'Option elements should work if they are a descendant of a selects datalist.');
+
+test(() => {
+ select.setAttribute('multiple', '');
+ runTest();
+}, 'Options in datalist should still work when the multiple attribute is added.');
+
+test(() => {
+ select.innerHTML = select.innerHTML;
+ select.value = 'one';
+ runTest();
+}, 'Options in datalist in multiple should work after re-parsing and re-attaching.');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-keyboard-behavior.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-keyboard-behavior.tentative.html
new file mode 100644
index 0000000000..2fb11ba68b
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-keyboard-behavior.tentative.html
@@ -0,0 +1,208 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=1422275">
+<link rel=help href="https://github.com/openui/open-ui/issues/433#issuecomment-1452461404">
+<link rel=help href="https://github.com/openui/open-ui/issues/386#issuecomment-1452469497">
+<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>
+<script src="/resources/testdriver-actions.js"></script>
+
+<style>
+select {
+ appearance: base-select;
+}
+</style>
+
+<form></form>
+
+<div id=notform>
+ <select id=defaultbutton-defaultdatalist>
+ <option class=one>one</option>
+ <option class=two>two</option>
+ <option class=three>three</option>
+ </select>
+
+ <select id=defaultbutton-customdatalist>
+ <datalist>
+ <option class=one>one</option>
+ <option class=two>two</option>
+ <option class=three>three</option>
+ </datalist>
+ </select>
+
+ <select id=custombutton-defaultdatalist>
+ <button type=popover>custom button</button>
+ <option class=one>one</option>
+ <option class=two>two</option>
+ <option class=three>three</option>
+ </select>
+
+ <select id=custombutton-customdatalist>
+ <button type=popover>custom button</button>
+ <datalist>
+ <option class=one>one</option>
+ <option class=two>two</option>
+ <option class=three>three</option>
+ </datalist>
+ </select>
+</div>
+
+<script>
+const Enter = '\uE007';
+const Escape = '\uE00C';
+const ArrowLeft = '\uE012';
+const ArrowUp = '\uE013';
+const ArrowRight = '\uE014';
+const ArrowDown = '\uE015';
+const Space = ' ';
+const form = document.querySelector('form');
+const notform = document.getElementById('notform');
+
+for (const id of ['defaultbutton-defaultdatalist',
+ 'defaultbutton-customdatalist',
+ 'custombutton-defaultdatalist',
+ 'custombutton-customdatalist']) {
+ const select = document.getElementById(id);
+
+ async function closeListbox() {
+ await test_driver.click(select);
+ }
+
+ function addCloseCleanup(t) {
+ t.add_cleanup(async () => {
+ if (select.matches(':open')) {
+ await closeListbox();
+ }
+ if (select.matches(':open')) {
+ throw new Error('select failed to close!');
+ }
+ select.value = 'one';
+ });
+ }
+
+ promise_test(async t => {
+ addCloseCleanup(t);
+ // TODO(http://crbug.com/1350299): When focus for custom buttons is fixed,
+ // then we shouldn't need to explicitly focus the custom button like this
+ // anymore.
+ const customButton = select.querySelector('button');
+ if (customButton) {
+ customButton.focus();
+ } else {
+ select.focus();
+ }
+ assert_false(select.matches(':open'),
+ 'The select should initially be closed.');
+ await test_driver.send_keys(document.activeElement, Space);
+ assert_true(select.matches(':open'),
+ 'The select should be open after pressing space.');
+ }, `${id}: When the listbox is closed, spacebar should open the listbox.`);
+
+ promise_test(async t => {
+ addCloseCleanup(t);
+ select.value = 'two';
+ select.focus();
+ assert_false(select.matches(':open'),
+ 'The select should initially be closed.');
+
+ await test_driver.send_keys(document.activeElement, ArrowLeft);
+ assert_true(select.matches(':open'),
+ 'Arrow left should open the listbox.');
+ assert_equals(select.value, 'two',
+ 'Arrow left should not change the selected value.');
+ await closeListbox();
+
+ await test_driver.send_keys(document.activeElement, ArrowUp);
+ assert_true(select.matches(':open'),
+ 'Arrow up should open the listbox.');
+ assert_equals(select.value, 'two',
+ 'Arrow up should not change the selected value.');
+ await closeListbox();
+
+ await test_driver.send_keys(document.activeElement, ArrowRight);
+ assert_true(select.matches(':open'),
+ 'Arrow right should open the listbox.');
+ assert_equals(select.value, 'two',
+ 'Arrow right should not change the selected value.');
+ await closeListbox();
+
+ await test_driver.send_keys(document.activeElement, ArrowDown);
+ assert_true(select.matches(':open'),
+ 'Arrow down should open the listbox.');
+ assert_equals(select.value, 'two',
+ 'Arrow down should not change the selected value.');
+ }, `${id}: When the listbox is closed, all arrow keys should open the listbox.`);
+
+ promise_test(async t => {
+ addCloseCleanup(t);
+
+ // TODO(http://crbug.com/1350299): When focus for custom buttons is fixed,
+ // then we shouldn't need to explicitly use the custom button like this
+ // anymore.
+ const customButton = select.querySelector('button');
+ if (customButton) {
+ await test_driver.send_keys(customButton, Enter);
+ } else {
+ await test_driver.send_keys(select, Enter);
+ }
+ assert_false(select.matches(':open'),
+ 'Enter should not open the listbox when outside a form.');
+
+ form.appendChild(select);
+ let formWasSubmitted = false;
+ form.addEventListener('submit', event => {
+ event.preventDefault();
+ formWasSubmitted = true;
+ }, {once: true});
+ if (customButton) {
+ await test_driver.send_keys(customButton, Enter);
+ } else {
+ await test_driver.send_keys(select, Enter);
+ }
+ assert_true(formWasSubmitted,
+ 'Enter should submit the form when the listbox is closed.');
+ assert_false(select.matches(':open'),
+ 'Enter should not open the listbox when it is in a form.');
+ }, `${id}: When the listbox is closed, the enter key should submit the form or do nothing.`);
+
+ promise_test(async t => {
+ addCloseCleanup(t);
+ const optionOne = select.querySelector('.one');
+ const optionTwo = select.querySelector('.two');
+ const optionThree = select.querySelector('.three');
+
+ select.value = 'two';
+ await test_driver.click(select);
+ assert_true(select.matches(':open'),
+ 'The select should open when clicked.');
+ assert_equals(document.activeElement, optionTwo,
+ 'The selected option should receive initial focus.');
+
+ await test_driver.send_keys(document.activeElement, ArrowDown);
+ assert_equals(document.activeElement, optionThree,
+ 'The next option should receive focus when the down arrow key is pressed.');
+ assert_equals(select.value, 'two',
+ 'The selects value should not change when focusing another option.');
+
+ await test_driver.send_keys(document.activeElement, ArrowUp);
+ assert_equals(document.activeElement, optionTwo,
+ 'The previous option should receive focus when the up arrow key is pressed.');
+ assert_equals(select.value, 'two',
+ 'The selects value should not change when focusing another option.');
+
+ await test_driver.send_keys(document.activeElement, ArrowUp);
+ assert_equals(document.activeElement, optionOne,
+ 'The first option should be selected.');
+ assert_equals(select.value, 'two',
+ 'The selects value should not change when focusing another option.');
+
+ await test_driver.send_keys(document.activeElement, Enter);
+ assert_false(select.matches(':open'),
+ 'The listbox should be closed after pressing enter.');
+ assert_equals(select.value, 'one',
+ 'The selects value should change after pressing enter on a different option.');
+ }, `${id}: When the listbox is open, the enter key should commit the selected option.`);
+}
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-mouse-behavior.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-mouse-behavior.tentative.html
new file mode 100644
index 0000000000..aff976d1ad
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-mouse-behavior.tentative.html
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<link rel=author href="mailto:jarhar@chromium.org">
+<link rel=help href="https://bugs.chromium.org/p/chromium/issues/detail?id=1422275">
+<link rel=help href="https://github.com/openui/open-ui/issues/433#issuecomment-1452461404">
+<link rel=help href="https://github.com/openui/open-ui/issues/386#issuecomment-1452469497">
+<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>
+<script src="/resources/testdriver-actions.js"></script>
+
+<style>
+select {
+ appearance: base-select;
+}
+</style>
+
+<!-- TODO(http://crbug.com/1511354): Add test cases with no <button> and no <datalist>. -->
+<select>
+ <button type=popover>button</button>
+ <datalist>
+ <option class=one>one</option>
+ <option class=two>two</option>
+ </datalist>
+</select>
+
+<script>
+const select = document.querySelector('select');
+const button = document.querySelector('button');
+const optionOne = document.querySelector('option.one');
+const optionTwo = document.querySelector('option.two');
+
+promise_test(async () => {
+ assert_false(select.matches(':open'),
+ 'Select should be closed at the start of the test.');
+
+ await test_driver.click(button);
+ assert_true(select.matches(':open'),
+ 'Select should be open after clicking the button.');
+
+ await test_driver.click(button);
+ assert_false(select.matches(':open'),
+ 'Select should be closed after clicking the button a second time.');
+}, 'Select with appearance:base-select should open and close when clicking the button.');
+
+promise_test(async () => {
+ assert_false(select.matches(':open'),
+ 'Select should be closed at the start of the test.');
+ assert_equals(select.value, 'one',
+ 'Select.value should be one at the start of the test.');
+
+ await test_driver.click(button);
+ assert_true(select.matches(':open'),
+ 'Select should be open after clicking the button.');
+
+ await test_driver.click(optionTwo);
+ assert_false(select.matches(':open'),
+ 'Select should be closed after clicking an option.');
+ assert_equals(select.value, 'two',
+ 'Select.value should be two after clicking the option.');
+}, 'Clicking an option in an appearance:base-select select should choose the option and close the popover.');
+</script>
diff --git a/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-parsing.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/select-parsing.tentative.html
new file mode 100644
index 0000000000..31133446d4
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/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/stylable-select/selectedoption.tentative.html b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/selectedoption.tentative.html
new file mode 100644
index 0000000000..16d711515c
--- /dev/null
+++ b/testing/web-platform/tests/html/semantics/forms/the-select-element/stylable-select/selectedoption.tentative.html
@@ -0,0 +1,82 @@
+<!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>
+<script src="/resources/testdriver.js"></script>
+<script src="/resources/testdriver-vendor.js"></script>
+
+<form>
+ <select style="appearance:base-select">
+ <button>
+ <selectedoption></selectedoption>
+ </button>
+ <datalist>
+ <option class=one value=one>
+ <span class=one>span</span> one
+ </option>
+ <option class=two value=two>
+ <span class=two>span</span> two
+ </option>
+ </datalist>
+ </select>
+</form>
+
+<script>
+promise_test(async () => {
+ const optionOne = document.querySelector('option.one');
+ const optionTwo = document.querySelector('option.two');
+ const selectedOption = document.querySelector('selectedoption');
+ const select = document.querySelector('select');
+ const spanTwo = document.querySelector('span.two');
+ const form = document.querySelector('form');
+ const button = document.querySelector('button');
+
+ assert_equals(selectedOption.innerHTML, optionOne.innerHTML,
+ 'The innerHTML of <selectedoption> should initially match the innerHTML of the selected <option>.');
+
+ select.value = 'two';
+ assert_equals(selectedOption.innerHTML, optionTwo.innerHTML,
+ 'The innerHTML of <selectedoption> should change after the selected option is changed.');
+
+ spanTwo.textContent = 'new span';
+ assert_equals(selectedOption.innerHTML, optionTwo.innerHTML,
+ '<selectedoption> should respond to text content changes.');
+
+ spanTwo.appendChild(document.createElement('div'));
+ assert_equals(selectedOption.innerHTML, optionTwo.innerHTML,
+ '<selectedoption> should respond to new elements being added to descendants.');
+
+ spanTwo.setAttribute('data-foo', 'bar');
+ assert_equals(selectedOption.innerHTML, optionTwo.innerHTML,
+ '<selectedoption> should respond to attributes being added to descendants.');
+
+ form.reset();
+ assert_equals(select.value, 'one',
+ 'form.reset() should change the selects value to one.');
+ assert_equals(selectedOption.innerHTML, optionOne.innerHTML,
+ 'The innerHTML of <selectedoption> should be updated in response to a form reset.');
+
+ await test_driver.bless();
+ select.showPicker();
+ await test_driver.click(optionTwo);
+ assert_equals(select.value, 'two',
+ 'Clicking on another option should change select.value.');
+ assert_equals(selectedOption.innerHTML, optionTwo.innerHTML,
+ 'Clicking on an option element should update the <selectedoption>.');
+
+ selectedOption.remove();
+ assert_equals(selectedOption.innerHTML, '',
+ 'Removing the <selectedoption> from the <select> should make it clear its contents.');
+ button.appendChild(selectedOption);
+ assert_equals(selectedOption.innerHTML, optionTwo.innerHTML,
+ 'Re-inserting the <selectedoption> should make it update its contents.');
+
+ optionTwo.remove();
+ assert_equals(selectedOption.innerHTML, optionOne.innerHTML,
+ 'The innerHTML of <selectedoption> should be updated in response to selected <option> removal.');
+ optionOne.remove();
+ assert_equals(selectedOption.innerHTML, '',
+ 'The content of <selectedoption> should be cleared if there is no selected <option>.');
+}, 'The <selectedoption> element should reflect the HTML contents of the selected <option>.');
+</script>