v1 of accname name computation tests (#39604)

* v1 of accname name computation test files (with todos b/c this is not exhaustive)
* new error handling in aria-utils.js
diff --git a/accname/META.yml b/accname/META.yml
index 356c4b2..81588fb 100644
--- a/accname/META.yml
+++ b/accname/META.yml
@@ -1,4 +1,7 @@
 spec: https://w3c.github.io/accname/
 suggested_reviewers:
+  - cookiecrook
+  - spectranaut
+  - jnurthen
   - halindrome
   - joanmarie
diff --git a/accname/basic.html b/accname/basic.html
index 0df93c8..0971235 100644
--- a/accname/basic.html
+++ b/accname/basic.html
@@ -11,12 +11,12 @@
 
 promise_test(async t => {
   const label = await test_driver.get_computed_label(document.getElementById('d'));
-  assert_true(label == "test label");
+  assert_equals(label, "test label");
 }, "tests labelFrom: author");
 
 promise_test(async t => {
   const label = await test_driver.get_computed_label(document.getElementById('h'));
-  assert_true(label == "test heading");
+  assert_equals(label, "test heading");
 }, "tests labelFrom: contents");
 
 </script>
diff --git a/accname/name/ReadMe.md b/accname/name/ReadMe.md
new file mode 100644
index 0000000..be95525
--- /dev/null
+++ b/accname/name/ReadMe.md
@@ -0,0 +1,60 @@
+
+## Breakdown of AccName Name Computation files...
+
+Portions of the AccName algorithm are referenced via unique IDs such as `comp_labelledby` and `comp_embedded_control`. This ReadMe lists those sections (and subsections) in order as they appear in [AccName Computation Steps](https://w3c.github.io/accname/#computation-steps).
+
+In order to make the WPT test files digestible and understandable, the tests are broken up more or less in the structure of the algorithm, with the file struction listed below. Sub-section test (such as `comp_labelledby_recursion`) are tested as part of the main section `comp_labelledby` in [comp_labelledby.html](comp_labelledby.html).
+
+Non-name portions of the AccName spec (such as Descripton Computation) should be tested in another directory.
+
+If a new section of the AccName algorithm is added, please list it here when checking in new tests. Thanks.
+
+### No-Op (no test files)
+- comp_init
+- comp_computation
+
+### [comp_hidden_not_referenced](comp_hidden_not_referenced.html)
+
+### [comp_labelledby](comp_labelledby.html)
+  - comp_labelledby_reset
+  - comp_labelledby_foreach
+  - comp_labelledby_set_current
+  - comp_labelledby_recursion
+  - comp_labelledby_append
+  - comp_labelledby_return
+
+### [comp_embedded_control](comp_embedded_control.html)
+ - comp_embedded_control_textbox
+ - comp_embedded_control_combobox_or_listbox
+ - comp_embedded_control_range
+ - comp_embedded_control_range_valuetext
+ - comp_embedded_control_range_valuenow
+ - comp_embedded_control_range_host_language_value
+
+### [comp_label](comp_label.html)
+
+### [comp_host_language_label](comp_host_language_label.html)
+
+### [comp_name_from_content](comp_name_from_content.html)
+  - comp_name_from_content_reset
+  - comp_name_from_content_pseudo_element
+  - comp_name_from_content_pseudo_element_before
+  - comp_name_from_content_pseudo_element_after
+  - comp_name_from_content_for_each_child
+  - comp_name_from_content_for_each_child_set_current
+  - comp_name_from_content_for_each_child_recursion
+  - comp_for_each_child_append
+  - comp_name_from_content_return
+
+### [comp_text_node](comp_text_node.html)
+
+### comp_recursive_name_from_content (tested with [comp_name_from_content](comp_name_from_content.html))
+
+### [comp_tooltip](comp_tooltip.html)
+
+### No-Op (no test files)
+  - comp_append
+  - comp_complete
+
+
+
diff --git a/accname/name/comp_embedded_control.html b/accname/name/comp_embedded_control.html
new file mode 100644
index 0000000..cfcd4d2
--- /dev/null
+++ b/accname/name/comp_embedded_control.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+  <title>Name Comp: Embedded Control</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>
+
+<label>
+  <input type="checkbox" data-expectedlabel="Flash the screen 3 times" data-testname="checkbox label with embedded textfield" class="ex">
+  Flash the screen
+  <input value="3" aria-label="number of times" data-expectedlabel="number of times" data-testname="label of embedded textfield inside checkbox label" class="ex"> times
+</label>
+
+
+<!--
+
+Todo: test all remaining cases of https://w3c.github.io/accname/#comp_embedded_control
+ - comp_embedded_control_textbox
+ - comp_embedded_control_combobox_or_listbox
+ - comp_embedded_control_range
+ - comp_embedded_control_range_valuetext
+ - comp_embedded_control_range_valuenow
+ - comp_embedded_control_range_host_language_value
+
+-->
+
+<script>
+AriaUtils.verifyLabelsBySelector(".ex");
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/accname/name/comp_hidden_not_referenced.html b/accname/name/comp_hidden_not_referenced.html
new file mode 100644
index 0000000..cfaebbb
--- /dev/null
+++ b/accname/name/comp_hidden_not_referenced.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+<head>
+  <title>Name Comp: Hidden Not Referenced</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>
+
+<h2 class="ex" data-expectedlabel="heading label" data-testname="heading with interior hidden node">
+  heading
+  <span hidden>bogus</span>
+  label
+</h2>
+
+<!-- Todo: test all remaining cases of https://w3c.github.io/accname/#comp_hidden_not_referenced -->
+
+<script>
+AriaUtils.verifyLabelsBySelector(".ex");
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/accname/name/comp_host_language_label.html b/accname/name/comp_host_language_label.html
new file mode 100644
index 0000000..d2638b1
--- /dev/null
+++ b/accname/name/comp_host_language_label.html
@@ -0,0 +1,30 @@
+<!doctype html>
+<html>
+<head>
+  <title>Name Comp: Host Language Label</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>
+
+<label for="t">label</label>
+<input id="t" data-expectedlabel="label" data-testname="host language: label[for] input[type=text]" class="ex">
+<!-- Todo: test all remaining input types with label[for] -->
+
+<label>
+  <input type="checkbox" data-expectedlabel="label" data-testname="host language: label input[type=checkbox] encapsulation" class="ex">
+  label
+</label>
+<!-- Todo: test all remaining input types with label encapsulation -->
+
+<!-- Todo: test all remaining cases of https://w3c.github.io/accname/#comp_host_language_label -->
+
+<script>
+AriaUtils.verifyLabelsBySelector(".ex");
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/accname/name/comp_label.html b/accname/name/comp_label.html
new file mode 100644
index 0000000..9edd800
--- /dev/null
+++ b/accname/name/comp_label.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<html>
+<head>
+  <title>Name Comp: Label</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>
+
+<div aria-label="label" data-expectedlabel="label" data-testname="label valid on group" role="group" class="ex">x</div>
+
+<!-- Todo: test all remaining cases of https://w3c.github.io/accname/#comp_label -->
+
+<script>
+AriaUtils.verifyLabelsBySelector(".ex");
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/accname/name/comp_labelledby.html b/accname/name/comp_labelledby.html
new file mode 100644
index 0000000..8e66362
--- /dev/null
+++ b/accname/name/comp_labelledby.html
@@ -0,0 +1,35 @@
+<!doctype html>
+<html>
+<head>
+  <title>Name Comp: Labelledby</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>
+
+<div role="group" aria-labelledby="h" class="ex" data-expectedlabel="div group label" data-testname="div group explicitly labelledby heading">
+  <h2 id="h">div group label</h2>
+  <p>text inside div group</p>
+</div>
+
+<!--
+
+Todo: test all remaining cases of https://w3c.github.io/accname/#comp_labelledby
+  - comp_labelledby_reset
+  - comp_labelledby_foreach
+  - comp_labelledby_set_current
+  - comp_labelledby_recursion
+  - comp_labelledby_append
+  - comp_labelledby_return
+
+-->
+
+<script>
+AriaUtils.verifyLabelsBySelector(".ex");
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/accname/name/comp_name_from_content.html b/accname/name/comp_name_from_content.html
new file mode 100644
index 0000000..1390c6d
--- /dev/null
+++ b/accname/name/comp_name_from_content.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<html>
+<head>
+  <title>Name Comp: Name From Content</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>
+
+<h1 data-expectedlabel="label" data-testname="heading name from content" class="ex">label</h1>
+
+<!--
+
+Todo: test all remaining cases of https://w3c.github.io/accname/#comp_name_from_content
+  - comp_name_from_content_reset
+  - comp_name_from_content_pseudo_element
+  - comp_name_from_content_pseudo_element_before
+  - comp_name_from_content_pseudo_element_after
+  - comp_name_from_content_for_each_child
+  - comp_name_from_content_for_each_child_set_current
+  - comp_name_from_content_for_each_child_recursion
+  - comp_for_each_child_append
+  - comp_name_from_content_return
+
+Todo: test all remaining *recursive* cases in https://w3c.github.io/accname/#comp_recursive_name_from_content
+
+-->
+
+<script>
+AriaUtils.verifyLabelsBySelector(".ex");
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/accname/name/comp_text_node.html b/accname/name/comp_text_node.html
new file mode 100644
index 0000000..61f51cf
--- /dev/null
+++ b/accname/name/comp_text_node.html
@@ -0,0 +1,36 @@
+<!doctype html>
+<html>
+<head>
+  <title>Name Comp: Text Node</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>
+
+<!-- I'm not certain whether #comp_text_node requires a lot of testing outside of the #comp_name_from_content contexts, -->
+<!-- but I did think of one example where text node versus comment node may make a difference when joining text nodes with a space vs innerText. -->
+
+<!-- Skipped (class="ex" removed) until https://github.com/w3c/accname/issues/193 is resolved -->
+<h2 class="ex-skipped" data-expectedlabel="heading label" data-testname="heading with text/comment/text nodes, no space">
+  heading<!-- with non-text node splitting concatenated text nodes -->label<!-- [sic] no extra spaces around first comment -->
+</h2>
+
+
+<h2 class="ex" data-expectedlabel="heading label" data-testname="heading with text/comment/text nodes, with space">
+  heading
+  <!-- comment node between text nodes with leading/trailing whitespace -->
+  label
+</h2>
+
+
+<!-- Todo: test all remaining cases of https://w3c.github.io/accname/#comp_text_node -->
+
+<script>
+AriaUtils.verifyLabelsBySelector(".ex");
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/accname/name/comp_tooltip.html b/accname/name/comp_tooltip.html
new file mode 100644
index 0000000..52e7b43
--- /dev/null
+++ b/accname/name/comp_tooltip.html
@@ -0,0 +1,22 @@
+<!doctype html>
+<html>
+<head>
+  <title>Name Comp: Tooltip</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>
+
+<a href="#" title="label" data-expectedlabel="label" data-testname="link label from tooltip" class="ex"><img src="#" alt=""></a>
+
+<!-- Todo: test all remaining cases of https://w3c.github.io/accname/#comp_tooltip -->
+
+<script>
+AriaUtils.verifyLabelsBySelector(".ex");
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/wai-aria/META.yml b/wai-aria/META.yml
index 25ab1c2..502b9c3 100644
--- a/wai-aria/META.yml
+++ b/wai-aria/META.yml
@@ -1,6 +1,8 @@
 spec: https://w3c.github.io/aria/
 suggested_reviewers:
   - cookiecrook
+  - spectranaut
+  - jnurthen
   - halindrome
   - joanmarie
   - michael-n-cooper
diff --git a/wai-aria/scripts/aria-utils.js b/wai-aria/scripts/aria-utils.js
index 41d8535..e6411a9 100644
--- a/wai-aria/scripts/aria-utils.js
+++ b/wai-aria/scripts/aria-utils.js
@@ -5,8 +5,14 @@
   /*
   Tests simple role assignment: <div role="alert">x</div>
   Not intended for nested, context-dependent, or other complex role tests.
+
+  Ex: AriaUtils.assignAndVerifyRolesByRoleNames(["group", "main", "button"])
+
   */
   assignAndVerifyRolesByRoleNames: function(roleNames) {
+    if (!Array.isArray(roleNames) || !roleNames.length) {
+      throw `Param roleNames of assignAndVerifyRolesByRoleNames("${roleNames}") should be an array containing at least one role string.`;
+    }
     for (const role of roleNames) {
       promise_test(async t => {
         let el = document.createElement("div");
@@ -20,9 +26,10 @@
     }
   },
 
+
   /*
-  Tests computed role of all elements matching selector
-  against the string value of their data-role attribute.
+  Tests computed ROLE of all elements matching selector
+  against the string value of their data-expectedrole attribute.
 
   Ex: <div role="list"
         data-testname="optional unique test name"
@@ -34,9 +41,12 @@
   */
   verifyRolesBySelector: function(selector) {
     const els = document.querySelectorAll(selector);
+    if (!els.length) {
+      throw `Selector passed in verifyRolesBySelector("${selector}") should match at least one element.`;
+    }
     for (const el of els) {
       let role = el.getAttribute("data-expectedrole");
-      let testName = el.getAttribute("data-testname") || role; // data-testname optional if role unique per test file
+      let testName = el.getAttribute("data-testname") || role; // data-testname optional if role is unique per test file
       promise_test(async t => {
         const expectedRole = el.getAttribute("data-expectedrole");
 
@@ -57,5 +67,51 @@
     }
   },
 
+
+  /*
+  Tests computed LABEL of all elements matching selector
+  against the string value of their data-expectedlabel attribute.
+
+  Ex: <div aria-label="foo"
+        data-testname="optional unique test name"
+        data-expectedlabel="foo"
+        class="ex">
+
+      AriaUtils.verifyLabelsBySelector(".ex")
+
+  */
+  verifyLabelsBySelector: function(selector) {
+    const els = document.querySelectorAll(selector);
+    if (!els.length) {
+      throw `Selector passed in verifyLabelsBySelector("${selector}") should match at least one element.`;
+    }
+    for (const el of els) {
+      let label = el.getAttribute("data-expectedlabel");
+      let testName = el.getAttribute("data-testname") || label; // data-testname optional if label is unique per test file
+      promise_test(async t => {
+        const expectedLabel = el.getAttribute("data-expectedlabel");
+
+        // ensure ID existence and uniqueness for the webdriver callback
+        if (!el.id) {
+          let labelCount = 1;
+          let elID = `labelTest${labelCount}`;
+          while(document.getElementById(elID)) {
+            labelCount++;
+            elID = `labelTest${labelCount}`;
+          }
+          el.id = elID;
+        }
+
+        let computedLabel = await test_driver.get_computed_label(el);
+
+        // Todo: Remove whitespace normalization after https://github.com/w3c/accname/issues/192 is addressed. Change prior line back to `const`, too.
+        computedLabel = computedLabel.trim()
+
+        assert_equals(computedLabel, expectedLabel, el.outerHTML);
+      }, `${testName}`);
+    }
+  },
+
+
 };