HTML: tentative tests for <input type=checkbox switch>

For https://github.com/whatwg/html/pull/9546.

Co-authored-by: lilyspiniolas <119537181+lilyspiniolas@users.noreply.github.com>
diff --git a/html-aam/roles-dynamic-switch.tentative.window.js b/html-aam/roles-dynamic-switch.tentative.window.js
new file mode 100644
index 0000000..2993c36
--- /dev/null
+++ b/html-aam/roles-dynamic-switch.tentative.window.js
@@ -0,0 +1,71 @@
+// META: script=/resources/testdriver.js
+// META: script=/resources/testdriver-vendor.js
+// META: script=/resources/testdriver-actions.js
+
+promise_test(async () => {
+  const control = document.createElement("input");
+  control.type = "checkbox";
+  control.switch = true;
+  const role = await test_driver.get_computed_role(control);
+  assert_equals(role, "");
+}, `Disconnected <input type=checkbox switch>`);
+
+promise_test(async t => {
+  const control = document.createElement("input");
+  t.add_cleanup(() => control.remove());
+  control.type = "checkbox";
+  control.switch = true;
+  document.body.append(control);
+  const role = await test_driver.get_computed_role(control);
+  assert_equals(role, "switch");
+}, `Connected <input type=checkbox switch>`);
+
+promise_test(async t => {
+  const control = document.createElement("input");
+  t.add_cleanup(() => control.remove());
+  control.type = "checkbox";
+  document.body.append(control);
+  let role = await test_driver.get_computed_role(control);
+  assert_equals(role, "checkbox");
+  control.switch = true;
+  role = await test_driver.get_computed_role(control);
+  assert_equals(role, "switch");
+}, `Connected <input type=checkbox switch>: adding switch attribute`);
+
+promise_test(async t => {
+  const control = document.createElement("input");
+  t.add_cleanup(() => control.remove());
+  control.type = "checkbox";
+  control.switch = true;
+  document.body.append(control);
+  let role = await test_driver.get_computed_role(control);
+  assert_equals(role, "switch");
+  control.switch = false;
+  role = await test_driver.get_computed_role(control);
+  assert_equals(role, "checkbox");
+}, `Connected <input type=checkbox switch>: removing switch attribute`);
+
+promise_test(async t => {
+  const control = document.createElement("input");
+  t.add_cleanup(() => control.remove());
+  control.type = "checkbox";
+  document.body.append(control);
+  control.switch = true;
+  let role = await test_driver.get_computed_role(control);
+  assert_equals(role, "switch");
+  control.removeAttribute("type");
+  role = await test_driver.get_computed_role(control);
+  assert_equals(role, "textbox");
+}, `Connected <input type=checkbox switch>: removing type attribute`);
+
+promise_test(async t => {
+  const control = document.createElement("input");
+  t.add_cleanup(() => control.remove());
+  control.switch = true;
+  document.body.append(control);
+  let role = await test_driver.get_computed_role(control);
+  assert_equals(role, "textbox");
+  control.type = "checkbox";
+  role = await test_driver.get_computed_role(control);
+  assert_equals(role, "switch");
+}, `Connected <input type=checkbox switch>: adding type attribute`);
diff --git a/html-aam/roles.tentative.html b/html-aam/roles.tentative.html
new file mode 100644
index 0000000..a3eb850
--- /dev/null
+++ b/html-aam/roles.tentative.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+<head>
+  <title>HTML-AAM Role Verification Tests</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>
+  <script src="/resources/testdriver-actions.js"></script>
+  <script src="/wai-aria/scripts/aria-utils.js"></script>
+</head>
+<body>
+
+
+<p>Tests the computedrole mappings defined in <a href="https://w3c.github.io/html-aam/">HTML-AAM</a>. Most test names correspond to a unique ID defined in the spec.<p>
+
+<p>These should remain in alphabetical order, and include all HTML tagnames. If a tag is not tested here, include a pointer to the file where it is tested, such as: <code>&lt;!-- caption -&gt; ./table-roles.html --&gt;</code></p>
+
+<input type="checkbox" switch data-testname="el-input-checkbox-switch" data-expectedrole="switch" class="ex">
+
+<script>
+AriaUtils.verifyRolesBySelector(".ex");
+</script>
+
+</body>
+</html>
diff --git a/html/rendering/widgets/input-checkbox-switch-indeterminate-ref.html b/html/rendering/widgets/input-checkbox-switch-indeterminate-ref.html
new file mode 100644
index 0000000..cb9a76a
--- /dev/null
+++ b/html/rendering/widgets/input-checkbox-switch-indeterminate-ref.html
@@ -0,0 +1,2 @@
+<!doctype html>
+<input type=checkbox switch>
diff --git a/html/rendering/widgets/input-checkbox-switch-indeterminate.tentative.html b/html/rendering/widgets/input-checkbox-switch-indeterminate.tentative.html
new file mode 100644
index 0000000..bd4137c
--- /dev/null
+++ b/html/rendering/widgets/input-checkbox-switch-indeterminate.tentative.html
@@ -0,0 +1,7 @@
+<!doctype html>
+<title>Checkbox with switch attribute set does not render differently when the indeterminate attribute is set</title>
+<link rel=match href="input-checkbox-switch-indeterminate-ref.html">
+<input id="input" type=checkbox switch>
+<script>
+    input.indeterminate = true;
+</script>
diff --git a/html/rendering/widgets/input-checkbox-switch-notref.html b/html/rendering/widgets/input-checkbox-switch-notref.html
new file mode 100644
index 0000000..75fff5d
--- /dev/null
+++ b/html/rendering/widgets/input-checkbox-switch-notref.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<input type=checkbox>
+<input type=checkbox>
+<input type=checkbox switch>
diff --git a/html/rendering/widgets/input-checkbox-switch-ref.html b/html/rendering/widgets/input-checkbox-switch-ref.html
new file mode 100644
index 0000000..94aa1b7
--- /dev/null
+++ b/html/rendering/widgets/input-checkbox-switch-ref.html
@@ -0,0 +1,4 @@
+<!doctype html>
+<input type=checkbox switch>
+<input type=checkbox switch>
+<input type=checkbox>
diff --git a/html/rendering/widgets/input-checkbox-switch.tentative.html b/html/rendering/widgets/input-checkbox-switch.tentative.html
new file mode 100644
index 0000000..315728d
--- /dev/null
+++ b/html/rendering/widgets/input-checkbox-switch.tentative.html
@@ -0,0 +1,14 @@
+<!doctype html>
+<html class="reftest-wait">
+<title>Checkbox with switch attribute set renders differently than a checkbox without switch attribute</title>
+<link rel=match href="input-checkbox-switch-ref.html">
+<link rel=mismatch href="input-checkbox-switch-notref.html">
+<input type=checkbox switch>
+<input id='input2' type=checkbox>
+<input id='input3' type=checkbox switch>
+<script>
+    input2.setAttribute('switch','');
+    input3.removeAttribute('switch');
+    document.documentElement.classList.remove("reftest-wait");
+</script>
+</html>
diff --git a/html/rendering/widgets/input-checkbox-switch.tentative.window.js b/html/rendering/widgets/input-checkbox-switch.tentative.window.js
new file mode 100644
index 0000000..7e5095a
--- /dev/null
+++ b/html/rendering/widgets/input-checkbox-switch.tentative.window.js
@@ -0,0 +1,16 @@
+test(t => {
+  const input = document.body.appendChild(document.createElement("input"));
+  t.add_cleanup(() => input.remove());
+  input.type = "checkbox";
+  input.switch = true;
+  assert_equals(getComputedStyle(input).appearance, "auto");
+}, "Default appearance value");
+
+test(t => {
+  const input = document.body.appendChild(document.createElement("input"));
+  t.add_cleanup(() => input.remove());
+  input.type = "checkbox";
+  input.switch = true;
+  input.style.appearance = "none";
+  assert_equals(getComputedStyle(input).appearance, "none");
+}, "appearance:none should work");
diff --git a/html/semantics/selectors/pseudo-classes/input-checkbox-switch.tentative.window.js b/html/semantics/selectors/pseudo-classes/input-checkbox-switch.tentative.window.js
new file mode 100644
index 0000000..eb54f2a
--- /dev/null
+++ b/html/semantics/selectors/pseudo-classes/input-checkbox-switch.tentative.window.js
@@ -0,0 +1,62 @@
+test(t => {
+  const input = document.body.appendChild(document.createElement("input"));
+  t.add_cleanup(() => input.remove());
+  input.type = "checkbox";
+  input.switch = true;
+  input.indeterminate = true;
+
+  assert_false(input.matches(":indeterminate"));
+}, "Switch control does not match :indeterminate");
+
+test(t => {
+  const input = document.body.appendChild(document.createElement("input"));
+  t.add_cleanup(() => input.remove());
+  input.type = "checkbox";
+  input.switch = true;
+  input.indeterminate = true;
+
+  assert_false(input.matches(":indeterminate"));
+
+  input.switch = false;
+  assert_true(input.matches(":indeterminate"));
+}, "Checkbox that is no longer a switch control does match :indeterminate");
+
+test(t => {
+  const input = document.body.appendChild(document.createElement("input"));
+  t.add_cleanup(() => input.remove());
+  input.type = "checkbox";
+  input.indeterminate = true;
+
+  assert_true(input.matches(":indeterminate"));
+
+  input.setAttribute("switch", "blah");
+  assert_false(input.matches(":indeterminate"));
+}, "Checkbox that becomes a switch control does not match :indeterminate");
+
+test(t => {
+  const input = document.body.appendChild(document.createElement("input"));
+  t.add_cleanup(() => input.remove());
+  input.type = "checkbox";
+  input.indeterminate = true;
+
+  assert_true(document.body.matches(":has(:indeterminate)"));
+
+  input.switch = true;
+  assert_false(document.body.matches(":has(:indeterminate)"));
+}, "Parent of a checkbox that becomes a switch control does not match :has(:indeterminate)");
+
+test(t => {
+  const input = document.body.appendChild(document.createElement("input"));
+  t.add_cleanup(() => input.remove());
+  input.type = "checkbox";
+  input.switch = true
+  input.checked = true;
+
+  assert_true(document.body.matches(":has(:checked)"));
+
+  input.switch = false;
+  assert_true(document.body.matches(":has(:checked)"));
+
+  input.checked = false;
+  assert_false(document.body.matches(":has(:checked)"));
+}, "Parent of a switch control that becomes a checkbox continues to match :has(:checked)");