Pārlūkot izejas kodu

LibWeb: Don't allow trailing commas in selector lists

comma-separated list != #-multiplier
Gingeh 7 mēneši atpakaļ
vecāks
revīzija
bb5678a175

+ 2 - 0
Libraries/LibWeb/CSS/Parser/Parser.cpp

@@ -768,6 +768,8 @@ Vector<ComponentValue> Parser::consume_a_list_of_component_values(TokenStream<T>
         }
     }
 }
+template Vector<ComponentValue> Parser::consume_a_list_of_component_values(TokenStream<ComponentValue>& input, Optional<Token::Type> stop_token, Nested nested);
+template Vector<ComponentValue> Parser::consume_a_list_of_component_values(TokenStream<Token>& input, Optional<Token::Type> stop_token, Nested nested);
 
 // https://drafts.csswg.org/css-syntax/#consume-simple-block
 template<typename T>

+ 11 - 6
Libraries/LibWeb/CSS/Parser/SelectorParsing.cpp

@@ -86,10 +86,9 @@ static NonnullRefPtr<Selector> create_invalid_selector(Selector::Combinator comb
 template<typename T>
 Parser::ParseErrorOr<SelectorList> Parser::parse_a_selector_list(TokenStream<T>& tokens, SelectorType mode, SelectorParsingMode parsing_mode)
 {
-    auto comma_separated_lists = parse_a_comma_separated_list_of_component_values(tokens);
-
     SelectorList selectors;
-    for (auto& selector_parts : comma_separated_lists) {
+    for (;;) {
+        auto selector_parts = consume_a_list_of_component_values(tokens, Token::Type::Comma);
         auto stream = TokenStream(selector_parts);
         auto selector = parse_complex_selector(stream, mode);
         if (selector.is_error()) {
@@ -97,11 +96,17 @@ Parser::ParseErrorOr<SelectorList> Parser::parse_a_selector_list(TokenStream<T>&
                 // Keep the invalid selector around for serialization and nesting
                 auto combinator = mode == SelectorType::Standalone ? Selector::Combinator::None : Selector::Combinator::Descendant;
                 selectors.append(create_invalid_selector(combinator, move(selector_parts)));
-                continue;
+            } else {
+                return selector.error();
             }
-            return selector.error();
+        } else {
+            selectors.append(selector.release_value());
         }
-        selectors.append(selector.release_value());
+
+        if (tokens.is_empty())
+            break;
+
+        tokens.discard_a_token();
     }
 
     if (selectors.is_empty() && parsing_mode != SelectorParsingMode::Forgiving)

+ 3 - 0
Tests/LibWeb/TestConfig.ini

@@ -165,3 +165,6 @@ Text/input/wpt-import/css/css-backgrounds/animations/discrete-no-interpolation.h
 
 ; https://github.com/LadybirdBrowser/ladybird/issues/2314
 Text/input/test-http-test-server.html
+
+; Too slow for CI
+Text/input/wpt-import/dom/nodes/ParentNode-querySelector-All.html

+ 377 - 0
Tests/LibWeb/Text/data/ParentNode-querySelector-All-content.html

@@ -0,0 +1,377 @@
+<!DOCTYPE html>
+<html id="html" lang="en">
+<head id="head">
+  <meta id="meta" charset="UTF-8">
+  <title id="title">Selectors-API Test Suite: HTML with Selectors Level 2 using TestHarness: Test Document</title>
+
+  <!-- Links for :link and :visited pseudo-class test -->
+  <link id="pseudo-link-link1" href="">
+  <link id="pseudo-link-link2" href="http://example.org/">
+  <link id="pseudo-link-link3">
+  <style>
+  @namespace ns "http://www.w3.org/1999/xhtml";
+   /* Declare the namespace prefix used in tests. This declaration should not be used by the API. */
+  </style>
+</head>
+<body id="body">
+<div id="root">
+  <div id="target"></div>
+
+  <div id="universal">
+    <p id="universal-p1">Universal selector tests inside element with <code id="universal-code1">id="universal"</code>.</p>
+    <hr id="universal-hr1">
+    <pre id="universal-pre1">Some preformatted text with some <span id="universal-span1">embedded code</span></pre>
+    <p id="universal-p2">This is a normal link: <a id="universal-a1" href="http://www.w3.org/">W3C</a></p>
+    <address id="universal-address1">Some more nested elements <code id="universal-code2"><a href="#" id="universal-a2">code hyperlink</a></code></address>
+  </div>
+
+  <div id="attr-presence">
+    <div class="attr-presence-div1" id="attr-presence-div1" align="center"></div>
+    <div class="attr-presence-div2" id="attr-presence-div2" align=""></div>
+    <div class="attr-presence-div3" id="attr-presence-div3" valign="center"></div>
+    <div class="attr-presence-div4" id="attr-presence-div4" alignv="center"></div>
+    <p id="attr-presence-p1"><a  id="attr-presence-a1" tItLe=""></a><span id="attr-presence-span1" TITLE="attr-presence-span1"></span><i id="attr-presence-i1"></i></p>
+    <pre id="attr-presence-pre1" data-attr-presence="pre1"></pre>
+    <blockquote id="attr-presence-blockquote1" data-attr-presence="blockquote1"></blockquote>
+    <ul id="attr-presence-ul1" data-中文=""></ul>
+
+    <select id="attr-presence-select1">
+      <option id="attr-presence-select1-option1">A</option>
+      <option id="attr-presence-select1-option2">B</option>
+      <option id="attr-presence-select1-option3">C</option>
+      <option id="attr-presence-select1-option4">D</option>
+    </select>
+    <select id="attr-presence-select2">
+      <option id="attr-presence-select2-option1">A</option>
+      <option id="attr-presence-select2-option2">B</option>
+      <option id="attr-presence-select2-option3">C</option>
+      <option id="attr-presence-select2-option4" selected="selected">D</option>
+    </select>
+    <select id="attr-presence-select3" multiple="multiple">
+      <option id="attr-presence-select3-option1">A</option>
+      <option id="attr-presence-select3-option2" selected="">B</option>
+      <option id="attr-presence-select3-option3" selected="selected">C</option>
+      <option id="attr-presence-select3-option4">D</option>
+    </select>
+  </div>
+
+  <div id="attr-value">
+    <div id="attr-value-div1" align="center"></div>
+      <div id="attr-value-div2" align=""></div>
+      <div id="attr-value-div3" data-attr-value="&#xE9;"></div>
+      <div id="attr-value-div4" data-attr-value_foo="&#xE9;"></div>
+
+    <form id="attr-value-form1">
+      <input id="attr-value-input1" type="text">
+      <input id="attr-value-input2" type="password">
+      <input id="attr-value-input3" type="hidden">
+      <input id="attr-value-input4" type="radio">
+      <input id="attr-value-input5" type="checkbox">
+      <input id="attr-value-input6" type="radio">
+      <input id="attr-value-input7" type="text">
+      <input id="attr-value-input8" type="hidden">
+      <input id="attr-value-input9" type="radio">
+    </form>
+
+    <div id="attr-value-div5" data-attr-value="中文"></div>
+  </div>
+
+  <div id="attr-whitespace">
+    <div id="attr-whitespace-div1" class="foo div1 bar"></div>
+      <div id="attr-whitespace-div2" class=""></div>
+      <div id="attr-whitespace-div3" class="foo div3 bar"></div>
+
+      <div id="attr-whitespace-div4" data-attr-whitespace="foo &#xE9; bar"></div>
+      <div id="attr-whitespace-div5" data-attr-whitespace_foo="&#xE9; foo"></div>
+
+    <a id="attr-whitespace-a1" rel="next bookmark"></a>
+    <a id="attr-whitespace-a2" rel="tag nofollow"></a>
+    <a id="attr-whitespace-a3" rel="tag bookmark"></a>
+    <a id="attr-whitespace-a4" rel="book mark"></a> <!-- Intentional space in "book mark" -->
+    <a id="attr-whitespace-a5" rel="nofollow"></a>
+    <a id="attr-whitespace-a6" rev="bookmark nofollow"></a>
+    <a id="attr-whitespace-a7" rel="prev next tag alternate nofollow author help icon noreferrer prefetch search stylesheet tag"></a>
+
+    <p id="attr-whitespace-p1" title="Chinese 中文 characters"></p>
+  </div>
+
+  <div id="attr-hyphen">
+    <div id="attr-hyphen-div1"></div>
+      <div id="attr-hyphen-div2" lang="fr"></div>
+      <div id="attr-hyphen-div3" lang="en-AU"></div>
+      <div id="attr-hyphen-div4" lang="es"></div>
+  </div>
+
+  <div id="attr-begins">
+    <a id="attr-begins-a1" href="http://www.example.org"></a>
+    <a id="attr-begins-a2" href="http://example.org/"></a>
+    <a id="attr-begins-a3" href="http://www.example.com/"></a>
+
+      <div id="attr-begins-div1" lang="fr"></div>
+      <div id="attr-begins-div2" lang="en-AU"></div>
+      <div id="attr-begins-div3" lang="es"></div>
+      <div id="attr-begins-div4" lang="en-US"></div>
+      <div id="attr-begins-div5" lang="en"></div>
+
+    <p id="attr-begins-p1" class=" apple"></p> <!-- Intentional space in class value " apple". -->
+  </div>
+
+  <div id="attr-ends">
+    <a id="attr-ends-a1" href="http://www.example.org"></a>
+    <a id="attr-ends-a2" href="http://example.org/"></a>
+    <a id="attr-ends-a3" href="http://www.example.org"></a>
+
+      <div id="attr-ends-div1" lang="fr"></div>
+      <div id="attr-ends-div2" lang="de-CH"></div>
+      <div id="attr-ends-div3" lang="es"></div>
+      <div id="attr-ends-div4" lang="fr-CH"></div>
+
+    <p id="attr-ends-p1" class="apple "></p> <!-- Intentional space in class value "apple ". -->
+  </div>
+
+  <div id="attr-contains">
+    <a id="attr-contains-a1" href="http://www.example.org"></a>
+    <a id="attr-contains-a2" href="http://example.org/"></a>
+    <a id="attr-contains-a3" href="http://www.example.com/"></a>
+
+      <div id="attr-contains-div1" lang="fr"></div>
+      <div id="attr-contains-div2" lang="en-AU"></div>
+      <div id="attr-contains-div3" lang="de-CH"></div>
+      <div id="attr-contains-div4" lang="es"></div>
+      <div id="attr-contains-div5" lang="fr-CH"></div>
+      <div id="attr-contains-div6" lang="en-US"></div>
+
+    <p id="attr-contains-p1" class=" apple banana orange "></p>
+  </div>
+
+  <div id="pseudo-nth">
+    <table id="pseudo-nth-table1">
+      <tr id="pseudo-nth-tr1"><td id="pseudo-nth-td1"></td><td id="pseudo-nth-td2"></td><td id="pseudo-nth-td3"></td><td id="pseudo-nth-td4"></td><td id="pseudo-nth--td5"></td><td id="pseudo-nth-td6"></td></tr>
+      <tr id="pseudo-nth-tr2"><td id="pseudo-nth-td7"></td><td id="pseudo-nth-td8"></td><td id="pseudo-nth-td9"></td><td id="pseudo-nth-td10"></td><td id="pseudo-nth-td11"></td><td id="pseudo-nth-td12"></td></tr>
+      <tr id="pseudo-nth-tr3"><td id="pseudo-nth-td13"></td><td id="pseudo-nth-td14"></td><td id="pseudo-nth-td15"></td><td id="pseudo-nth-td16"></td><td id="pseudo-nth-td17"></td><td id="pseudo-nth-td18"></td></tr>
+    </table>
+
+    <ol id="pseudo-nth-ol1">
+      <li id="pseudo-nth-li1"></li>
+      <li id="pseudo-nth-li2"></li>
+      <li id="pseudo-nth-li3"></li>
+      <li id="pseudo-nth-li4"></li>
+      <li id="pseudo-nth-li5"></li>
+      <li id="pseudo-nth-li6"></li>
+      <li id="pseudo-nth-li7"></li>
+      <li id="pseudo-nth-li8"></li>
+      <li id="pseudo-nth-li9"></li>
+      <li id="pseudo-nth-li10"></li>
+      <li id="pseudo-nth-li11"></li>
+      <li id="pseudo-nth-li12"></li>
+    </ol>
+
+    <p id="pseudo-nth-p1">
+      <span id="pseudo-nth-span1">span1</span>
+      <em id="pseudo-nth-em1">em1</em>
+      <!-- comment node-->
+      <em id="pseudo-nth-em2">em2</em>
+      <span id="pseudo-nth-span2">span2</span>
+      <strong id="pseudo-nth-strong1">strong1</strong>
+      <em id="pseudo-nth-em3">em3</em>
+      <span id="pseudo-nth-span3">span3</span>
+      <span id="pseudo-nth-span4">span4</span>
+      <strong id="pseudo-nth-strong2">strong2</strong>
+      <em id="pseudo-nth-em4">em4</em>
+    </p>
+  </div>
+
+  <div id="pseudo-first-child">
+    <div id="pseudo-first-child-div1"></div>
+    <div id="pseudo-first-child-div2"></div>
+    <div id="pseudo-first-child-div3"></div>
+
+    <p id="pseudo-first-child-p1"><span id="pseudo-first-child-span1"></span><span id="pseudo-first-child-span2"></span></p>
+    <p id="pseudo-first-child-p2"><span id="pseudo-first-child-span3"></span><span id="pseudo-first-child-span4"></span></p>
+    <p id="pseudo-first-child-p3"><span id="pseudo-first-child-span5"></span><span id="pseudo-first-child-span6"></span></p>
+  </div>
+
+  <div id="pseudo-last-child">
+    <p id="pseudo-last-child-p1"><span id="pseudo-last-child-span1"></span><span id="pseudo-last-child-span2"></span></p>
+    <p id="pseudo-last-child-p2"><span id="pseudo-last-child-span3"></span><span id="pseudo-last-child-span4"></span></p>
+    <p id="pseudo-last-child-p3"><span id="pseudo-last-child-span5"></span><span id="pseudo-last-child-span6"></span></p>
+
+    <div id="pseudo-last-child-div1"></div>
+    <div id="pseudo-last-child-div2"></div>
+    <div id="pseudo-last-child-div3"></div>
+  </div>
+
+  <div id="pseudo-only">
+    <p id="pseudo-only-p1">
+      <span id="pseudo-only-span1"></span>
+    </p>
+    <p id="pseudo-only-p2">
+      <span id="pseudo-only-span2"></span>
+      <span id="pseudo-only-span3"></span>
+    </p>
+    <p id="pseudo-only-p3">
+      <span id="pseudo-only-span4"></span>
+      <em id="pseudo-only-em1"></em>
+      <span id="pseudo-only-span5"></span>
+    </p>
+  </div>>
+
+  <div id="pseudo-empty">
+    <p id="pseudo-empty-p1"></p>
+    <p id="pseudo-empty-p2"><!-- comment node --></p>
+    <p id="pseudo-empty-p3"> </p>
+    <p id="pseudo-empty-p4">Text node</p>
+    <p id="pseudo-empty-p5"><span id="pseudo-empty-span1"></span></p>
+  </div>
+
+  <div id="pseudo-link">
+    <a id="pseudo-link-a1" href="">with href</a>
+    <a id="pseudo-link-a2" href="http://example.org/">with href</a>
+    <a id="pseudo-link-a3">without href</a>
+    <map name="pseudo-link-map1" id="pseudo-link-map1">
+      <area id="pseudo-link-area1" href="">
+      <area id="pseudo-link-area2">
+    </map>
+  </div>
+
+  <div id="pseudo-lang">
+    <div id="pseudo-lang-div1"></div>
+      <div id="pseudo-lang-div2" lang="fr"></div>
+      <div id="pseudo-lang-div3" lang="en-AU"></div>
+      <div id="pseudo-lang-div4" lang="es"></div>
+  </div>
+
+  <div id="pseudo-ui">
+    <input id="pseudo-ui-input1" type="text">
+    <input id="pseudo-ui-input2" type="password">
+    <input id="pseudo-ui-input3" type="radio">
+    <input id="pseudo-ui-input4" type="radio" checked="checked">
+    <input id="pseudo-ui-input5" type="checkbox">
+    <input id="pseudo-ui-input6" type="checkbox" checked="checked">
+    <input id="pseudo-ui-input7" type="submit">
+    <input id="pseudo-ui-input8" type="button">
+    <input id="pseudo-ui-input9" type="hidden">
+    <textarea id="pseudo-ui-textarea1"></textarea>
+    <button id="pseudo-ui-button1">Enabled</button>
+
+    <input id="pseudo-ui-input10" disabled="disabled" type="text">
+    <input id="pseudo-ui-input11" disabled="disabled" type="password">
+    <input id="pseudo-ui-input12" disabled="disabled" type="radio">
+    <input id="pseudo-ui-input13" disabled="disabled" type="radio" checked="checked">
+    <input id="pseudo-ui-input14" disabled="disabled" type="checkbox">
+    <input id="pseudo-ui-input15" disabled="disabled" type="checkbox" checked="checked">
+    <input id="pseudo-ui-input16" disabled="disabled" type="submit">
+    <input id="pseudo-ui-input17" disabled="disabled" type="button">
+    <input id="pseudo-ui-input18" disabled="disabled" type="hidden">
+    <textarea id="pseudo-ui-textarea2" disabled="disabled"></textarea>
+    <button id="pseudo-ui-button2" disabled="disabled">Disabled</button>
+  </div>
+
+  <div id="not">
+    <div id="not-div1"></div>
+    <div id="not-div2"></div>
+    <div id="not-div3"></div>
+
+    <p id="not-p1"><span id="not-span1"></span><em id="not-em1"></em></p>
+    <p id="not-p2"><span id="not-span2"></span><em id="not-em2"></em></p>
+    <p id="not-p3"><span id="not-span3"></span><em id="not-em3"></em></p>
+  </div>
+
+  <div id="pseudo-element">All pseudo-element tests</div>
+
+  <div id="class">
+    <p id="class-p1" class="foo class-p bar"></p>
+    <p id="class-p2" class="class-p foo bar"></p>
+    <p id="class-p3" class="foo bar class-p"></p>
+
+    <!-- All permutations of the classes should match -->
+    <div id="class-div1" class="apple orange banana"></div>
+    <div id="class-div2" class="apple banana orange"></div>
+    <p id="class-p4" class="orange apple banana"></p>
+    <div id="class-div3" class="orange banana apple"></div>
+    <p id="class-p6" class="banana apple orange"></p>
+    <div id="class-div4" class="banana orange apple"></div>
+    <div id="class-div5" class="apple orange"></div>
+    <div id="class-div6" class="apple banana"></div>
+    <div id="class-div7" class="orange banana"></div>
+
+    <span id="class-span1" class="台北Táiběi 台北"></span>
+    <span id="class-span2" class="台北"></span>
+
+    <span id="class-span3" class="foo:bar"></span>
+    <span id="class-span4" class="test.foo[5]bar"></span>
+  </div>
+
+  <div id="id">
+    <div id="id-div1"></div>
+    <div id="id-div2"></div>
+
+    <ul id="id-ul1">
+      <li id="id-li-duplicate"></li>
+      <li id="id-li-duplicate"></li>
+      <li id="id-li-duplicate"></li>
+      <li id="id-li-duplicate"></li>
+    </ul>
+
+    <span id="台北Táiběi"></span>
+    <span id="台北"></span>
+
+    <span id="#foo:bar"></span>
+    <span id="test.foo[5]bar"></span>
+  </div>
+
+  <div id="descendant">
+    <div id="descendant-div1" class="descendant-div1">
+      <div id="descendant-div2" class="descendant-div2">
+        <div id="descendant-div3" class="descendant-div3">
+        </div>
+      </div>
+    </div>
+    <div id="descendant-div4" class="descendant-div4"></div>
+  </div>
+
+  <div id="child">
+    <div id="child-div1" class="child-div1">
+      <div id="child-div2" class="child-div2">
+        <div id="child-div3" class="child-div3">
+        </div>
+      </div>
+    </div>
+    <div id="child-div4" class="child-div4"></div>
+  </div>
+
+  <div id="adjacent">
+    <div id="adjacent-div1" class="adjacent-div1"></div>
+    <div id="adjacent-div2" class="adjacent-div2">
+      <div id="adjacent-div3" class="adjacent-div3"></div>
+    </div>
+    <div id="adjacent-div4" class="adjacent-div4">
+      <p id="adjacent-p1" class="adjacent-p1"></p>
+      <div id="adjacent-div5" class="adjacent-div5"></div>
+    </div>
+    <div id="adjacent-div6" class="adjacent-div6"></div>
+    <p id="adjacent-p2" class="adjacent-p2"></p>
+    <p id="adjacent-p3" class="adjacent-p3"></p>
+  </div>
+
+  <div id="sibling">
+    <div id="sibling-div1" class="sibling-div"></div>
+    <div id="sibling-div2" class="sibling-div">
+      <div id="sibling-div3" class="sibling-div"></div>
+    </div>
+    <div id="sibling-div4" class="sibling-div">
+      <p id="sibling-p1" class="sibling-p"></p>
+      <div id="sibling-div5" class="sibling-div"></div>
+    </div>
+    <div id="sibling-div6" class="sibling-div"></div>
+    <p id="sibling-p2" class="sibling-p"></p>
+    <p id="sibling-p3" class="sibling-p"></p>
+  </div>
+
+  <div id="group">
+    <em id="group-em1"></em>
+    <strong id="group-strong1"></strong>
+  </div>
+</div>
+</body>
+</html>

+ 1986 - 0
Tests/LibWeb/Text/expected/wpt-import/dom/nodes/ParentNode-querySelector-All.txt

@@ -0,0 +1,1986 @@
+Summary
+
+Harness status: OK
+
+Rerun
+
+Found 1975 tests
+
+1903 Pass
+72 Fail
+Details
+Result	Test Name	MessagePass	Selectors-API Test Suite: HTML	
+Pass	Document supports querySelector	
+Pass	Document supports querySelectorAll	
+Pass	Document.querySelectorAll returns NodeList instance	
+Pass	Detached Element supports querySelector	
+Pass	Detached Element supports querySelectorAll	
+Pass	Detached Element.querySelectorAll returns NodeList instance	
+Pass	Fragment supports querySelector	
+Pass	Fragment supports querySelectorAll	
+Pass	Fragment.querySelectorAll returns NodeList instance	
+Pass	In-document Element supports querySelector	
+Pass	In-document Element supports querySelectorAll	
+Pass	In-document Element.querySelectorAll returns NodeList instance	
+Pass	Document.querySelectorAll null	
+Pass	Document.querySelectorAll undefined	
+Pass	Document.querySelectorAll no parameter	
+Pass	Document.querySelector null	
+Pass	Document.querySelector undefined	
+Pass	Document.querySelector no parameter	
+Pass	Document.querySelectorAll tree order	
+Pass	Detached Element.querySelectorAll null	
+Pass	Detached Element.querySelectorAll undefined	
+Pass	Detached Element.querySelectorAll no parameter	
+Pass	Detached Element.querySelector null	
+Pass	Detached Element.querySelector undefined	
+Pass	Detached Element.querySelector no parameter	
+Pass	Detached Element.querySelectorAll tree order	
+Pass	Fragment.querySelectorAll null	
+Pass	Fragment.querySelectorAll undefined	
+Pass	Fragment.querySelectorAll no parameter	
+Pass	Fragment.querySelector null	
+Pass	Fragment.querySelector undefined	
+Pass	Fragment.querySelector no parameter	
+Pass	Fragment.querySelectorAll tree order	
+Pass	In-document Element.querySelectorAll null	
+Pass	In-document Element.querySelectorAll undefined	
+Pass	In-document Element.querySelectorAll no parameter	
+Pass	In-document Element.querySelector null	
+Pass	In-document Element.querySelector undefined	
+Pass	In-document Element.querySelector no parameter	
+Pass	In-document Element.querySelectorAll tree order	
+Pass	Document: static NodeList	
+Pass	Document: new NodeList	
+Pass	Detached Element: static NodeList	
+Pass	Detached Element: new NodeList	
+Pass	Fragment: static NodeList	
+Pass	Fragment: new NodeList	
+Pass	In-document Element: static NodeList	
+Pass	In-document Element: new NodeList	
+Pass	Document.querySelector: Empty String: 	
+Pass	Document.querySelectorAll: Empty String: 	
+Pass	Document.querySelector: Invalid character: [	
+Pass	Document.querySelectorAll: Invalid character: [	
+Pass	Document.querySelector: Invalid character: ]	
+Pass	Document.querySelectorAll: Invalid character: ]	
+Pass	Document.querySelector: Invalid character: (	
+Pass	Document.querySelectorAll: Invalid character: (	
+Pass	Document.querySelector: Invalid character: )	
+Pass	Document.querySelectorAll: Invalid character: )	
+Pass	Document.querySelector: Invalid character: {	
+Pass	Document.querySelectorAll: Invalid character: {	
+Pass	Document.querySelector: Invalid character: }	
+Pass	Document.querySelectorAll: Invalid character: }	
+Pass	Document.querySelector: Invalid character: <	
+Pass	Document.querySelectorAll: Invalid character: <	
+Pass	Document.querySelector: Invalid character: >	
+Pass	Document.querySelectorAll: Invalid character: >	
+Pass	Document.querySelector: Invalid ID: #	
+Pass	Document.querySelectorAll: Invalid ID: #	
+Pass	Document.querySelector: Invalid group of selectors: div,	
+Pass	Document.querySelectorAll: Invalid group of selectors: div,	
+Pass	Document.querySelector: Invalid class: .	
+Pass	Document.querySelectorAll: Invalid class: .	
+Pass	Document.querySelector: Invalid class: .5cm	
+Pass	Document.querySelectorAll: Invalid class: .5cm	
+Pass	Document.querySelector: Invalid class: ..test	
+Pass	Document.querySelectorAll: Invalid class: ..test	
+Pass	Document.querySelector: Invalid class: .foo..quux	
+Pass	Document.querySelectorAll: Invalid class: .foo..quux	
+Pass	Document.querySelector: Invalid class: .bar.	
+Pass	Document.querySelectorAll: Invalid class: .bar.	
+Pass	Document.querySelector: Invalid combinator: div % address, p	
+Pass	Document.querySelectorAll: Invalid combinator: div % address, p	
+Fail	Document.querySelector: Invalid combinator: div ++ address, p	
+Fail	Document.querySelectorAll: Invalid combinator: div ++ address, p	
+Fail	Document.querySelector: Invalid combinator: div ~~ address, p	
+Fail	Document.querySelectorAll: Invalid combinator: div ~~ address, p	
+Pass	Document.querySelector: Invalid [att=value] selector: [*=test]	
+Pass	Document.querySelectorAll: Invalid [att=value] selector: [*=test]	
+Pass	Document.querySelector: Invalid [att=value] selector: [*|*=test]	
+Pass	Document.querySelectorAll: Invalid [att=value] selector: [*|*=test]	
+Pass	Document.querySelector: Invalid [att=value] selector: [class= space unquoted ]	
+Pass	Document.querySelectorAll: Invalid [att=value] selector: [class= space unquoted ]	
+Pass	Document.querySelector: Unknown pseudo-class: div:example	
+Pass	Document.querySelectorAll: Unknown pseudo-class: div:example	
+Pass	Document.querySelector: Unknown pseudo-class: :example	
+Pass	Document.querySelectorAll: Unknown pseudo-class: :example	
+Pass	Document.querySelector: Unknown pseudo-class: div:linkexample	
+Pass	Document.querySelectorAll: Unknown pseudo-class: div:linkexample	
+Pass	Document.querySelector: Unknown pseudo-element: div::example	
+Pass	Document.querySelectorAll: Unknown pseudo-element: div::example	
+Pass	Document.querySelector: Unknown pseudo-element: ::example	
+Pass	Document.querySelectorAll: Unknown pseudo-element: ::example	
+Pass	Document.querySelector: Invalid pseudo-element: :::before	
+Pass	Document.querySelectorAll: Invalid pseudo-element: :::before	
+Pass	Document.querySelector: Invalid pseudo-element: :: before	
+Pass	Document.querySelectorAll: Invalid pseudo-element: :: before	
+Fail	Document.querySelector: Undeclared namespace: ns|div	
+Fail	Document.querySelectorAll: Undeclared namespace: ns|div	
+Fail	Document.querySelector: Undeclared namespace: :not(ns|div)	
+Fail	Document.querySelectorAll: Undeclared namespace: :not(ns|div)	
+Pass	Document.querySelector: Invalid namespace: ^|div	
+Pass	Document.querySelectorAll: Invalid namespace: ^|div	
+Pass	Document.querySelector: Invalid namespace: $|div	
+Pass	Document.querySelectorAll: Invalid namespace: $|div	
+Pass	Document.querySelector: Relative selector: >*	
+Pass	Document.querySelectorAll: Relative selector: >*	
+Pass	Detached Element.querySelector: Empty String: 	
+Pass	Detached Element.querySelectorAll: Empty String: 	
+Pass	Detached Element.querySelector: Invalid character: [	
+Pass	Detached Element.querySelectorAll: Invalid character: [	
+Pass	Detached Element.querySelector: Invalid character: ]	
+Pass	Detached Element.querySelectorAll: Invalid character: ]	
+Pass	Detached Element.querySelector: Invalid character: (	
+Pass	Detached Element.querySelectorAll: Invalid character: (	
+Pass	Detached Element.querySelector: Invalid character: )	
+Pass	Detached Element.querySelectorAll: Invalid character: )	
+Pass	Detached Element.querySelector: Invalid character: {	
+Pass	Detached Element.querySelectorAll: Invalid character: {	
+Pass	Detached Element.querySelector: Invalid character: }	
+Pass	Detached Element.querySelectorAll: Invalid character: }	
+Pass	Detached Element.querySelector: Invalid character: <	
+Pass	Detached Element.querySelectorAll: Invalid character: <	
+Pass	Detached Element.querySelector: Invalid character: >	
+Pass	Detached Element.querySelectorAll: Invalid character: >	
+Pass	Detached Element.querySelector: Invalid ID: #	
+Pass	Detached Element.querySelectorAll: Invalid ID: #	
+Pass	Detached Element.querySelector: Invalid group of selectors: div,	
+Pass	Detached Element.querySelectorAll: Invalid group of selectors: div,	
+Pass	Detached Element.querySelector: Invalid class: .	
+Pass	Detached Element.querySelectorAll: Invalid class: .	
+Pass	Detached Element.querySelector: Invalid class: .5cm	
+Pass	Detached Element.querySelectorAll: Invalid class: .5cm	
+Pass	Detached Element.querySelector: Invalid class: ..test	
+Pass	Detached Element.querySelectorAll: Invalid class: ..test	
+Pass	Detached Element.querySelector: Invalid class: .foo..quux	
+Pass	Detached Element.querySelectorAll: Invalid class: .foo..quux	
+Pass	Detached Element.querySelector: Invalid class: .bar.	
+Pass	Detached Element.querySelectorAll: Invalid class: .bar.	
+Pass	Detached Element.querySelector: Invalid combinator: div % address, p	
+Pass	Detached Element.querySelectorAll: Invalid combinator: div % address, p	
+Fail	Detached Element.querySelector: Invalid combinator: div ++ address, p	
+Fail	Detached Element.querySelectorAll: Invalid combinator: div ++ address, p	
+Fail	Detached Element.querySelector: Invalid combinator: div ~~ address, p	
+Fail	Detached Element.querySelectorAll: Invalid combinator: div ~~ address, p	
+Pass	Detached Element.querySelector: Invalid [att=value] selector: [*=test]	
+Pass	Detached Element.querySelectorAll: Invalid [att=value] selector: [*=test]	
+Pass	Detached Element.querySelector: Invalid [att=value] selector: [*|*=test]	
+Pass	Detached Element.querySelectorAll: Invalid [att=value] selector: [*|*=test]	
+Pass	Detached Element.querySelector: Invalid [att=value] selector: [class= space unquoted ]	
+Pass	Detached Element.querySelectorAll: Invalid [att=value] selector: [class= space unquoted ]	
+Pass	Detached Element.querySelector: Unknown pseudo-class: div:example	
+Pass	Detached Element.querySelectorAll: Unknown pseudo-class: div:example	
+Pass	Detached Element.querySelector: Unknown pseudo-class: :example	
+Pass	Detached Element.querySelectorAll: Unknown pseudo-class: :example	
+Pass	Detached Element.querySelector: Unknown pseudo-class: div:linkexample	
+Pass	Detached Element.querySelectorAll: Unknown pseudo-class: div:linkexample	
+Pass	Detached Element.querySelector: Unknown pseudo-element: div::example	
+Pass	Detached Element.querySelectorAll: Unknown pseudo-element: div::example	
+Pass	Detached Element.querySelector: Unknown pseudo-element: ::example	
+Pass	Detached Element.querySelectorAll: Unknown pseudo-element: ::example	
+Pass	Detached Element.querySelector: Invalid pseudo-element: :::before	
+Pass	Detached Element.querySelectorAll: Invalid pseudo-element: :::before	
+Pass	Detached Element.querySelector: Invalid pseudo-element: :: before	
+Pass	Detached Element.querySelectorAll: Invalid pseudo-element: :: before	
+Fail	Detached Element.querySelector: Undeclared namespace: ns|div	
+Fail	Detached Element.querySelectorAll: Undeclared namespace: ns|div	
+Fail	Detached Element.querySelector: Undeclared namespace: :not(ns|div)	
+Fail	Detached Element.querySelectorAll: Undeclared namespace: :not(ns|div)	
+Pass	Detached Element.querySelector: Invalid namespace: ^|div	
+Pass	Detached Element.querySelectorAll: Invalid namespace: ^|div	
+Pass	Detached Element.querySelector: Invalid namespace: $|div	
+Pass	Detached Element.querySelectorAll: Invalid namespace: $|div	
+Pass	Detached Element.querySelector: Relative selector: >*	
+Pass	Detached Element.querySelectorAll: Relative selector: >*	
+Pass	Fragment.querySelector: Empty String: 	
+Pass	Fragment.querySelectorAll: Empty String: 	
+Pass	Fragment.querySelector: Invalid character: [	
+Pass	Fragment.querySelectorAll: Invalid character: [	
+Pass	Fragment.querySelector: Invalid character: ]	
+Pass	Fragment.querySelectorAll: Invalid character: ]	
+Pass	Fragment.querySelector: Invalid character: (	
+Pass	Fragment.querySelectorAll: Invalid character: (	
+Pass	Fragment.querySelector: Invalid character: )	
+Pass	Fragment.querySelectorAll: Invalid character: )	
+Pass	Fragment.querySelector: Invalid character: {	
+Pass	Fragment.querySelectorAll: Invalid character: {	
+Pass	Fragment.querySelector: Invalid character: }	
+Pass	Fragment.querySelectorAll: Invalid character: }	
+Pass	Fragment.querySelector: Invalid character: <	
+Pass	Fragment.querySelectorAll: Invalid character: <	
+Pass	Fragment.querySelector: Invalid character: >	
+Pass	Fragment.querySelectorAll: Invalid character: >	
+Pass	Fragment.querySelector: Invalid ID: #	
+Pass	Fragment.querySelectorAll: Invalid ID: #	
+Pass	Fragment.querySelector: Invalid group of selectors: div,	
+Pass	Fragment.querySelectorAll: Invalid group of selectors: div,	
+Pass	Fragment.querySelector: Invalid class: .	
+Pass	Fragment.querySelectorAll: Invalid class: .	
+Pass	Fragment.querySelector: Invalid class: .5cm	
+Pass	Fragment.querySelectorAll: Invalid class: .5cm	
+Pass	Fragment.querySelector: Invalid class: ..test	
+Pass	Fragment.querySelectorAll: Invalid class: ..test	
+Pass	Fragment.querySelector: Invalid class: .foo..quux	
+Pass	Fragment.querySelectorAll: Invalid class: .foo..quux	
+Pass	Fragment.querySelector: Invalid class: .bar.	
+Pass	Fragment.querySelectorAll: Invalid class: .bar.	
+Pass	Fragment.querySelector: Invalid combinator: div % address, p	
+Pass	Fragment.querySelectorAll: Invalid combinator: div % address, p	
+Fail	Fragment.querySelector: Invalid combinator: div ++ address, p	
+Fail	Fragment.querySelectorAll: Invalid combinator: div ++ address, p	
+Fail	Fragment.querySelector: Invalid combinator: div ~~ address, p	
+Fail	Fragment.querySelectorAll: Invalid combinator: div ~~ address, p	
+Pass	Fragment.querySelector: Invalid [att=value] selector: [*=test]	
+Pass	Fragment.querySelectorAll: Invalid [att=value] selector: [*=test]	
+Pass	Fragment.querySelector: Invalid [att=value] selector: [*|*=test]	
+Pass	Fragment.querySelectorAll: Invalid [att=value] selector: [*|*=test]	
+Pass	Fragment.querySelector: Invalid [att=value] selector: [class= space unquoted ]	
+Pass	Fragment.querySelectorAll: Invalid [att=value] selector: [class= space unquoted ]	
+Pass	Fragment.querySelector: Unknown pseudo-class: div:example	
+Pass	Fragment.querySelectorAll: Unknown pseudo-class: div:example	
+Pass	Fragment.querySelector: Unknown pseudo-class: :example	
+Pass	Fragment.querySelectorAll: Unknown pseudo-class: :example	
+Pass	Fragment.querySelector: Unknown pseudo-class: div:linkexample	
+Pass	Fragment.querySelectorAll: Unknown pseudo-class: div:linkexample	
+Pass	Fragment.querySelector: Unknown pseudo-element: div::example	
+Pass	Fragment.querySelectorAll: Unknown pseudo-element: div::example	
+Pass	Fragment.querySelector: Unknown pseudo-element: ::example	
+Pass	Fragment.querySelectorAll: Unknown pseudo-element: ::example	
+Pass	Fragment.querySelector: Invalid pseudo-element: :::before	
+Pass	Fragment.querySelectorAll: Invalid pseudo-element: :::before	
+Pass	Fragment.querySelector: Invalid pseudo-element: :: before	
+Pass	Fragment.querySelectorAll: Invalid pseudo-element: :: before	
+Fail	Fragment.querySelector: Undeclared namespace: ns|div	
+Fail	Fragment.querySelectorAll: Undeclared namespace: ns|div	
+Fail	Fragment.querySelector: Undeclared namespace: :not(ns|div)	
+Fail	Fragment.querySelectorAll: Undeclared namespace: :not(ns|div)	
+Pass	Fragment.querySelector: Invalid namespace: ^|div	
+Pass	Fragment.querySelectorAll: Invalid namespace: ^|div	
+Pass	Fragment.querySelector: Invalid namespace: $|div	
+Pass	Fragment.querySelectorAll: Invalid namespace: $|div	
+Pass	Fragment.querySelector: Relative selector: >*	
+Pass	Fragment.querySelectorAll: Relative selector: >*	
+Pass	In-document Element.querySelector: Empty String: 	
+Pass	In-document Element.querySelectorAll: Empty String: 	
+Pass	In-document Element.querySelector: Invalid character: [	
+Pass	In-document Element.querySelectorAll: Invalid character: [	
+Pass	In-document Element.querySelector: Invalid character: ]	
+Pass	In-document Element.querySelectorAll: Invalid character: ]	
+Pass	In-document Element.querySelector: Invalid character: (	
+Pass	In-document Element.querySelectorAll: Invalid character: (	
+Pass	In-document Element.querySelector: Invalid character: )	
+Pass	In-document Element.querySelectorAll: Invalid character: )	
+Pass	In-document Element.querySelector: Invalid character: {	
+Pass	In-document Element.querySelectorAll: Invalid character: {	
+Pass	In-document Element.querySelector: Invalid character: }	
+Pass	In-document Element.querySelectorAll: Invalid character: }	
+Pass	In-document Element.querySelector: Invalid character: <	
+Pass	In-document Element.querySelectorAll: Invalid character: <	
+Pass	In-document Element.querySelector: Invalid character: >	
+Pass	In-document Element.querySelectorAll: Invalid character: >	
+Pass	In-document Element.querySelector: Invalid ID: #	
+Pass	In-document Element.querySelectorAll: Invalid ID: #	
+Pass	In-document Element.querySelector: Invalid group of selectors: div,	
+Pass	In-document Element.querySelectorAll: Invalid group of selectors: div,	
+Pass	In-document Element.querySelector: Invalid class: .	
+Pass	In-document Element.querySelectorAll: Invalid class: .	
+Pass	In-document Element.querySelector: Invalid class: .5cm	
+Pass	In-document Element.querySelectorAll: Invalid class: .5cm	
+Pass	In-document Element.querySelector: Invalid class: ..test	
+Pass	In-document Element.querySelectorAll: Invalid class: ..test	
+Pass	In-document Element.querySelector: Invalid class: .foo..quux	
+Pass	In-document Element.querySelectorAll: Invalid class: .foo..quux	
+Pass	In-document Element.querySelector: Invalid class: .bar.	
+Pass	In-document Element.querySelectorAll: Invalid class: .bar.	
+Pass	In-document Element.querySelector: Invalid combinator: div % address, p	
+Pass	In-document Element.querySelectorAll: Invalid combinator: div % address, p	
+Fail	In-document Element.querySelector: Invalid combinator: div ++ address, p	
+Fail	In-document Element.querySelectorAll: Invalid combinator: div ++ address, p	
+Fail	In-document Element.querySelector: Invalid combinator: div ~~ address, p	
+Fail	In-document Element.querySelectorAll: Invalid combinator: div ~~ address, p	
+Pass	In-document Element.querySelector: Invalid [att=value] selector: [*=test]	
+Pass	In-document Element.querySelectorAll: Invalid [att=value] selector: [*=test]	
+Pass	In-document Element.querySelector: Invalid [att=value] selector: [*|*=test]	
+Pass	In-document Element.querySelectorAll: Invalid [att=value] selector: [*|*=test]	
+Pass	In-document Element.querySelector: Invalid [att=value] selector: [class= space unquoted ]	
+Pass	In-document Element.querySelectorAll: Invalid [att=value] selector: [class= space unquoted ]	
+Pass	In-document Element.querySelector: Unknown pseudo-class: div:example	
+Pass	In-document Element.querySelectorAll: Unknown pseudo-class: div:example	
+Pass	In-document Element.querySelector: Unknown pseudo-class: :example	
+Pass	In-document Element.querySelectorAll: Unknown pseudo-class: :example	
+Pass	In-document Element.querySelector: Unknown pseudo-class: div:linkexample	
+Pass	In-document Element.querySelectorAll: Unknown pseudo-class: div:linkexample	
+Pass	In-document Element.querySelector: Unknown pseudo-element: div::example	
+Pass	In-document Element.querySelectorAll: Unknown pseudo-element: div::example	
+Pass	In-document Element.querySelector: Unknown pseudo-element: ::example	
+Pass	In-document Element.querySelectorAll: Unknown pseudo-element: ::example	
+Pass	In-document Element.querySelector: Invalid pseudo-element: :::before	
+Pass	In-document Element.querySelectorAll: Invalid pseudo-element: :::before	
+Pass	In-document Element.querySelector: Invalid pseudo-element: :: before	
+Pass	In-document Element.querySelectorAll: Invalid pseudo-element: :: before	
+Fail	In-document Element.querySelector: Undeclared namespace: ns|div	
+Fail	In-document Element.querySelectorAll: Undeclared namespace: ns|div	
+Fail	In-document Element.querySelector: Undeclared namespace: :not(ns|div)	
+Fail	In-document Element.querySelectorAll: Undeclared namespace: :not(ns|div)	
+Pass	In-document Element.querySelector: Invalid namespace: ^|div	
+Pass	In-document Element.querySelectorAll: Invalid namespace: ^|div	
+Pass	In-document Element.querySelector: Invalid namespace: $|div	
+Pass	In-document Element.querySelectorAll: Invalid namespace: $|div	
+Pass	In-document Element.querySelector: Relative selector: >*	
+Pass	In-document Element.querySelectorAll: Relative selector: >*	
+Pass	Empty Element.querySelector: Empty String: 	
+Pass	Empty Element.querySelectorAll: Empty String: 	
+Pass	Empty Element.querySelector: Invalid character: [	
+Pass	Empty Element.querySelectorAll: Invalid character: [	
+Pass	Empty Element.querySelector: Invalid character: ]	
+Pass	Empty Element.querySelectorAll: Invalid character: ]	
+Pass	Empty Element.querySelector: Invalid character: (	
+Pass	Empty Element.querySelectorAll: Invalid character: (	
+Pass	Empty Element.querySelector: Invalid character: )	
+Pass	Empty Element.querySelectorAll: Invalid character: )	
+Pass	Empty Element.querySelector: Invalid character: {	
+Pass	Empty Element.querySelectorAll: Invalid character: {	
+Pass	Empty Element.querySelector: Invalid character: }	
+Pass	Empty Element.querySelectorAll: Invalid character: }	
+Pass	Empty Element.querySelector: Invalid character: <	
+Pass	Empty Element.querySelectorAll: Invalid character: <	
+Pass	Empty Element.querySelector: Invalid character: >	
+Pass	Empty Element.querySelectorAll: Invalid character: >	
+Pass	Empty Element.querySelector: Invalid ID: #	
+Pass	Empty Element.querySelectorAll: Invalid ID: #	
+Pass	Empty Element.querySelector: Invalid group of selectors: div,	
+Pass	Empty Element.querySelectorAll: Invalid group of selectors: div,	
+Pass	Empty Element.querySelector: Invalid class: .	
+Pass	Empty Element.querySelectorAll: Invalid class: .	
+Pass	Empty Element.querySelector: Invalid class: .5cm	
+Pass	Empty Element.querySelectorAll: Invalid class: .5cm	
+Pass	Empty Element.querySelector: Invalid class: ..test	
+Pass	Empty Element.querySelectorAll: Invalid class: ..test	
+Pass	Empty Element.querySelector: Invalid class: .foo..quux	
+Pass	Empty Element.querySelectorAll: Invalid class: .foo..quux	
+Pass	Empty Element.querySelector: Invalid class: .bar.	
+Pass	Empty Element.querySelectorAll: Invalid class: .bar.	
+Pass	Empty Element.querySelector: Invalid combinator: div % address, p	
+Pass	Empty Element.querySelectorAll: Invalid combinator: div % address, p	
+Fail	Empty Element.querySelector: Invalid combinator: div ++ address, p	
+Fail	Empty Element.querySelectorAll: Invalid combinator: div ++ address, p	
+Fail	Empty Element.querySelector: Invalid combinator: div ~~ address, p	
+Fail	Empty Element.querySelectorAll: Invalid combinator: div ~~ address, p	
+Pass	Empty Element.querySelector: Invalid [att=value] selector: [*=test]	
+Pass	Empty Element.querySelectorAll: Invalid [att=value] selector: [*=test]	
+Pass	Empty Element.querySelector: Invalid [att=value] selector: [*|*=test]	
+Pass	Empty Element.querySelectorAll: Invalid [att=value] selector: [*|*=test]	
+Pass	Empty Element.querySelector: Invalid [att=value] selector: [class= space unquoted ]	
+Pass	Empty Element.querySelectorAll: Invalid [att=value] selector: [class= space unquoted ]	
+Pass	Empty Element.querySelector: Unknown pseudo-class: div:example	
+Pass	Empty Element.querySelectorAll: Unknown pseudo-class: div:example	
+Pass	Empty Element.querySelector: Unknown pseudo-class: :example	
+Pass	Empty Element.querySelectorAll: Unknown pseudo-class: :example	
+Pass	Empty Element.querySelector: Unknown pseudo-class: div:linkexample	
+Pass	Empty Element.querySelectorAll: Unknown pseudo-class: div:linkexample	
+Pass	Empty Element.querySelector: Unknown pseudo-element: div::example	
+Pass	Empty Element.querySelectorAll: Unknown pseudo-element: div::example	
+Pass	Empty Element.querySelector: Unknown pseudo-element: ::example	
+Pass	Empty Element.querySelectorAll: Unknown pseudo-element: ::example	
+Pass	Empty Element.querySelector: Invalid pseudo-element: :::before	
+Pass	Empty Element.querySelectorAll: Invalid pseudo-element: :::before	
+Pass	Empty Element.querySelector: Invalid pseudo-element: :: before	
+Pass	Empty Element.querySelectorAll: Invalid pseudo-element: :: before	
+Fail	Empty Element.querySelector: Undeclared namespace: ns|div	
+Fail	Empty Element.querySelectorAll: Undeclared namespace: ns|div	
+Fail	Empty Element.querySelector: Undeclared namespace: :not(ns|div)	
+Fail	Empty Element.querySelectorAll: Undeclared namespace: :not(ns|div)	
+Pass	Empty Element.querySelector: Invalid namespace: ^|div	
+Pass	Empty Element.querySelectorAll: Invalid namespace: ^|div	
+Pass	Empty Element.querySelector: Invalid namespace: $|div	
+Pass	Empty Element.querySelectorAll: Invalid namespace: $|div	
+Pass	Empty Element.querySelector: Relative selector: >*	
+Pass	Empty Element.querySelectorAll: Relative selector: >*	
+Pass	Document.querySelectorAll: Type selector, matching html element: html	
+Pass	Document.querySelector: Type selector, matching html element: html	
+Pass	Document.querySelectorAll: Type selector, matching body element: body	
+Pass	Document.querySelector: Type selector, matching body element: body	
+Pass	Document.querySelectorAll: Universal selector, matching all children of element with specified ID: #universal>*	
+Pass	Document.querySelector: Universal selector, matching all children of element with specified ID: #universal>*	
+Pass	Document.querySelectorAll: Universal selector, matching all grandchildren of element with specified ID: #universal>*>*	
+Pass	Document.querySelector: Universal selector, matching all grandchildren of element with specified ID: #universal>*>*	
+Pass	Document.querySelectorAll: Universal selector, matching all children of empty element with specified ID: #empty>*	
+Pass	Document.querySelector: Universal selector, matching all children of empty element with specified ID: #empty>*	
+Pass	Document.querySelectorAll: Universal selector, matching all descendants of element with specified ID: #universal *	
+Pass	Document.querySelector: Universal selector, matching all descendants of element with specified ID: #universal *	
+Pass	Document.querySelectorAll: Attribute presence selector, matching align attribute with value: .attr-presence-div1[align]	
+Pass	Document.querySelector: Attribute presence selector, matching align attribute with value: .attr-presence-div1[align]	
+Pass	Document.querySelectorAll: Attribute presence selector, matching align attribute with empty value: .attr-presence-div2[align]	
+Pass	Document.querySelector: Attribute presence selector, matching align attribute with empty value: .attr-presence-div2[align]	
+Fail	Document.querySelectorAll: Attribute presence selector, matching title attribute, case insensitivity: #attr-presence [*|TiTlE]	
+Fail	Document.querySelector: Attribute presence selector, matching title attribute, case insensitivity: #attr-presence [*|TiTlE]	
+Pass	Document.querySelectorAll: Attribute presence selector, matching custom data-* attribute: [data-attr-presence]	
+Pass	Document.querySelector: Attribute presence selector, matching custom data-* attribute: [data-attr-presence]	
+Pass	Document.querySelectorAll: Attribute presence selector, not matching attribute with similar name: .attr-presence-div3[align], .attr-presence-div4[align]	
+Pass	Document.querySelector: Attribute presence selector, not matching attribute with similar name: .attr-presence-div3[align], .attr-presence-div4[align]	
+Pass	Document.querySelectorAll: Attribute presence selector, matching attribute with non-ASCII characters: ul[data-中文]	
+Pass	Document.querySelector: Attribute presence selector, matching attribute with non-ASCII characters: ul[data-中文]	
+Pass	Document.querySelectorAll: Attribute presence selector, not matching default option without selected attribute: #attr-presence-select1 option[selected]	
+Pass	Document.querySelector: Attribute presence selector, not matching default option without selected attribute: #attr-presence-select1 option[selected]	
+Pass	Document.querySelectorAll: Attribute presence selector, matching option with selected attribute: #attr-presence-select2 option[selected]	
+Pass	Document.querySelector: Attribute presence selector, matching option with selected attribute: #attr-presence-select2 option[selected]	
+Pass	Document.querySelectorAll: Attribute presence selector, matching multiple options with selected attributes: #attr-presence-select3 option[selected]	
+Pass	Document.querySelector: Attribute presence selector, matching multiple options with selected attributes: #attr-presence-select3 option[selected]	
+Pass	Document.querySelectorAll: Attribute value selector, matching align attribute with value: #attr-value [align="center"]	
+Pass	Document.querySelector: Attribute value selector, matching align attribute with value: #attr-value [align="center"]	
+Pass	Document.querySelectorAll: Attribute value selector, matching align attribute with value, unclosed bracket: #attr-value [align="center"	
+Pass	Document.querySelector: Attribute value selector, matching align attribute with value, unclosed bracket: #attr-value [align="center"	
+Pass	Document.querySelectorAll: Attribute value selector, matching align attribute with empty value: #attr-value [align=""]	
+Pass	Document.querySelector: Attribute value selector, matching align attribute with empty value: #attr-value [align=""]	
+Pass	Document.querySelectorAll: Attribute value selector, not matching align attribute with partial value: #attr-value [align="c"]	
+Pass	Document.querySelector: Attribute value selector, not matching align attribute with partial value: #attr-value [align="c"]	
+Pass	Document.querySelectorAll: Attribute value selector, not matching align attribute with incorrect value: #attr-value [align="centera"]	
+Pass	Document.querySelector: Attribute value selector, not matching align attribute with incorrect value: #attr-value [align="centera"]	
+Pass	Document.querySelectorAll: Attribute value selector, matching custom data-* attribute with unicode escaped value: [data-attr-value="\e9"]	
+Pass	Document.querySelector: Attribute value selector, matching custom data-* attribute with unicode escaped value: [data-attr-value="\e9"]	
+Pass	Document.querySelectorAll: Attribute value selector, matching custom data-* attribute with escaped character: [data-attr-value_foo="\e9"]	
+Pass	Document.querySelector: Attribute value selector, matching custom data-* attribute with escaped character: [data-attr-value_foo="\e9"]	
+Pass	Document.querySelectorAll: Attribute value selector with single-quoted value, matching multiple inputs with type attributes: #attr-value input[type='hidden'],#attr-value input[type='radio']	
+Pass	Document.querySelector: Attribute value selector with single-quoted value, matching multiple inputs with type attributes: #attr-value input[type='hidden'],#attr-value input[type='radio']	
+Pass	Document.querySelectorAll: Attribute value selector with double-quoted value, matching multiple inputs with type attributes: #attr-value input[type="hidden"],#attr-value input[type='radio']	
+Pass	Document.querySelector: Attribute value selector with double-quoted value, matching multiple inputs with type attributes: #attr-value input[type="hidden"],#attr-value input[type='radio']	
+Pass	Document.querySelectorAll: Attribute value selector with unquoted value, matching multiple inputs with type attributes: #attr-value input[type=hidden],#attr-value input[type=radio]	
+Pass	Document.querySelector: Attribute value selector with unquoted value, matching multiple inputs with type attributes: #attr-value input[type=hidden],#attr-value input[type=radio]	
+Pass	Document.querySelectorAll: Attribute value selector, matching attribute with value using non-ASCII characters: [data-attr-value=中文]	
+Pass	Document.querySelector: Attribute value selector, matching attribute with value using non-ASCII characters: [data-attr-value=中文]	
+Pass	Document.querySelectorAll: Attribute whitespace-separated list selector, matching class attribute with value: #attr-whitespace [class~="div1"]	
+Pass	Document.querySelector: Attribute whitespace-separated list selector, matching class attribute with value: #attr-whitespace [class~="div1"]	
+Pass	Document.querySelectorAll: Attribute whitespace-separated list selector, not matching class attribute with empty value: #attr-whitespace [class~=""]	
+Pass	Document.querySelector: Attribute whitespace-separated list selector, not matching class attribute with empty value: #attr-whitespace [class~=""]	
+Pass	Document.querySelectorAll: Attribute whitespace-separated list selector, not matching class attribute with partial value: [data-attr-whitespace~="div"]	
+Pass	Document.querySelector: Attribute whitespace-separated list selector, not matching class attribute with partial value: [data-attr-whitespace~="div"]	
+Pass	Document.querySelectorAll: Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value: [data-attr-whitespace~="\0000e9"]	
+Pass	Document.querySelector: Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value: [data-attr-whitespace~="\0000e9"]	
+Pass	Document.querySelectorAll: Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character: [data-attr-whitespace_foo~="\e9"]	
+Pass	Document.querySelector: Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character: [data-attr-whitespace_foo~="\e9"]	
+Pass	Document.querySelectorAll: Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~='bookmark'], #attr-whitespace a[rel~='nofollow']	
+Pass	Document.querySelector: Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~='bookmark'], #attr-whitespace a[rel~='nofollow']	
+Pass	Document.querySelectorAll: Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~="bookmark"],#attr-whitespace a[rel~='nofollow']	
+Pass	Document.querySelector: Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~="bookmark"],#attr-whitespace a[rel~='nofollow']	
+Pass	Document.querySelectorAll: Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~=bookmark], #attr-whitespace a[rel~=nofollow]	
+Pass	Document.querySelector: Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~=bookmark], #attr-whitespace a[rel~=nofollow]	
+Pass	Document.querySelectorAll: Attribute whitespace-separated list selector with double-quoted value, not matching value with space: #attr-whitespace a[rel~="book mark"]	
+Pass	Document.querySelector: Attribute whitespace-separated list selector with double-quoted value, not matching value with space: #attr-whitespace a[rel~="book mark"]	
+Pass	Document.querySelectorAll: Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters: #attr-whitespace [title~=中文]	
+Pass	Document.querySelector: Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters: #attr-whitespace [title~=中文]	
+Pass	Document.querySelectorAll: Attribute hyphen-separated list selector, not matching unspecified lang attribute: #attr-hyphen-div1[lang|="en"]	
+Pass	Document.querySelector: Attribute hyphen-separated list selector, not matching unspecified lang attribute: #attr-hyphen-div1[lang|="en"]	
+Pass	Document.querySelectorAll: Attribute hyphen-separated list selector, matching lang attribute with exact value: #attr-hyphen-div2[lang|="fr"]	
+Pass	Document.querySelector: Attribute hyphen-separated list selector, matching lang attribute with exact value: #attr-hyphen-div2[lang|="fr"]	
+Pass	Document.querySelectorAll: Attribute hyphen-separated list selector, matching lang attribute with partial value: #attr-hyphen-div3[lang|="en"]	
+Pass	Document.querySelector: Attribute hyphen-separated list selector, matching lang attribute with partial value: #attr-hyphen-div3[lang|="en"]	
+Pass	Document.querySelectorAll: Attribute hyphen-separated list selector, not matching incorrect value: #attr-hyphen-div4[lang|="es-AR"]	
+Pass	Document.querySelector: Attribute hyphen-separated list selector, not matching incorrect value: #attr-hyphen-div4[lang|="es-AR"]	
+Pass	Document.querySelectorAll: Attribute begins with selector, matching href attributes beginning with specified substring: #attr-begins a[href^="http://www"]	
+Pass	Document.querySelector: Attribute begins with selector, matching href attributes beginning with specified substring: #attr-begins a[href^="http://www"]	
+Pass	Document.querySelectorAll: Attribute begins with selector, matching lang attributes beginning with specified substring, : #attr-begins [lang^="en-"]	
+Pass	Document.querySelector: Attribute begins with selector, matching lang attributes beginning with specified substring, : #attr-begins [lang^="en-"]	
+Pass	Document.querySelectorAll: Attribute begins with selector, not matching class attribute with empty value: #attr-begins [class^=""]	
+Pass	Document.querySelector: Attribute begins with selector, not matching class attribute with empty value: #attr-begins [class^=""]	
+Pass	Document.querySelectorAll: Attribute begins with selector, not matching class attribute not beginning with specified substring: #attr-begins [class^=apple]	
+Pass	Document.querySelector: Attribute begins with selector, not matching class attribute not beginning with specified substring: #attr-begins [class^=apple]	
+Pass	Document.querySelectorAll: Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=' apple']	
+Pass	Document.querySelector: Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=' apple']	
+Pass	Document.querySelectorAll: Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=" apple"]	
+Pass	Document.querySelector: Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=" apple"]	
+Pass	Document.querySelectorAll: Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring: #attr-begins [class^= apple]	
+Pass	Document.querySelector: Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring: #attr-begins [class^= apple]	
+Pass	Document.querySelectorAll: Attribute ends with selector, matching href attributes ending with specified substring: #attr-ends a[href$=".org"]	
+Pass	Document.querySelector: Attribute ends with selector, matching href attributes ending with specified substring: #attr-ends a[href$=".org"]	
+Pass	Document.querySelectorAll: Attribute ends with selector, matching lang attributes ending with specified substring, : #attr-ends [lang$="-CH"]	
+Pass	Document.querySelector: Attribute ends with selector, matching lang attributes ending with specified substring, : #attr-ends [lang$="-CH"]	
+Pass	Document.querySelectorAll: Attribute ends with selector, not matching class attribute with empty value: #attr-ends [class$=""]	
+Pass	Document.querySelector: Attribute ends with selector, not matching class attribute with empty value: #attr-ends [class$=""]	
+Pass	Document.querySelectorAll: Attribute ends with selector, not matching class attribute not ending with specified substring: #attr-ends [class$=apple]	
+Pass	Document.querySelector: Attribute ends with selector, not matching class attribute not ending with specified substring: #attr-ends [class$=apple]	
+Pass	Document.querySelectorAll: Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring: #attr-ends [class$='apple ']	
+Pass	Document.querySelector: Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring: #attr-ends [class$='apple ']	
+Pass	Document.querySelectorAll: Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring: #attr-ends [class$="apple "]	
+Pass	Document.querySelector: Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring: #attr-ends [class$="apple "]	
+Pass	Document.querySelectorAll: Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring: #attr-ends [class$=apple ]	
+Pass	Document.querySelector: Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring: #attr-ends [class$=apple ]	
+Pass	Document.querySelectorAll: Attribute contains selector, matching href attributes beginning with specified substring: #attr-contains a[href*="http://www"]	
+Pass	Document.querySelector: Attribute contains selector, matching href attributes beginning with specified substring: #attr-contains a[href*="http://www"]	
+Pass	Document.querySelectorAll: Attribute contains selector, matching href attributes ending with specified substring: #attr-contains a[href*=".org"]	
+Pass	Document.querySelector: Attribute contains selector, matching href attributes ending with specified substring: #attr-contains a[href*=".org"]	
+Pass	Document.querySelectorAll: Attribute contains selector, matching href attributes containing specified substring: #attr-contains a[href*=".example."]	
+Pass	Document.querySelector: Attribute contains selector, matching href attributes containing specified substring: #attr-contains a[href*=".example."]	
+Pass	Document.querySelectorAll: Attribute contains selector, matching lang attributes beginning with specified substring, : #attr-contains [lang*="en-"]	
+Pass	Document.querySelector: Attribute contains selector, matching lang attributes beginning with specified substring, : #attr-contains [lang*="en-"]	
+Pass	Document.querySelectorAll: Attribute contains selector, matching lang attributes ending with specified substring, : #attr-contains [lang*="-CH"]	
+Pass	Document.querySelector: Attribute contains selector, matching lang attributes ending with specified substring, : #attr-contains [lang*="-CH"]	
+Pass	Document.querySelectorAll: Attribute contains selector, not matching class attribute with empty value: #attr-contains [class*=""]	
+Pass	Document.querySelector: Attribute contains selector, not matching class attribute with empty value: #attr-contains [class*=""]	
+Pass	Document.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=' apple']	
+Pass	Document.querySelector: Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=' apple']	
+Pass	Document.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute ending with specified substring: #attr-contains [class*='orange ']	
+Pass	Document.querySelector: Attribute contains selector with single-quoted value, matching class attribute ending with specified substring: #attr-contains [class*='orange ']	
+Pass	Document.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute containing specified substring: #attr-contains [class*='ple banana ora']	
+Pass	Document.querySelector: Attribute contains selector with single-quoted value, matching class attribute containing specified substring: #attr-contains [class*='ple banana ora']	
+Pass	Document.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=" apple"]	
+Pass	Document.querySelector: Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=" apple"]	
+Pass	Document.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute ending with specified substring: #attr-contains [class*="orange "]	
+Pass	Document.querySelector: Attribute contains selector with double-quoted value, matching class attribute ending with specified substring: #attr-contains [class*="orange "]	
+Pass	Document.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute containing specified substring: #attr-contains [class*="ple banana ora"]	
+Pass	Document.querySelector: Attribute contains selector with double-quoted value, matching class attribute containing specified substring: #attr-contains [class*="ple banana ora"]	
+Pass	Document.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute beginning with specified substring: #attr-contains [class*= apple]	
+Pass	Document.querySelector: Attribute contains selector with unquoted value, matching class attribute beginning with specified substring: #attr-contains [class*= apple]	
+Pass	Document.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute ending with specified substring: #attr-contains [class*=orange ]	
+Pass	Document.querySelector: Attribute contains selector with unquoted value, matching class attribute ending with specified substring: #attr-contains [class*=orange ]	
+Pass	Document.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute containing specified substring: #attr-contains [class*= banana ]	
+Pass	Document.querySelector: Attribute contains selector with unquoted value, matching class attribute containing specified substring: #attr-contains [class*= banana ]	
+Pass	Document.querySelectorAll: :root pseudo-class selector, matching document root element: :root	
+Pass	Document.querySelector: :root pseudo-class selector, matching document root element: :root	
+Pass	Document.querySelectorAll: :nth-child selector, matching the third child element: #pseudo-nth-table1 :nth-child(3)	
+Pass	Document.querySelector: :nth-child selector, matching the third child element: #pseudo-nth-table1 :nth-child(3)	
+Pass	Document.querySelectorAll: :nth-child selector, matching every third child element: #pseudo-nth li:nth-child(3n)	
+Pass	Document.querySelector: :nth-child selector, matching every third child element: #pseudo-nth li:nth-child(3n)	
+Pass	Document.querySelectorAll: :nth-child selector, matching every second child element, starting from the fourth: #pseudo-nth li:nth-child(2n+4)	
+Pass	Document.querySelector: :nth-child selector, matching every second child element, starting from the fourth: #pseudo-nth li:nth-child(2n+4)	
+Pass	Document.querySelectorAll: :nth-child selector, matching every fourth child element, starting from the third: #pseudo-nth-p1 :nth-child(4n-1)	
+Pass	Document.querySelector: :nth-child selector, matching every fourth child element, starting from the third: #pseudo-nth-p1 :nth-child(4n-1)	
+Pass	Document.querySelectorAll: :nth-last-child selector, matching the third last child element: #pseudo-nth-table1 :nth-last-child(3)	
+Pass	Document.querySelector: :nth-last-child selector, matching the third last child element: #pseudo-nth-table1 :nth-last-child(3)	
+Pass	Document.querySelectorAll: :nth-last-child selector, matching every third child element from the end: #pseudo-nth li:nth-last-child(3n)	
+Pass	Document.querySelector: :nth-last-child selector, matching every third child element from the end: #pseudo-nth li:nth-last-child(3n)	
+Pass	Document.querySelectorAll: :nth-last-child selector, matching every second child element from the end, starting from the fourth last: #pseudo-nth li:nth-last-child(2n+4)	
+Pass	Document.querySelector: :nth-last-child selector, matching every second child element from the end, starting from the fourth last: #pseudo-nth li:nth-last-child(2n+4)	
+Pass	Document.querySelectorAll: :nth-last-child selector, matching every fourth element from the end, starting from the third last: #pseudo-nth-p1 :nth-last-child(4n-1)	
+Pass	Document.querySelector: :nth-last-child selector, matching every fourth element from the end, starting from the third last: #pseudo-nth-p1 :nth-last-child(4n-1)	
+Pass	Document.querySelectorAll: :nth-of-type selector, matching the third em element: #pseudo-nth-p1 em:nth-of-type(3)	
+Pass	Document.querySelector: :nth-of-type selector, matching the third em element: #pseudo-nth-p1 em:nth-of-type(3)	
+Pass	Document.querySelectorAll: :nth-of-type selector, matching every second element of their type: #pseudo-nth-p1 :nth-of-type(2n)	
+Pass	Document.querySelector: :nth-of-type selector, matching every second element of their type: #pseudo-nth-p1 :nth-of-type(2n)	
+Pass	Document.querySelectorAll: :nth-of-type selector, matching every second elemetn of their type, starting from the first: #pseudo-nth-p1 span:nth-of-type(2n-1)	
+Pass	Document.querySelector: :nth-of-type selector, matching every second elemetn of their type, starting from the first: #pseudo-nth-p1 span:nth-of-type(2n-1)	
+Pass	Document.querySelectorAll: :nth-last-of-type selector, matching the third last em element: #pseudo-nth-p1 em:nth-last-of-type(3)	
+Pass	Document.querySelector: :nth-last-of-type selector, matching the third last em element: #pseudo-nth-p1 em:nth-last-of-type(3)	
+Pass	Document.querySelectorAll: :nth-last-of-type selector, matching every second last element of their type: #pseudo-nth-p1 :nth-last-of-type(2n)	
+Pass	Document.querySelector: :nth-last-of-type selector, matching every second last element of their type: #pseudo-nth-p1 :nth-last-of-type(2n)	
+Pass	Document.querySelectorAll: :nth-last-of-type selector, matching every second last element of their type, starting from the last: #pseudo-nth-p1 span:nth-last-of-type(2n-1)	
+Pass	Document.querySelector: :nth-last-of-type selector, matching every second last element of their type, starting from the last: #pseudo-nth-p1 span:nth-last-of-type(2n-1)	
+Pass	Document.querySelectorAll: :first-of-type selector, matching the first em element: #pseudo-nth-p1 em:first-of-type	
+Pass	Document.querySelector: :first-of-type selector, matching the first em element: #pseudo-nth-p1 em:first-of-type	
+Pass	Document.querySelectorAll: :first-of-type selector, matching the first of every type of element: #pseudo-nth-p1 :first-of-type	
+Pass	Document.querySelector: :first-of-type selector, matching the first of every type of element: #pseudo-nth-p1 :first-of-type	
+Pass	Document.querySelectorAll: :first-of-type selector, matching the first td element in each table row: #pseudo-nth-table1 tr :first-of-type	
+Pass	Document.querySelector: :first-of-type selector, matching the first td element in each table row: #pseudo-nth-table1 tr :first-of-type	
+Pass	Document.querySelectorAll: :last-of-type selector, matching the last em elemnet: #pseudo-nth-p1 em:last-of-type	
+Pass	Document.querySelector: :last-of-type selector, matching the last em elemnet: #pseudo-nth-p1 em:last-of-type	
+Pass	Document.querySelectorAll: :last-of-type selector, matching the last of every type of element: #pseudo-nth-p1 :last-of-type	
+Pass	Document.querySelector: :last-of-type selector, matching the last of every type of element: #pseudo-nth-p1 :last-of-type	
+Pass	Document.querySelectorAll: :last-of-type selector, matching the last td element in each table row: #pseudo-nth-table1 tr :last-of-type	
+Pass	Document.querySelector: :last-of-type selector, matching the last td element in each table row: #pseudo-nth-table1 tr :last-of-type	
+Pass	Document.querySelectorAll: :first-child pseudo-class selector, matching first child div element: #pseudo-first-child div:first-child	
+Pass	Document.querySelector: :first-child pseudo-class selector, matching first child div element: #pseudo-first-child div:first-child	
+Pass	Document.querySelectorAll: :first-child pseudo-class selector, doesn't match non-first-child elements: .pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child	
+Pass	Document.querySelector: :first-child pseudo-class selector, doesn't match non-first-child elements: .pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child	
+Pass	Document.querySelectorAll: :first-child pseudo-class selector, matching first-child of multiple elements: #pseudo-first-child span:first-child	
+Pass	Document.querySelector: :first-child pseudo-class selector, matching first-child of multiple elements: #pseudo-first-child span:first-child	
+Pass	Document.querySelectorAll: :last-child pseudo-class selector, matching last child div element: #pseudo-last-child div:last-child	
+Pass	Document.querySelector: :last-child pseudo-class selector, matching last child div element: #pseudo-last-child div:last-child	
+Pass	Document.querySelectorAll: :last-child pseudo-class selector, doesn't match non-last-child elements: .pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child	
+Pass	Document.querySelector: :last-child pseudo-class selector, doesn't match non-last-child elements: .pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child	
+Pass	Document.querySelectorAll: :last-child pseudo-class selector, matching first-child of multiple elements: #pseudo-last-child span:last-child	
+Pass	Document.querySelector: :last-child pseudo-class selector, matching first-child of multiple elements: #pseudo-last-child span:last-child	
+Pass	Document.querySelectorAll: :pseudo-only-child pseudo-class selector, matching all only-child elements: #pseudo-only :only-child	
+Pass	Document.querySelector: :pseudo-only-child pseudo-class selector, matching all only-child elements: #pseudo-only :only-child	
+Pass	Document.querySelectorAll: :pseudo-only-child pseudo-class selector, matching only-child em elements: #pseudo-only em:only-child	
+Pass	Document.querySelector: :pseudo-only-child pseudo-class selector, matching only-child em elements: #pseudo-only em:only-child	
+Pass	Document.querySelectorAll: :pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type: #pseudo-only :only-of-type	
+Pass	Document.querySelector: :pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type: #pseudo-only :only-of-type	
+Pass	Document.querySelectorAll: :pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type: #pseudo-only em:only-of-type	
+Pass	Document.querySelector: :pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type: #pseudo-only em:only-of-type	
+Pass	Document.querySelectorAll: :empty pseudo-class selector, matching empty p elements: #pseudo-empty p:empty	
+Pass	Document.querySelector: :empty pseudo-class selector, matching empty p elements: #pseudo-empty p:empty	
+Pass	Document.querySelectorAll: :empty pseudo-class selector, matching all empty elements: #pseudo-empty :empty	
+Pass	Document.querySelector: :empty pseudo-class selector, matching all empty elements: #pseudo-empty :empty	
+Pass	Document.querySelectorAll: :link and :visited pseudo-class selectors, matching a and area elements with href attributes: #pseudo-link :link, #pseudo-link :visited	
+Pass	Document.querySelector: :link and :visited pseudo-class selectors, matching a and area elements with href attributes: #pseudo-link :link, #pseudo-link :visited	
+Pass	Document.querySelectorAll: :link and :visited pseudo-class selectors, matching no elements: #head :link, #head :visited	
+Pass	Document.querySelector: :link and :visited pseudo-class selectors, matching no elements: #head :link, #head :visited	
+Fail	Document.querySelectorAll: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target	
+Fail	Document.querySelector: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target	
+Pass	Document.querySelectorAll: :lang pseudo-class selector, matching inherited language: #pseudo-lang-div1:lang(en)	
+Pass	Document.querySelector: :lang pseudo-class selector, matching inherited language: #pseudo-lang-div1:lang(en)	
+Pass	Document.querySelectorAll: :lang pseudo-class selector, matching specified language with exact value: #pseudo-lang-div2:lang(fr)	
+Pass	Document.querySelector: :lang pseudo-class selector, matching specified language with exact value: #pseudo-lang-div2:lang(fr)	
+Pass	Document.querySelectorAll: :lang pseudo-class selector, matching specified language with partial value: #pseudo-lang-div3:lang(en)	
+Pass	Document.querySelector: :lang pseudo-class selector, matching specified language with partial value: #pseudo-lang-div3:lang(en)	
+Pass	Document.querySelectorAll: :lang pseudo-class selector, not matching incorrect language: #pseudo-lang-div4:lang(es-AR)	
+Pass	Document.querySelector: :lang pseudo-class selector, not matching incorrect language: #pseudo-lang-div4:lang(es-AR)	
+Pass	Document.querySelectorAll: :enabled pseudo-class selector, matching all enabled form controls: #pseudo-ui :enabled	
+Pass	Document.querySelector: :enabled pseudo-class selector, matching all enabled form controls: #pseudo-ui :enabled	
+Pass	Document.querySelectorAll: :enabled pseudo-class selector, not matching link elements: #pseudo-link :enabled	
+Pass	Document.querySelector: :enabled pseudo-class selector, not matching link elements: #pseudo-link :enabled	
+Pass	Document.querySelectorAll: :disabled pseudo-class selector, matching all disabled form controls: #pseudo-ui :disabled	
+Pass	Document.querySelector: :disabled pseudo-class selector, matching all disabled form controls: #pseudo-ui :disabled	
+Pass	Document.querySelectorAll: :disabled pseudo-class selector, not matching link elements: #pseudo-link :disabled	
+Pass	Document.querySelector: :disabled pseudo-class selector, not matching link elements: #pseudo-link :disabled	
+Pass	Document.querySelectorAll: :checked pseudo-class selector, matching checked radio buttons and checkboxes: #pseudo-ui :checked	
+Pass	Document.querySelector: :checked pseudo-class selector, matching checked radio buttons and checkboxes: #pseudo-ui :checked	
+Pass	Document.querySelectorAll: :not pseudo-class selector, matching : #not>:not(div)	
+Pass	Document.querySelector: :not pseudo-class selector, matching : #not>:not(div)	
+Pass	Document.querySelectorAll: :not pseudo-class selector, matching : #not * :not(:first-child)	
+Pass	Document.querySelector: :not pseudo-class selector, matching : #not * :not(:first-child)	
+Pass	Document.querySelectorAll: :not pseudo-class selector, matching nothing: :not(*)	
+Pass	Document.querySelector: :not pseudo-class selector, matching nothing: :not(*)	
+Pass	Document.querySelectorAll: :not pseudo-class selector, matching nothing: :not(*|*)	
+Pass	Document.querySelector: :not pseudo-class selector, matching nothing: :not(*|*)	
+Pass	Document.querySelectorAll: :not pseudo-class selector argument surrounded by spaces, matching : #not>:not( div )	
+Pass	Document.querySelector: :not pseudo-class selector argument surrounded by spaces, matching : #not>:not( div )	
+Pass	Document.querySelectorAll: :first-line pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-line	
+Pass	Document.querySelector: :first-line pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-line	
+Pass	Document.querySelectorAll: ::first-line pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-line	
+Pass	Document.querySelector: ::first-line pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-line	
+Pass	Document.querySelectorAll: :first-letter pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-letter	
+Pass	Document.querySelector: :first-letter pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-letter	
+Pass	Document.querySelectorAll: ::first-letter pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-letter	
+Pass	Document.querySelector: ::first-letter pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-letter	
+Pass	Document.querySelectorAll: :before pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:before	
+Pass	Document.querySelector: :before pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:before	
+Pass	Document.querySelectorAll: ::before pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::before	
+Pass	Document.querySelector: ::before pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::before	
+Pass	Document.querySelectorAll: :after pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:after	
+Pass	Document.querySelector: :after pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:after	
+Pass	Document.querySelectorAll: ::after pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::after	
+Pass	Document.querySelector: ::after pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::after	
+Pass	Document.querySelectorAll: Class selector, matching element with specified class: .class-p	
+Pass	Document.querySelector: Class selector, matching element with specified class: .class-p	
+Pass	Document.querySelectorAll: Class selector, chained, matching only elements with all specified classes: #class .apple.orange.banana	
+Pass	Document.querySelector: Class selector, chained, matching only elements with all specified classes: #class .apple.orange.banana	
+Pass	Document.querySelectorAll: Class Selector, chained, with type selector: div.apple.banana.orange	
+Pass	Document.querySelector: Class Selector, chained, with type selector: div.apple.banana.orange	
+Pass	Document.querySelectorAll: Class selector, matching element with class value using non-ASCII characters (1): .台北Táiběi	
+Pass	Document.querySelector: Class selector, matching element with class value using non-ASCII characters (1): .台北Táiběi	
+Pass	Document.querySelectorAll: Class selector, matching multiple elements with class value using non-ASCII characters: .台北	
+Pass	Document.querySelector: Class selector, matching multiple elements with class value using non-ASCII characters: .台北	
+Pass	Document.querySelectorAll: Class selector, chained, matching element with multiple class values using non-ASCII characters (1): .台北Táiběi.台北	
+Pass	Document.querySelector: Class selector, chained, matching element with multiple class values using non-ASCII characters (1): .台北Táiběi.台北	
+Pass	Document.querySelectorAll: Class selector, matching element with class with escaped character: .foo\:bar	
+Pass	Document.querySelector: Class selector, matching element with class with escaped character: .foo\:bar	
+Pass	Document.querySelectorAll: Class selector, matching element with class with escaped character: .test\.foo\[5\]bar	
+Pass	Document.querySelector: Class selector, matching element with class with escaped character: .test\.foo\[5\]bar	
+Pass	Document.querySelectorAll: ID selector, matching element with specified id: #id #id-div1	
+Pass	Document.querySelector: ID selector, matching element with specified id: #id #id-div1	
+Fail	Document.querySelectorAll: ID selector, chained, matching element with specified id: #id-div1, #id-div1	
+Pass	Document.querySelector: ID selector, chained, matching element with specified id: #id-div1, #id-div1	
+Pass	Document.querySelectorAll: ID selector, chained, matching element with specified id: #id-div1, #id-div2	
+Pass	Document.querySelector: ID selector, chained, matching element with specified id: #id-div1, #id-div2	
+Pass	Document.querySelectorAll: ID Selector, chained, with type selector: div#id-div1, div#id-div2	
+Pass	Document.querySelector: ID Selector, chained, with type selector: div#id-div1, div#id-div2	
+Pass	Document.querySelectorAll: ID selector, not matching non-existent descendant: #id #none	
+Pass	Document.querySelector: ID selector, not matching non-existent descendant: #id #none	
+Pass	Document.querySelectorAll: ID selector, not matching non-existent ancestor: #none #id-div1	
+Pass	Document.querySelector: ID selector, not matching non-existent ancestor: #none #id-div1	
+Pass	Document.querySelectorAll: ID selector, matching multiple elements with duplicate id: #id-li-duplicate	
+Pass	Document.querySelector: ID selector, matching multiple elements with duplicate id: #id-li-duplicate	
+Pass	Document.querySelectorAll: ID selector, matching id value using non-ASCII characters (1): #台北Táiběi	
+Pass	Document.querySelector: ID selector, matching id value using non-ASCII characters (1): #台北Táiběi	
+Pass	Document.querySelectorAll: ID selector, matching id value using non-ASCII characters (2): #台北	
+Pass	Document.querySelector: ID selector, matching id value using non-ASCII characters (2): #台北	
+Pass	Document.querySelectorAll: ID selector, matching id values using non-ASCII characters (1): #台北Táiběi, #台北	
+Pass	Document.querySelector: ID selector, matching id values using non-ASCII characters (1): #台北Táiběi, #台北	
+Pass	Document.querySelectorAll: ID selector, matching element with id with escaped character: #\#foo\:bar	
+Pass	Document.querySelector: ID selector, matching element with id with escaped character: #\#foo\:bar	
+Pass	Document.querySelectorAll: ID selector, matching element with id with escaped character: #test\.foo\[5\]bar	
+Pass	Document.querySelector: ID selector, matching element with id with escaped character: #test\.foo\[5\]bar	
+Pass	Document.querySelectorAll: Namespace selector, matching element with any namespace: #any-namespace *|div	
+Pass	Document.querySelector: Namespace selector, matching element with any namespace: #any-namespace *|div	
+Pass	Document.querySelectorAll: Namespace selector, matching div elements in no namespace only: #no-namespace |div	
+Pass	Document.querySelector: Namespace selector, matching div elements in no namespace only: #no-namespace |div	
+Pass	Document.querySelectorAll: Namespace selector, matching any elements in no namespace only: #no-namespace |*	
+Pass	Document.querySelector: Namespace selector, matching any elements in no namespace only: #no-namespace |*	
+Pass	Document.querySelectorAll: Descendant combinator, matching element that is a descendant of an element with id: #descendant div	
+Pass	Document.querySelector: Descendant combinator, matching element that is a descendant of an element with id: #descendant div	
+Pass	Document.querySelectorAll: Descendant combinator, matching element with id that is a descendant of an element: body #descendant-div1	
+Pass	Document.querySelector: Descendant combinator, matching element with id that is a descendant of an element: body #descendant-div1	
+Pass	Document.querySelectorAll: Descendant combinator, matching element with id that is a descendant of an element: div #descendant-div1	
+Pass	Document.querySelector: Descendant combinator, matching element with id that is a descendant of an element: div #descendant-div1	
+Pass	Document.querySelectorAll: Descendant combinator, matching element with id that is a descendant of an element with id: #descendant #descendant-div2	
+Pass	Document.querySelector: Descendant combinator, matching element with id that is a descendant of an element with id: #descendant #descendant-div2	
+Pass	Document.querySelectorAll: Descendant combinator, matching element with class that is a descendant of an element with id: #descendant .descendant-div2	
+Pass	Document.querySelector: Descendant combinator, matching element with class that is a descendant of an element with id: #descendant .descendant-div2	
+Pass	Document.querySelectorAll: Descendant combinator, matching element with class that is a descendant of an element with class: .descendant-div1 .descendant-div3	
+Pass	Document.querySelector: Descendant combinator, matching element with class that is a descendant of an element with class: .descendant-div1 .descendant-div3	
+Pass	Document.querySelectorAll: Descendant combinator, not matching element with id that is not a descendant of an element with id: #descendant-div1 #descendant-div4	
+Pass	Document.querySelector: Descendant combinator, not matching element with id that is not a descendant of an element with id: #descendant-div1 #descendant-div4	
+Pass	Document.querySelectorAll: Descendant combinator, whitespace characters: #descendant #descendant-div2	
+Pass	Document.querySelector: Descendant combinator, whitespace characters: #descendant #descendant-div2	
+Pass	Document.querySelectorAll: Child combinator, matching element that is a child of an element with id: #child>div	
+Pass	Document.querySelector: Child combinator, matching element that is a child of an element with id: #child>div	
+Pass	Document.querySelectorAll: Child combinator, matching element with id that is a child of an element: div>#child-div1	
+Pass	Document.querySelector: Child combinator, matching element with id that is a child of an element: div>#child-div1	
+Pass	Document.querySelectorAll: Child combinator, matching element with id that is a child of an element with id: #child>#child-div1	
+Pass	Document.querySelector: Child combinator, matching element with id that is a child of an element with id: #child>#child-div1	
+Pass	Document.querySelectorAll: Child combinator, matching element with id that is a child of an element with class: #child-div1>.child-div2	
+Pass	Document.querySelector: Child combinator, matching element with id that is a child of an element with class: #child-div1>.child-div2	
+Pass	Document.querySelectorAll: Child combinator, matching element with class that is a child of an element with class: .child-div1>.child-div2	
+Pass	Document.querySelector: Child combinator, matching element with class that is a child of an element with class: .child-div1>.child-div2	
+Pass	Document.querySelectorAll: Child combinator, not matching element with id that is not a child of an element with id: #child>#child-div3	
+Pass	Document.querySelector: Child combinator, not matching element with id that is not a child of an element with id: #child>#child-div3	
+Pass	Document.querySelectorAll: Child combinator, not matching element with id that is not a child of an element with class: #child-div1>.child-div3	
+Pass	Document.querySelector: Child combinator, not matching element with id that is not a child of an element with class: #child-div1>.child-div3	
+Pass	Document.querySelectorAll: Child combinator, not matching element with class that is not a child of an element with class: .child-div1>.child-div3	
+Pass	Document.querySelector: Child combinator, not matching element with class that is not a child of an element with class: .child-div1>.child-div3	
+Pass	Document.querySelectorAll: Child combinator, surrounded by whitespace: #child-div1 > #child-div2	
+Pass	Document.querySelector: Child combinator, surrounded by whitespace: #child-div1 > #child-div2	
+Pass	Document.querySelectorAll: Child combinator, whitespace after: #child-div1> #child-div2	
+Pass	Document.querySelector: Child combinator, whitespace after: #child-div1> #child-div2	
+Pass	Document.querySelectorAll: Child combinator, whitespace before: #child-div1 >#child-div2	
+Pass	Document.querySelector: Child combinator, whitespace before: #child-div1 >#child-div2	
+Pass	Document.querySelectorAll: Child combinator, no whitespace: #child-div1>#child-div2	
+Pass	Document.querySelector: Child combinator, no whitespace: #child-div1>#child-div2	
+Pass	Document.querySelectorAll: Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id: #adjacent-div2+div	
+Pass	Document.querySelector: Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id: #adjacent-div2+div	
+Pass	Document.querySelectorAll: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element: div+#adjacent-div4	
+Pass	Document.querySelector: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element: div+#adjacent-div4	
+Pass	Document.querySelectorAll: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id: #adjacent-div2+#adjacent-div4	
+Pass	Document.querySelector: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id: #adjacent-div2+#adjacent-div4	
+Pass	Document.querySelectorAll: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id: #adjacent-div2+.adjacent-div4	
+Pass	Document.querySelector: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id: #adjacent-div2+.adjacent-div4	
+Pass	Document.querySelectorAll: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class: .adjacent-div2+.adjacent-div4	
+Pass	Document.querySelector: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class: .adjacent-div2+.adjacent-div4	
+Pass	Document.querySelectorAll: Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element: #adjacent div+p	
+Pass	Document.querySelector: Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element: #adjacent div+p	
+Pass	Document.querySelectorAll: Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id: #adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1	
+Pass	Document.querySelector: Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id: #adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1	
+Pass	Document.querySelectorAll: Adjacent sibling combinator, surrounded by whitespace: #adjacent-p2 + #adjacent-p3	
+Pass	Document.querySelector: Adjacent sibling combinator, surrounded by whitespace: #adjacent-p2 + #adjacent-p3	
+Pass	Document.querySelectorAll: Adjacent sibling combinator, whitespace after: #adjacent-p2+ #adjacent-p3	
+Pass	Document.querySelector: Adjacent sibling combinator, whitespace after: #adjacent-p2+ #adjacent-p3	
+Pass	Document.querySelectorAll: Adjacent sibling combinator, whitespace before: #adjacent-p2 +#adjacent-p3	
+Pass	Document.querySelector: Adjacent sibling combinator, whitespace before: #adjacent-p2 +#adjacent-p3	
+Pass	Document.querySelectorAll: Adjacent sibling combinator, no whitespace: #adjacent-p2+#adjacent-p3	
+Pass	Document.querySelector: Adjacent sibling combinator, no whitespace: #adjacent-p2+#adjacent-p3	
+Pass	Document.querySelectorAll: General sibling combinator, matching element that is a sibling of an element with id: #sibling-div2~div	
+Pass	Document.querySelector: General sibling combinator, matching element that is a sibling of an element with id: #sibling-div2~div	
+Pass	Document.querySelectorAll: General sibling combinator, matching element with id that is a sibling of an element: div~#sibling-div4	
+Pass	Document.querySelector: General sibling combinator, matching element with id that is a sibling of an element: div~#sibling-div4	
+Pass	Document.querySelectorAll: General sibling combinator, matching element with id that is a sibling of an element with id: #sibling-div2~#sibling-div4	
+Pass	Document.querySelector: General sibling combinator, matching element with id that is a sibling of an element with id: #sibling-div2~#sibling-div4	
+Pass	Document.querySelectorAll: General sibling combinator, matching element with class that is a sibling of an element with id: #sibling-div2~.sibling-div	
+Pass	Document.querySelector: General sibling combinator, matching element with class that is a sibling of an element with id: #sibling-div2~.sibling-div	
+Pass	Document.querySelectorAll: General sibling combinator, matching p element that is a sibling of a div element: #sibling div~p	
+Pass	Document.querySelector: General sibling combinator, matching p element that is a sibling of a div element: #sibling div~p	
+Pass	Document.querySelectorAll: General sibling combinator, not matching element with id that is not a sibling after a p element: #sibling>p~div	
+Pass	Document.querySelector: General sibling combinator, not matching element with id that is not a sibling after a p element: #sibling>p~div	
+Pass	Document.querySelectorAll: General sibling combinator, not matching element with id that is not a sibling after an element with id: #sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1	
+Pass	Document.querySelector: General sibling combinator, not matching element with id that is not a sibling after an element with id: #sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1	
+Pass	Document.querySelectorAll: General sibling combinator, surrounded by whitespace: #sibling-p2 ~ #sibling-p3	
+Pass	Document.querySelector: General sibling combinator, surrounded by whitespace: #sibling-p2 ~ #sibling-p3	
+Pass	Document.querySelectorAll: General sibling combinator, whitespace after: #sibling-p2~ #sibling-p3	
+Pass	Document.querySelector: General sibling combinator, whitespace after: #sibling-p2~ #sibling-p3	
+Pass	Document.querySelectorAll: General sibling combinator, whitespace before: #sibling-p2 ~#sibling-p3	
+Pass	Document.querySelector: General sibling combinator, whitespace before: #sibling-p2 ~#sibling-p3	
+Pass	Document.querySelectorAll: General sibling combinator, no whitespace: #sibling-p2~#sibling-p3	
+Pass	Document.querySelector: General sibling combinator, no whitespace: #sibling-p2~#sibling-p3	
+Pass	Document.querySelectorAll: Syntax, group of selectors separator, surrounded by whitespace: #group em , #group strong	
+Pass	Document.querySelector: Syntax, group of selectors separator, surrounded by whitespace: #group em , #group strong	
+Pass	Document.querySelectorAll: Syntax, group of selectors separator, whitespace after: #group em, #group strong	
+Pass	Document.querySelector: Syntax, group of selectors separator, whitespace after: #group em, #group strong	
+Pass	Document.querySelectorAll: Syntax, group of selectors separator, whitespace before: #group em ,#group strong	
+Pass	Document.querySelector: Syntax, group of selectors separator, whitespace before: #group em ,#group strong	
+Pass	Document.querySelectorAll: Syntax, group of selectors separator, no whitespace: #group em,#group strong	
+Pass	Document.querySelector: Syntax, group of selectors separator, no whitespace: #group em,#group strong	
+Fail	Document.querySelectorAll: Slotted selector: ::slotted(foo)	Failed to parse selector
+Fail	Document.querySelector: Slotted selector: ::slotted(foo)	Failed to parse selector
+Fail	Document.querySelectorAll: Slotted selector (no matching closing paren): ::slotted(foo	Failed to parse selector
+Fail	Document.querySelector: Slotted selector (no matching closing paren): ::slotted(foo	Failed to parse selector
+Pass	Detached Element.querySelectorAll: Type selector, matching html element: html	
+Pass	Detached Element.querySelector: Type selector, matching html element: html	
+Pass	Detached Element.querySelectorAll: Type selector, matching body element: body	
+Pass	Detached Element.querySelector: Type selector, matching body element: body	
+Pass	Detached Element.querySelectorAll: Universal selector, matching all children of element with specified ID: #universal>*	
+Pass	Detached Element.querySelector: Universal selector, matching all children of element with specified ID: #universal>*	
+Pass	Detached Element.querySelectorAll: Universal selector, matching all grandchildren of element with specified ID: #universal>*>*	
+Pass	Detached Element.querySelector: Universal selector, matching all grandchildren of element with specified ID: #universal>*>*	
+Pass	Detached Element.querySelectorAll: Universal selector, matching all children of empty element with specified ID: #empty>*	
+Pass	Detached Element.querySelector: Universal selector, matching all children of empty element with specified ID: #empty>*	
+Pass	Detached Element.querySelectorAll: Universal selector, matching all descendants of element with specified ID: #universal *	
+Pass	Detached Element.querySelector: Universal selector, matching all descendants of element with specified ID: #universal *	
+Pass	Detached Element.querySelectorAll: Attribute presence selector, matching align attribute with value: .attr-presence-div1[align]	
+Pass	Detached Element.querySelector: Attribute presence selector, matching align attribute with value: .attr-presence-div1[align]	
+Pass	Detached Element.querySelectorAll: Attribute presence selector, matching align attribute with empty value: .attr-presence-div2[align]	
+Pass	Detached Element.querySelector: Attribute presence selector, matching align attribute with empty value: .attr-presence-div2[align]	
+Fail	Detached Element.querySelectorAll: Attribute presence selector, matching title attribute, case insensitivity: #attr-presence [*|TiTlE]	
+Fail	Detached Element.querySelector: Attribute presence selector, matching title attribute, case insensitivity: #attr-presence [*|TiTlE]	
+Pass	Detached Element.querySelectorAll: Attribute presence selector, matching custom data-* attribute: [data-attr-presence]	
+Pass	Detached Element.querySelector: Attribute presence selector, matching custom data-* attribute: [data-attr-presence]	
+Pass	Detached Element.querySelectorAll: Attribute presence selector, not matching attribute with similar name: .attr-presence-div3[align], .attr-presence-div4[align]	
+Pass	Detached Element.querySelector: Attribute presence selector, not matching attribute with similar name: .attr-presence-div3[align], .attr-presence-div4[align]	
+Pass	Detached Element.querySelectorAll: Attribute presence selector, matching attribute with non-ASCII characters: ul[data-中文]	
+Pass	Detached Element.querySelector: Attribute presence selector, matching attribute with non-ASCII characters: ul[data-中文]	
+Pass	Detached Element.querySelectorAll: Attribute presence selector, not matching default option without selected attribute: #attr-presence-select1 option[selected]	
+Pass	Detached Element.querySelector: Attribute presence selector, not matching default option without selected attribute: #attr-presence-select1 option[selected]	
+Pass	Detached Element.querySelectorAll: Attribute presence selector, matching option with selected attribute: #attr-presence-select2 option[selected]	
+Pass	Detached Element.querySelector: Attribute presence selector, matching option with selected attribute: #attr-presence-select2 option[selected]	
+Pass	Detached Element.querySelectorAll: Attribute presence selector, matching multiple options with selected attributes: #attr-presence-select3 option[selected]	
+Pass	Detached Element.querySelector: Attribute presence selector, matching multiple options with selected attributes: #attr-presence-select3 option[selected]	
+Pass	Detached Element.querySelectorAll: Attribute value selector, matching align attribute with value: #attr-value [align="center"]	
+Pass	Detached Element.querySelector: Attribute value selector, matching align attribute with value: #attr-value [align="center"]	
+Pass	Detached Element.querySelectorAll: Attribute value selector, matching align attribute with value, unclosed bracket: #attr-value [align="center"	
+Pass	Detached Element.querySelector: Attribute value selector, matching align attribute with value, unclosed bracket: #attr-value [align="center"	
+Pass	Detached Element.querySelectorAll: Attribute value selector, matching align attribute with empty value: #attr-value [align=""]	
+Pass	Detached Element.querySelector: Attribute value selector, matching align attribute with empty value: #attr-value [align=""]	
+Pass	Detached Element.querySelectorAll: Attribute value selector, not matching align attribute with partial value: #attr-value [align="c"]	
+Pass	Detached Element.querySelector: Attribute value selector, not matching align attribute with partial value: #attr-value [align="c"]	
+Pass	Detached Element.querySelectorAll: Attribute value selector, not matching align attribute with incorrect value: #attr-value [align="centera"]	
+Pass	Detached Element.querySelector: Attribute value selector, not matching align attribute with incorrect value: #attr-value [align="centera"]	
+Pass	Detached Element.querySelectorAll: Attribute value selector, matching custom data-* attribute with unicode escaped value: [data-attr-value="\e9"]	
+Pass	Detached Element.querySelector: Attribute value selector, matching custom data-* attribute with unicode escaped value: [data-attr-value="\e9"]	
+Pass	Detached Element.querySelectorAll: Attribute value selector, matching custom data-* attribute with escaped character: [data-attr-value_foo="\e9"]	
+Pass	Detached Element.querySelector: Attribute value selector, matching custom data-* attribute with escaped character: [data-attr-value_foo="\e9"]	
+Pass	Detached Element.querySelectorAll: Attribute value selector with single-quoted value, matching multiple inputs with type attributes: #attr-value input[type='hidden'],#attr-value input[type='radio']	
+Pass	Detached Element.querySelector: Attribute value selector with single-quoted value, matching multiple inputs with type attributes: #attr-value input[type='hidden'],#attr-value input[type='radio']	
+Pass	Detached Element.querySelectorAll: Attribute value selector with double-quoted value, matching multiple inputs with type attributes: #attr-value input[type="hidden"],#attr-value input[type='radio']	
+Pass	Detached Element.querySelector: Attribute value selector with double-quoted value, matching multiple inputs with type attributes: #attr-value input[type="hidden"],#attr-value input[type='radio']	
+Pass	Detached Element.querySelectorAll: Attribute value selector with unquoted value, matching multiple inputs with type attributes: #attr-value input[type=hidden],#attr-value input[type=radio]	
+Pass	Detached Element.querySelector: Attribute value selector with unquoted value, matching multiple inputs with type attributes: #attr-value input[type=hidden],#attr-value input[type=radio]	
+Pass	Detached Element.querySelectorAll: Attribute value selector, matching attribute with value using non-ASCII characters: [data-attr-value=中文]	
+Pass	Detached Element.querySelector: Attribute value selector, matching attribute with value using non-ASCII characters: [data-attr-value=中文]	
+Pass	Detached Element.querySelectorAll: Attribute whitespace-separated list selector, matching class attribute with value: #attr-whitespace [class~="div1"]	
+Pass	Detached Element.querySelector: Attribute whitespace-separated list selector, matching class attribute with value: #attr-whitespace [class~="div1"]	
+Pass	Detached Element.querySelectorAll: Attribute whitespace-separated list selector, not matching class attribute with empty value: #attr-whitespace [class~=""]	
+Pass	Detached Element.querySelector: Attribute whitespace-separated list selector, not matching class attribute with empty value: #attr-whitespace [class~=""]	
+Pass	Detached Element.querySelectorAll: Attribute whitespace-separated list selector, not matching class attribute with partial value: [data-attr-whitespace~="div"]	
+Pass	Detached Element.querySelector: Attribute whitespace-separated list selector, not matching class attribute with partial value: [data-attr-whitespace~="div"]	
+Pass	Detached Element.querySelectorAll: Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value: [data-attr-whitespace~="\0000e9"]	
+Pass	Detached Element.querySelector: Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value: [data-attr-whitespace~="\0000e9"]	
+Pass	Detached Element.querySelectorAll: Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character: [data-attr-whitespace_foo~="\e9"]	
+Pass	Detached Element.querySelector: Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character: [data-attr-whitespace_foo~="\e9"]	
+Pass	Detached Element.querySelectorAll: Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~='bookmark'], #attr-whitespace a[rel~='nofollow']	
+Pass	Detached Element.querySelector: Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~='bookmark'], #attr-whitespace a[rel~='nofollow']	
+Pass	Detached Element.querySelectorAll: Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~="bookmark"],#attr-whitespace a[rel~='nofollow']	
+Pass	Detached Element.querySelector: Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~="bookmark"],#attr-whitespace a[rel~='nofollow']	
+Pass	Detached Element.querySelectorAll: Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~=bookmark], #attr-whitespace a[rel~=nofollow]	
+Pass	Detached Element.querySelector: Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~=bookmark], #attr-whitespace a[rel~=nofollow]	
+Pass	Detached Element.querySelectorAll: Attribute whitespace-separated list selector with double-quoted value, not matching value with space: #attr-whitespace a[rel~="book mark"]	
+Pass	Detached Element.querySelector: Attribute whitespace-separated list selector with double-quoted value, not matching value with space: #attr-whitespace a[rel~="book mark"]	
+Pass	Detached Element.querySelectorAll: Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters: #attr-whitespace [title~=中文]	
+Pass	Detached Element.querySelector: Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters: #attr-whitespace [title~=中文]	
+Pass	Detached Element.querySelectorAll: Attribute hyphen-separated list selector, not matching unspecified lang attribute: #attr-hyphen-div1[lang|="en"]	
+Pass	Detached Element.querySelector: Attribute hyphen-separated list selector, not matching unspecified lang attribute: #attr-hyphen-div1[lang|="en"]	
+Pass	Detached Element.querySelectorAll: Attribute hyphen-separated list selector, matching lang attribute with exact value: #attr-hyphen-div2[lang|="fr"]	
+Pass	Detached Element.querySelector: Attribute hyphen-separated list selector, matching lang attribute with exact value: #attr-hyphen-div2[lang|="fr"]	
+Pass	Detached Element.querySelectorAll: Attribute hyphen-separated list selector, matching lang attribute with partial value: #attr-hyphen-div3[lang|="en"]	
+Pass	Detached Element.querySelector: Attribute hyphen-separated list selector, matching lang attribute with partial value: #attr-hyphen-div3[lang|="en"]	
+Pass	Detached Element.querySelectorAll: Attribute hyphen-separated list selector, not matching incorrect value: #attr-hyphen-div4[lang|="es-AR"]	
+Pass	Detached Element.querySelector: Attribute hyphen-separated list selector, not matching incorrect value: #attr-hyphen-div4[lang|="es-AR"]	
+Pass	Detached Element.querySelectorAll: Attribute begins with selector, matching href attributes beginning with specified substring: #attr-begins a[href^="http://www"]	
+Pass	Detached Element.querySelector: Attribute begins with selector, matching href attributes beginning with specified substring: #attr-begins a[href^="http://www"]	
+Pass	Detached Element.querySelectorAll: Attribute begins with selector, matching lang attributes beginning with specified substring, : #attr-begins [lang^="en-"]	
+Pass	Detached Element.querySelector: Attribute begins with selector, matching lang attributes beginning with specified substring, : #attr-begins [lang^="en-"]	
+Pass	Detached Element.querySelectorAll: Attribute begins with selector, not matching class attribute with empty value: #attr-begins [class^=""]	
+Pass	Detached Element.querySelector: Attribute begins with selector, not matching class attribute with empty value: #attr-begins [class^=""]	
+Pass	Detached Element.querySelectorAll: Attribute begins with selector, not matching class attribute not beginning with specified substring: #attr-begins [class^=apple]	
+Pass	Detached Element.querySelector: Attribute begins with selector, not matching class attribute not beginning with specified substring: #attr-begins [class^=apple]	
+Pass	Detached Element.querySelectorAll: Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=' apple']	
+Pass	Detached Element.querySelector: Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=' apple']	
+Pass	Detached Element.querySelectorAll: Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=" apple"]	
+Pass	Detached Element.querySelector: Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=" apple"]	
+Pass	Detached Element.querySelectorAll: Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring: #attr-begins [class^= apple]	
+Pass	Detached Element.querySelector: Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring: #attr-begins [class^= apple]	
+Pass	Detached Element.querySelectorAll: Attribute ends with selector, matching href attributes ending with specified substring: #attr-ends a[href$=".org"]	
+Pass	Detached Element.querySelector: Attribute ends with selector, matching href attributes ending with specified substring: #attr-ends a[href$=".org"]	
+Pass	Detached Element.querySelectorAll: Attribute ends with selector, matching lang attributes ending with specified substring, : #attr-ends [lang$="-CH"]	
+Pass	Detached Element.querySelector: Attribute ends with selector, matching lang attributes ending with specified substring, : #attr-ends [lang$="-CH"]	
+Pass	Detached Element.querySelectorAll: Attribute ends with selector, not matching class attribute with empty value: #attr-ends [class$=""]	
+Pass	Detached Element.querySelector: Attribute ends with selector, not matching class attribute with empty value: #attr-ends [class$=""]	
+Pass	Detached Element.querySelectorAll: Attribute ends with selector, not matching class attribute not ending with specified substring: #attr-ends [class$=apple]	
+Pass	Detached Element.querySelector: Attribute ends with selector, not matching class attribute not ending with specified substring: #attr-ends [class$=apple]	
+Pass	Detached Element.querySelectorAll: Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring: #attr-ends [class$='apple ']	
+Pass	Detached Element.querySelector: Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring: #attr-ends [class$='apple ']	
+Pass	Detached Element.querySelectorAll: Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring: #attr-ends [class$="apple "]	
+Pass	Detached Element.querySelector: Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring: #attr-ends [class$="apple "]	
+Pass	Detached Element.querySelectorAll: Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring: #attr-ends [class$=apple ]	
+Pass	Detached Element.querySelector: Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring: #attr-ends [class$=apple ]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector, matching href attributes beginning with specified substring: #attr-contains a[href*="http://www"]	
+Pass	Detached Element.querySelector: Attribute contains selector, matching href attributes beginning with specified substring: #attr-contains a[href*="http://www"]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector, matching href attributes ending with specified substring: #attr-contains a[href*=".org"]	
+Pass	Detached Element.querySelector: Attribute contains selector, matching href attributes ending with specified substring: #attr-contains a[href*=".org"]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector, matching href attributes containing specified substring: #attr-contains a[href*=".example."]	
+Pass	Detached Element.querySelector: Attribute contains selector, matching href attributes containing specified substring: #attr-contains a[href*=".example."]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector, matching lang attributes beginning with specified substring, : #attr-contains [lang*="en-"]	
+Pass	Detached Element.querySelector: Attribute contains selector, matching lang attributes beginning with specified substring, : #attr-contains [lang*="en-"]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector, matching lang attributes ending with specified substring, : #attr-contains [lang*="-CH"]	
+Pass	Detached Element.querySelector: Attribute contains selector, matching lang attributes ending with specified substring, : #attr-contains [lang*="-CH"]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector, not matching class attribute with empty value: #attr-contains [class*=""]	
+Pass	Detached Element.querySelector: Attribute contains selector, not matching class attribute with empty value: #attr-contains [class*=""]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=' apple']	
+Pass	Detached Element.querySelector: Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=' apple']	
+Pass	Detached Element.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute ending with specified substring: #attr-contains [class*='orange ']	
+Pass	Detached Element.querySelector: Attribute contains selector with single-quoted value, matching class attribute ending with specified substring: #attr-contains [class*='orange ']	
+Pass	Detached Element.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute containing specified substring: #attr-contains [class*='ple banana ora']	
+Pass	Detached Element.querySelector: Attribute contains selector with single-quoted value, matching class attribute containing specified substring: #attr-contains [class*='ple banana ora']	
+Pass	Detached Element.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=" apple"]	
+Pass	Detached Element.querySelector: Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=" apple"]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute ending with specified substring: #attr-contains [class*="orange "]	
+Pass	Detached Element.querySelector: Attribute contains selector with double-quoted value, matching class attribute ending with specified substring: #attr-contains [class*="orange "]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute containing specified substring: #attr-contains [class*="ple banana ora"]	
+Pass	Detached Element.querySelector: Attribute contains selector with double-quoted value, matching class attribute containing specified substring: #attr-contains [class*="ple banana ora"]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute beginning with specified substring: #attr-contains [class*= apple]	
+Pass	Detached Element.querySelector: Attribute contains selector with unquoted value, matching class attribute beginning with specified substring: #attr-contains [class*= apple]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute ending with specified substring: #attr-contains [class*=orange ]	
+Pass	Detached Element.querySelector: Attribute contains selector with unquoted value, matching class attribute ending with specified substring: #attr-contains [class*=orange ]	
+Pass	Detached Element.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute containing specified substring: #attr-contains [class*= banana ]	
+Pass	Detached Element.querySelector: Attribute contains selector with unquoted value, matching class attribute containing specified substring: #attr-contains [class*= banana ]	
+Pass	Detached Element.querySelectorAll: :root pseudo-class selector, not matching document root element: :root	
+Pass	Detached Element.querySelector: :root pseudo-class selector, not matching document root element: :root	
+Pass	Detached Element.querySelectorAll: :nth-child selector, matching the third child element: #pseudo-nth-table1 :nth-child(3)	
+Pass	Detached Element.querySelector: :nth-child selector, matching the third child element: #pseudo-nth-table1 :nth-child(3)	
+Pass	Detached Element.querySelectorAll: :nth-child selector, matching every third child element: #pseudo-nth li:nth-child(3n)	
+Pass	Detached Element.querySelector: :nth-child selector, matching every third child element: #pseudo-nth li:nth-child(3n)	
+Pass	Detached Element.querySelectorAll: :nth-child selector, matching every second child element, starting from the fourth: #pseudo-nth li:nth-child(2n+4)	
+Pass	Detached Element.querySelector: :nth-child selector, matching every second child element, starting from the fourth: #pseudo-nth li:nth-child(2n+4)	
+Pass	Detached Element.querySelectorAll: :nth-child selector, matching every fourth child element, starting from the third: #pseudo-nth-p1 :nth-child(4n-1)	
+Pass	Detached Element.querySelector: :nth-child selector, matching every fourth child element, starting from the third: #pseudo-nth-p1 :nth-child(4n-1)	
+Pass	Detached Element.querySelectorAll: :nth-last-child selector, matching the third last child element: #pseudo-nth-table1 :nth-last-child(3)	
+Pass	Detached Element.querySelector: :nth-last-child selector, matching the third last child element: #pseudo-nth-table1 :nth-last-child(3)	
+Pass	Detached Element.querySelectorAll: :nth-last-child selector, matching every third child element from the end: #pseudo-nth li:nth-last-child(3n)	
+Pass	Detached Element.querySelector: :nth-last-child selector, matching every third child element from the end: #pseudo-nth li:nth-last-child(3n)	
+Pass	Detached Element.querySelectorAll: :nth-last-child selector, matching every second child element from the end, starting from the fourth last: #pseudo-nth li:nth-last-child(2n+4)	
+Pass	Detached Element.querySelector: :nth-last-child selector, matching every second child element from the end, starting from the fourth last: #pseudo-nth li:nth-last-child(2n+4)	
+Pass	Detached Element.querySelectorAll: :nth-last-child selector, matching every fourth element from the end, starting from the third last: #pseudo-nth-p1 :nth-last-child(4n-1)	
+Pass	Detached Element.querySelector: :nth-last-child selector, matching every fourth element from the end, starting from the third last: #pseudo-nth-p1 :nth-last-child(4n-1)	
+Pass	Detached Element.querySelectorAll: :nth-of-type selector, matching the third em element: #pseudo-nth-p1 em:nth-of-type(3)	
+Pass	Detached Element.querySelector: :nth-of-type selector, matching the third em element: #pseudo-nth-p1 em:nth-of-type(3)	
+Pass	Detached Element.querySelectorAll: :nth-of-type selector, matching every second element of their type: #pseudo-nth-p1 :nth-of-type(2n)	
+Pass	Detached Element.querySelector: :nth-of-type selector, matching every second element of their type: #pseudo-nth-p1 :nth-of-type(2n)	
+Pass	Detached Element.querySelectorAll: :nth-of-type selector, matching every second elemetn of their type, starting from the first: #pseudo-nth-p1 span:nth-of-type(2n-1)	
+Pass	Detached Element.querySelector: :nth-of-type selector, matching every second elemetn of their type, starting from the first: #pseudo-nth-p1 span:nth-of-type(2n-1)	
+Pass	Detached Element.querySelectorAll: :nth-last-of-type selector, matching the third last em element: #pseudo-nth-p1 em:nth-last-of-type(3)	
+Pass	Detached Element.querySelector: :nth-last-of-type selector, matching the third last em element: #pseudo-nth-p1 em:nth-last-of-type(3)	
+Pass	Detached Element.querySelectorAll: :nth-last-of-type selector, matching every second last element of their type: #pseudo-nth-p1 :nth-last-of-type(2n)	
+Pass	Detached Element.querySelector: :nth-last-of-type selector, matching every second last element of their type: #pseudo-nth-p1 :nth-last-of-type(2n)	
+Pass	Detached Element.querySelectorAll: :nth-last-of-type selector, matching every second last element of their type, starting from the last: #pseudo-nth-p1 span:nth-last-of-type(2n-1)	
+Pass	Detached Element.querySelector: :nth-last-of-type selector, matching every second last element of their type, starting from the last: #pseudo-nth-p1 span:nth-last-of-type(2n-1)	
+Pass	Detached Element.querySelectorAll: :first-of-type selector, matching the first em element: #pseudo-nth-p1 em:first-of-type	
+Pass	Detached Element.querySelector: :first-of-type selector, matching the first em element: #pseudo-nth-p1 em:first-of-type	
+Pass	Detached Element.querySelectorAll: :first-of-type selector, matching the first of every type of element: #pseudo-nth-p1 :first-of-type	
+Pass	Detached Element.querySelector: :first-of-type selector, matching the first of every type of element: #pseudo-nth-p1 :first-of-type	
+Pass	Detached Element.querySelectorAll: :first-of-type selector, matching the first td element in each table row: #pseudo-nth-table1 tr :first-of-type	
+Pass	Detached Element.querySelector: :first-of-type selector, matching the first td element in each table row: #pseudo-nth-table1 tr :first-of-type	
+Pass	Detached Element.querySelectorAll: :last-of-type selector, matching the last em elemnet: #pseudo-nth-p1 em:last-of-type	
+Pass	Detached Element.querySelector: :last-of-type selector, matching the last em elemnet: #pseudo-nth-p1 em:last-of-type	
+Pass	Detached Element.querySelectorAll: :last-of-type selector, matching the last of every type of element: #pseudo-nth-p1 :last-of-type	
+Pass	Detached Element.querySelector: :last-of-type selector, matching the last of every type of element: #pseudo-nth-p1 :last-of-type	
+Pass	Detached Element.querySelectorAll: :last-of-type selector, matching the last td element in each table row: #pseudo-nth-table1 tr :last-of-type	
+Pass	Detached Element.querySelector: :last-of-type selector, matching the last td element in each table row: #pseudo-nth-table1 tr :last-of-type	
+Pass	Detached Element.querySelectorAll: :first-child pseudo-class selector, matching first child div element: #pseudo-first-child div:first-child	
+Pass	Detached Element.querySelector: :first-child pseudo-class selector, matching first child div element: #pseudo-first-child div:first-child	
+Pass	Detached Element.querySelectorAll: :first-child pseudo-class selector, doesn't match non-first-child elements: .pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child	
+Pass	Detached Element.querySelector: :first-child pseudo-class selector, doesn't match non-first-child elements: .pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child	
+Pass	Detached Element.querySelectorAll: :first-child pseudo-class selector, matching first-child of multiple elements: #pseudo-first-child span:first-child	
+Pass	Detached Element.querySelector: :first-child pseudo-class selector, matching first-child of multiple elements: #pseudo-first-child span:first-child	
+Pass	Detached Element.querySelectorAll: :last-child pseudo-class selector, matching last child div element: #pseudo-last-child div:last-child	
+Pass	Detached Element.querySelector: :last-child pseudo-class selector, matching last child div element: #pseudo-last-child div:last-child	
+Pass	Detached Element.querySelectorAll: :last-child pseudo-class selector, doesn't match non-last-child elements: .pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child	
+Pass	Detached Element.querySelector: :last-child pseudo-class selector, doesn't match non-last-child elements: .pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child	
+Pass	Detached Element.querySelectorAll: :last-child pseudo-class selector, matching first-child of multiple elements: #pseudo-last-child span:last-child	
+Pass	Detached Element.querySelector: :last-child pseudo-class selector, matching first-child of multiple elements: #pseudo-last-child span:last-child	
+Pass	Detached Element.querySelectorAll: :pseudo-only-child pseudo-class selector, matching all only-child elements: #pseudo-only :only-child	
+Pass	Detached Element.querySelector: :pseudo-only-child pseudo-class selector, matching all only-child elements: #pseudo-only :only-child	
+Pass	Detached Element.querySelectorAll: :pseudo-only-child pseudo-class selector, matching only-child em elements: #pseudo-only em:only-child	
+Pass	Detached Element.querySelector: :pseudo-only-child pseudo-class selector, matching only-child em elements: #pseudo-only em:only-child	
+Pass	Detached Element.querySelectorAll: :pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type: #pseudo-only :only-of-type	
+Pass	Detached Element.querySelector: :pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type: #pseudo-only :only-of-type	
+Pass	Detached Element.querySelectorAll: :pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type: #pseudo-only em:only-of-type	
+Pass	Detached Element.querySelector: :pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type: #pseudo-only em:only-of-type	
+Pass	Detached Element.querySelectorAll: :empty pseudo-class selector, matching empty p elements: #pseudo-empty p:empty	
+Pass	Detached Element.querySelector: :empty pseudo-class selector, matching empty p elements: #pseudo-empty p:empty	
+Pass	Detached Element.querySelectorAll: :empty pseudo-class selector, matching all empty elements: #pseudo-empty :empty	
+Pass	Detached Element.querySelector: :empty pseudo-class selector, matching all empty elements: #pseudo-empty :empty	
+Pass	Detached Element.querySelectorAll: :link and :visited pseudo-class selectors, matching a and area elements with href attributes: #pseudo-link :link, #pseudo-link :visited	
+Pass	Detached Element.querySelector: :link and :visited pseudo-class selectors, matching a and area elements with href attributes: #pseudo-link :link, #pseudo-link :visited	
+Pass	Detached Element.querySelectorAll: :link and :visited pseudo-class selectors, not matching link elements with href attributes: #head :link, #head :visited	
+Pass	Detached Element.querySelector: :link and :visited pseudo-class selectors, not matching link elements with href attributes: #head :link, #head :visited	
+Pass	Detached Element.querySelectorAll: :link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing: :link:visited	
+Pass	Detached Element.querySelector: :link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing: :link:visited	
+Pass	Detached Element.querySelectorAll: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target	
+Pass	Detached Element.querySelector: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target	
+Pass	Detached Element.querySelectorAll: :lang pseudo-class selector, not matching element with no inherited language: #pseudo-lang-div1:lang(en)	
+Pass	Detached Element.querySelector: :lang pseudo-class selector, not matching element with no inherited language: #pseudo-lang-div1:lang(en)	
+Pass	Detached Element.querySelectorAll: :lang pseudo-class selector, matching specified language with exact value: #pseudo-lang-div2:lang(fr)	
+Pass	Detached Element.querySelector: :lang pseudo-class selector, matching specified language with exact value: #pseudo-lang-div2:lang(fr)	
+Pass	Detached Element.querySelectorAll: :lang pseudo-class selector, matching specified language with partial value: #pseudo-lang-div3:lang(en)	
+Pass	Detached Element.querySelector: :lang pseudo-class selector, matching specified language with partial value: #pseudo-lang-div3:lang(en)	
+Pass	Detached Element.querySelectorAll: :lang pseudo-class selector, not matching incorrect language: #pseudo-lang-div4:lang(es-AR)	
+Pass	Detached Element.querySelector: :lang pseudo-class selector, not matching incorrect language: #pseudo-lang-div4:lang(es-AR)	
+Pass	Detached Element.querySelectorAll: :enabled pseudo-class selector, matching all enabled form controls: #pseudo-ui :enabled	
+Pass	Detached Element.querySelector: :enabled pseudo-class selector, matching all enabled form controls: #pseudo-ui :enabled	
+Pass	Detached Element.querySelectorAll: :enabled pseudo-class selector, not matching link elements: #pseudo-link :enabled	
+Pass	Detached Element.querySelector: :enabled pseudo-class selector, not matching link elements: #pseudo-link :enabled	
+Pass	Detached Element.querySelectorAll: :disabled pseudo-class selector, matching all disabled form controls: #pseudo-ui :disabled	
+Pass	Detached Element.querySelector: :disabled pseudo-class selector, matching all disabled form controls: #pseudo-ui :disabled	
+Pass	Detached Element.querySelectorAll: :disabled pseudo-class selector, not matching link elements: #pseudo-link :disabled	
+Pass	Detached Element.querySelector: :disabled pseudo-class selector, not matching link elements: #pseudo-link :disabled	
+Pass	Detached Element.querySelectorAll: :checked pseudo-class selector, matching checked radio buttons and checkboxes: #pseudo-ui :checked	
+Pass	Detached Element.querySelector: :checked pseudo-class selector, matching checked radio buttons and checkboxes: #pseudo-ui :checked	
+Pass	Detached Element.querySelectorAll: :not pseudo-class selector, matching : #not>:not(div)	
+Pass	Detached Element.querySelector: :not pseudo-class selector, matching : #not>:not(div)	
+Pass	Detached Element.querySelectorAll: :not pseudo-class selector, matching : #not * :not(:first-child)	
+Pass	Detached Element.querySelector: :not pseudo-class selector, matching : #not * :not(:first-child)	
+Pass	Detached Element.querySelectorAll: :not pseudo-class selector, matching nothing: :not(*)	
+Pass	Detached Element.querySelector: :not pseudo-class selector, matching nothing: :not(*)	
+Pass	Detached Element.querySelectorAll: :not pseudo-class selector, matching nothing: :not(*|*)	
+Pass	Detached Element.querySelector: :not pseudo-class selector, matching nothing: :not(*|*)	
+Pass	Detached Element.querySelectorAll: :not pseudo-class selector argument surrounded by spaces, matching : #not>:not( div )	
+Pass	Detached Element.querySelector: :not pseudo-class selector argument surrounded by spaces, matching : #not>:not( div )	
+Pass	Detached Element.querySelectorAll: :first-line pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-line	
+Pass	Detached Element.querySelector: :first-line pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-line	
+Pass	Detached Element.querySelectorAll: ::first-line pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-line	
+Pass	Detached Element.querySelector: ::first-line pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-line	
+Pass	Detached Element.querySelectorAll: :first-letter pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-letter	
+Pass	Detached Element.querySelector: :first-letter pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-letter	
+Pass	Detached Element.querySelectorAll: ::first-letter pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-letter	
+Pass	Detached Element.querySelector: ::first-letter pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-letter	
+Pass	Detached Element.querySelectorAll: :before pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:before	
+Pass	Detached Element.querySelector: :before pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:before	
+Pass	Detached Element.querySelectorAll: ::before pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::before	
+Pass	Detached Element.querySelector: ::before pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::before	
+Pass	Detached Element.querySelectorAll: :after pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:after	
+Pass	Detached Element.querySelector: :after pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:after	
+Pass	Detached Element.querySelectorAll: ::after pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::after	
+Pass	Detached Element.querySelector: ::after pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::after	
+Pass	Detached Element.querySelectorAll: Class selector, matching element with specified class: .class-p	
+Pass	Detached Element.querySelector: Class selector, matching element with specified class: .class-p	
+Pass	Detached Element.querySelectorAll: Class selector, chained, matching only elements with all specified classes: #class .apple.orange.banana	
+Pass	Detached Element.querySelector: Class selector, chained, matching only elements with all specified classes: #class .apple.orange.banana	
+Pass	Detached Element.querySelectorAll: Class Selector, chained, with type selector: div.apple.banana.orange	
+Pass	Detached Element.querySelector: Class Selector, chained, with type selector: div.apple.banana.orange	
+Pass	Detached Element.querySelectorAll: Class selector, matching element with class value using non-ASCII characters (1): .台北Táiběi	
+Pass	Detached Element.querySelector: Class selector, matching element with class value using non-ASCII characters (1): .台北Táiběi	
+Pass	Detached Element.querySelectorAll: Class selector, matching multiple elements with class value using non-ASCII characters: .台北	
+Pass	Detached Element.querySelector: Class selector, matching multiple elements with class value using non-ASCII characters: .台北	
+Pass	Detached Element.querySelectorAll: Class selector, chained, matching element with multiple class values using non-ASCII characters (1): .台北Táiběi.台北	
+Pass	Detached Element.querySelector: Class selector, chained, matching element with multiple class values using non-ASCII characters (1): .台北Táiběi.台北	
+Pass	Detached Element.querySelectorAll: Class selector, matching element with class with escaped character: .foo\:bar	
+Pass	Detached Element.querySelector: Class selector, matching element with class with escaped character: .foo\:bar	
+Pass	Detached Element.querySelectorAll: Class selector, matching element with class with escaped character: .test\.foo\[5\]bar	
+Pass	Detached Element.querySelector: Class selector, matching element with class with escaped character: .test\.foo\[5\]bar	
+Pass	Detached Element.querySelectorAll: ID selector, matching element with specified id: #id #id-div1	
+Pass	Detached Element.querySelector: ID selector, matching element with specified id: #id #id-div1	
+Fail	Detached Element.querySelectorAll: ID selector, chained, matching element with specified id: #id-div1, #id-div1	
+Pass	Detached Element.querySelector: ID selector, chained, matching element with specified id: #id-div1, #id-div1	
+Pass	Detached Element.querySelectorAll: ID selector, chained, matching element with specified id: #id-div1, #id-div2	
+Pass	Detached Element.querySelector: ID selector, chained, matching element with specified id: #id-div1, #id-div2	
+Pass	Detached Element.querySelectorAll: ID Selector, chained, with type selector: div#id-div1, div#id-div2	
+Pass	Detached Element.querySelector: ID Selector, chained, with type selector: div#id-div1, div#id-div2	
+Pass	Detached Element.querySelectorAll: ID selector, not matching non-existent descendant: #id #none	
+Pass	Detached Element.querySelector: ID selector, not matching non-existent descendant: #id #none	
+Pass	Detached Element.querySelectorAll: ID selector, not matching non-existent ancestor: #none #id-div1	
+Pass	Detached Element.querySelector: ID selector, not matching non-existent ancestor: #none #id-div1	
+Pass	Detached Element.querySelectorAll: ID selector, matching multiple elements with duplicate id: #id-li-duplicate	
+Pass	Detached Element.querySelector: ID selector, matching multiple elements with duplicate id: #id-li-duplicate	
+Pass	Detached Element.querySelectorAll: ID selector, matching id value using non-ASCII characters (1): #台北Táiběi	
+Pass	Detached Element.querySelector: ID selector, matching id value using non-ASCII characters (1): #台北Táiběi	
+Pass	Detached Element.querySelectorAll: ID selector, matching id value using non-ASCII characters (2): #台北	
+Pass	Detached Element.querySelector: ID selector, matching id value using non-ASCII characters (2): #台北	
+Pass	Detached Element.querySelectorAll: ID selector, matching id values using non-ASCII characters (1): #台北Táiběi, #台北	
+Pass	Detached Element.querySelector: ID selector, matching id values using non-ASCII characters (1): #台北Táiběi, #台北	
+Pass	Detached Element.querySelectorAll: ID selector, matching element with id with escaped character: #\#foo\:bar	
+Pass	Detached Element.querySelector: ID selector, matching element with id with escaped character: #\#foo\:bar	
+Pass	Detached Element.querySelectorAll: ID selector, matching element with id with escaped character: #test\.foo\[5\]bar	
+Pass	Detached Element.querySelector: ID selector, matching element with id with escaped character: #test\.foo\[5\]bar	
+Pass	Detached Element.querySelectorAll: Namespace selector, matching element with any namespace: #any-namespace *|div	
+Pass	Detached Element.querySelector: Namespace selector, matching element with any namespace: #any-namespace *|div	
+Pass	Detached Element.querySelectorAll: Namespace selector, matching div elements in no namespace only: #no-namespace |div	
+Pass	Detached Element.querySelector: Namespace selector, matching div elements in no namespace only: #no-namespace |div	
+Pass	Detached Element.querySelectorAll: Namespace selector, matching any elements in no namespace only: #no-namespace |*	
+Pass	Detached Element.querySelector: Namespace selector, matching any elements in no namespace only: #no-namespace |*	
+Pass	Detached Element.querySelectorAll: Descendant combinator, matching element that is a descendant of an element with id: #descendant div	
+Pass	Detached Element.querySelector: Descendant combinator, matching element that is a descendant of an element with id: #descendant div	
+Pass	Detached Element.querySelectorAll: Descendant combinator, matching element with id that is a descendant of an element: div #descendant-div1	
+Pass	Detached Element.querySelector: Descendant combinator, matching element with id that is a descendant of an element: div #descendant-div1	
+Pass	Detached Element.querySelectorAll: Descendant combinator, matching element with id that is a descendant of an element with id: #descendant #descendant-div2	
+Pass	Detached Element.querySelector: Descendant combinator, matching element with id that is a descendant of an element with id: #descendant #descendant-div2	
+Pass	Detached Element.querySelectorAll: Descendant combinator, matching element with class that is a descendant of an element with id: #descendant .descendant-div2	
+Pass	Detached Element.querySelector: Descendant combinator, matching element with class that is a descendant of an element with id: #descendant .descendant-div2	
+Pass	Detached Element.querySelectorAll: Descendant combinator, matching element with class that is a descendant of an element with class: .descendant-div1 .descendant-div3	
+Pass	Detached Element.querySelector: Descendant combinator, matching element with class that is a descendant of an element with class: .descendant-div1 .descendant-div3	
+Pass	Detached Element.querySelectorAll: Descendant combinator, not matching element with id that is not a descendant of an element with id: #descendant-div1 #descendant-div4	
+Pass	Detached Element.querySelector: Descendant combinator, not matching element with id that is not a descendant of an element with id: #descendant-div1 #descendant-div4	
+Pass	Detached Element.querySelectorAll: Descendant combinator, whitespace characters: #descendant #descendant-div2	
+Pass	Detached Element.querySelector: Descendant combinator, whitespace characters: #descendant #descendant-div2	
+Pass	Detached Element.querySelectorAll: Child combinator, matching element that is a child of an element with id: #child>div	
+Pass	Detached Element.querySelector: Child combinator, matching element that is a child of an element with id: #child>div	
+Pass	Detached Element.querySelectorAll: Child combinator, matching element with id that is a child of an element: div>#child-div1	
+Pass	Detached Element.querySelector: Child combinator, matching element with id that is a child of an element: div>#child-div1	
+Pass	Detached Element.querySelectorAll: Child combinator, matching element with id that is a child of an element with id: #child>#child-div1	
+Pass	Detached Element.querySelector: Child combinator, matching element with id that is a child of an element with id: #child>#child-div1	
+Pass	Detached Element.querySelectorAll: Child combinator, matching element with id that is a child of an element with class: #child-div1>.child-div2	
+Pass	Detached Element.querySelector: Child combinator, matching element with id that is a child of an element with class: #child-div1>.child-div2	
+Pass	Detached Element.querySelectorAll: Child combinator, matching element with class that is a child of an element with class: .child-div1>.child-div2	
+Pass	Detached Element.querySelector: Child combinator, matching element with class that is a child of an element with class: .child-div1>.child-div2	
+Pass	Detached Element.querySelectorAll: Child combinator, not matching element with id that is not a child of an element with id: #child>#child-div3	
+Pass	Detached Element.querySelector: Child combinator, not matching element with id that is not a child of an element with id: #child>#child-div3	
+Pass	Detached Element.querySelectorAll: Child combinator, not matching element with id that is not a child of an element with class: #child-div1>.child-div3	
+Pass	Detached Element.querySelector: Child combinator, not matching element with id that is not a child of an element with class: #child-div1>.child-div3	
+Pass	Detached Element.querySelectorAll: Child combinator, not matching element with class that is not a child of an element with class: .child-div1>.child-div3	
+Pass	Detached Element.querySelector: Child combinator, not matching element with class that is not a child of an element with class: .child-div1>.child-div3	
+Pass	Detached Element.querySelectorAll: Child combinator, surrounded by whitespace: #child-div1 > #child-div2	
+Pass	Detached Element.querySelector: Child combinator, surrounded by whitespace: #child-div1 > #child-div2	
+Pass	Detached Element.querySelectorAll: Child combinator, whitespace after: #child-div1> #child-div2	
+Pass	Detached Element.querySelector: Child combinator, whitespace after: #child-div1> #child-div2	
+Pass	Detached Element.querySelectorAll: Child combinator, whitespace before: #child-div1 >#child-div2	
+Pass	Detached Element.querySelector: Child combinator, whitespace before: #child-div1 >#child-div2	
+Pass	Detached Element.querySelectorAll: Child combinator, no whitespace: #child-div1>#child-div2	
+Pass	Detached Element.querySelector: Child combinator, no whitespace: #child-div1>#child-div2	
+Pass	Detached Element.querySelectorAll: Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id: #adjacent-div2+div	
+Pass	Detached Element.querySelector: Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id: #adjacent-div2+div	
+Pass	Detached Element.querySelectorAll: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element: div+#adjacent-div4	
+Pass	Detached Element.querySelector: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element: div+#adjacent-div4	
+Pass	Detached Element.querySelectorAll: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id: #adjacent-div2+#adjacent-div4	
+Pass	Detached Element.querySelector: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id: #adjacent-div2+#adjacent-div4	
+Pass	Detached Element.querySelectorAll: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id: #adjacent-div2+.adjacent-div4	
+Pass	Detached Element.querySelector: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id: #adjacent-div2+.adjacent-div4	
+Pass	Detached Element.querySelectorAll: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class: .adjacent-div2+.adjacent-div4	
+Pass	Detached Element.querySelector: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class: .adjacent-div2+.adjacent-div4	
+Pass	Detached Element.querySelectorAll: Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element: #adjacent div+p	
+Pass	Detached Element.querySelector: Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element: #adjacent div+p	
+Pass	Detached Element.querySelectorAll: Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id: #adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1	
+Pass	Detached Element.querySelector: Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id: #adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1	
+Pass	Detached Element.querySelectorAll: Adjacent sibling combinator, surrounded by whitespace: #adjacent-p2 + #adjacent-p3	
+Pass	Detached Element.querySelector: Adjacent sibling combinator, surrounded by whitespace: #adjacent-p2 + #adjacent-p3	
+Pass	Detached Element.querySelectorAll: Adjacent sibling combinator, whitespace after: #adjacent-p2+ #adjacent-p3	
+Pass	Detached Element.querySelector: Adjacent sibling combinator, whitespace after: #adjacent-p2+ #adjacent-p3	
+Pass	Detached Element.querySelectorAll: Adjacent sibling combinator, whitespace before: #adjacent-p2 +#adjacent-p3	
+Pass	Detached Element.querySelector: Adjacent sibling combinator, whitespace before: #adjacent-p2 +#adjacent-p3	
+Pass	Detached Element.querySelectorAll: Adjacent sibling combinator, no whitespace: #adjacent-p2+#adjacent-p3	
+Pass	Detached Element.querySelector: Adjacent sibling combinator, no whitespace: #adjacent-p2+#adjacent-p3	
+Pass	Detached Element.querySelectorAll: General sibling combinator, matching element that is a sibling of an element with id: #sibling-div2~div	
+Pass	Detached Element.querySelector: General sibling combinator, matching element that is a sibling of an element with id: #sibling-div2~div	
+Pass	Detached Element.querySelectorAll: General sibling combinator, matching element with id that is a sibling of an element: div~#sibling-div4	
+Pass	Detached Element.querySelector: General sibling combinator, matching element with id that is a sibling of an element: div~#sibling-div4	
+Pass	Detached Element.querySelectorAll: General sibling combinator, matching element with id that is a sibling of an element with id: #sibling-div2~#sibling-div4	
+Pass	Detached Element.querySelector: General sibling combinator, matching element with id that is a sibling of an element with id: #sibling-div2~#sibling-div4	
+Pass	Detached Element.querySelectorAll: General sibling combinator, matching element with class that is a sibling of an element with id: #sibling-div2~.sibling-div	
+Pass	Detached Element.querySelector: General sibling combinator, matching element with class that is a sibling of an element with id: #sibling-div2~.sibling-div	
+Pass	Detached Element.querySelectorAll: General sibling combinator, matching p element that is a sibling of a div element: #sibling div~p	
+Pass	Detached Element.querySelector: General sibling combinator, matching p element that is a sibling of a div element: #sibling div~p	
+Pass	Detached Element.querySelectorAll: General sibling combinator, not matching element with id that is not a sibling after a p element: #sibling>p~div	
+Pass	Detached Element.querySelector: General sibling combinator, not matching element with id that is not a sibling after a p element: #sibling>p~div	
+Pass	Detached Element.querySelectorAll: General sibling combinator, not matching element with id that is not a sibling after an element with id: #sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1	
+Pass	Detached Element.querySelector: General sibling combinator, not matching element with id that is not a sibling after an element with id: #sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1	
+Pass	Detached Element.querySelectorAll: General sibling combinator, surrounded by whitespace: #sibling-p2 ~ #sibling-p3	
+Pass	Detached Element.querySelector: General sibling combinator, surrounded by whitespace: #sibling-p2 ~ #sibling-p3	
+Pass	Detached Element.querySelectorAll: General sibling combinator, whitespace after: #sibling-p2~ #sibling-p3	
+Pass	Detached Element.querySelector: General sibling combinator, whitespace after: #sibling-p2~ #sibling-p3	
+Pass	Detached Element.querySelectorAll: General sibling combinator, whitespace before: #sibling-p2 ~#sibling-p3	
+Pass	Detached Element.querySelector: General sibling combinator, whitespace before: #sibling-p2 ~#sibling-p3	
+Pass	Detached Element.querySelectorAll: General sibling combinator, no whitespace: #sibling-p2~#sibling-p3	
+Pass	Detached Element.querySelector: General sibling combinator, no whitespace: #sibling-p2~#sibling-p3	
+Pass	Detached Element.querySelectorAll: Syntax, group of selectors separator, surrounded by whitespace: #group em , #group strong	
+Pass	Detached Element.querySelector: Syntax, group of selectors separator, surrounded by whitespace: #group em , #group strong	
+Pass	Detached Element.querySelectorAll: Syntax, group of selectors separator, whitespace after: #group em, #group strong	
+Pass	Detached Element.querySelector: Syntax, group of selectors separator, whitespace after: #group em, #group strong	
+Pass	Detached Element.querySelectorAll: Syntax, group of selectors separator, whitespace before: #group em ,#group strong	
+Pass	Detached Element.querySelector: Syntax, group of selectors separator, whitespace before: #group em ,#group strong	
+Pass	Detached Element.querySelectorAll: Syntax, group of selectors separator, no whitespace: #group em,#group strong	
+Pass	Detached Element.querySelector: Syntax, group of selectors separator, no whitespace: #group em,#group strong	
+Fail	Detached Element.querySelectorAll: Slotted selector: ::slotted(foo)	Failed to parse selector
+Fail	Detached Element.querySelector: Slotted selector: ::slotted(foo)	Failed to parse selector
+Fail	Detached Element.querySelectorAll: Slotted selector (no matching closing paren): ::slotted(foo	Failed to parse selector
+Fail	Detached Element.querySelector: Slotted selector (no matching closing paren): ::slotted(foo	Failed to parse selector
+Pass	Fragment.querySelectorAll: Type selector, matching html element: html	
+Pass	Fragment.querySelector: Type selector, matching html element: html	
+Pass	Fragment.querySelectorAll: Type selector, matching body element: body	
+Pass	Fragment.querySelector: Type selector, matching body element: body	
+Pass	Fragment.querySelectorAll: Universal selector, matching all children of element with specified ID: #universal>*	
+Pass	Fragment.querySelector: Universal selector, matching all children of element with specified ID: #universal>*	
+Pass	Fragment.querySelectorAll: Universal selector, matching all grandchildren of element with specified ID: #universal>*>*	
+Pass	Fragment.querySelector: Universal selector, matching all grandchildren of element with specified ID: #universal>*>*	
+Pass	Fragment.querySelectorAll: Universal selector, matching all children of empty element with specified ID: #empty>*	
+Pass	Fragment.querySelector: Universal selector, matching all children of empty element with specified ID: #empty>*	
+Pass	Fragment.querySelectorAll: Universal selector, matching all descendants of element with specified ID: #universal *	
+Pass	Fragment.querySelector: Universal selector, matching all descendants of element with specified ID: #universal *	
+Pass	Fragment.querySelectorAll: Attribute presence selector, matching align attribute with value: .attr-presence-div1[align]	
+Pass	Fragment.querySelector: Attribute presence selector, matching align attribute with value: .attr-presence-div1[align]	
+Pass	Fragment.querySelectorAll: Attribute presence selector, matching align attribute with empty value: .attr-presence-div2[align]	
+Pass	Fragment.querySelector: Attribute presence selector, matching align attribute with empty value: .attr-presence-div2[align]	
+Fail	Fragment.querySelectorAll: Attribute presence selector, matching title attribute, case insensitivity: #attr-presence [*|TiTlE]	
+Fail	Fragment.querySelector: Attribute presence selector, matching title attribute, case insensitivity: #attr-presence [*|TiTlE]	
+Pass	Fragment.querySelectorAll: Attribute presence selector, matching custom data-* attribute: [data-attr-presence]	
+Pass	Fragment.querySelector: Attribute presence selector, matching custom data-* attribute: [data-attr-presence]	
+Pass	Fragment.querySelectorAll: Attribute presence selector, not matching attribute with similar name: .attr-presence-div3[align], .attr-presence-div4[align]	
+Pass	Fragment.querySelector: Attribute presence selector, not matching attribute with similar name: .attr-presence-div3[align], .attr-presence-div4[align]	
+Pass	Fragment.querySelectorAll: Attribute presence selector, matching attribute with non-ASCII characters: ul[data-中文]	
+Pass	Fragment.querySelector: Attribute presence selector, matching attribute with non-ASCII characters: ul[data-中文]	
+Pass	Fragment.querySelectorAll: Attribute presence selector, not matching default option without selected attribute: #attr-presence-select1 option[selected]	
+Pass	Fragment.querySelector: Attribute presence selector, not matching default option without selected attribute: #attr-presence-select1 option[selected]	
+Pass	Fragment.querySelectorAll: Attribute presence selector, matching option with selected attribute: #attr-presence-select2 option[selected]	
+Pass	Fragment.querySelector: Attribute presence selector, matching option with selected attribute: #attr-presence-select2 option[selected]	
+Pass	Fragment.querySelectorAll: Attribute presence selector, matching multiple options with selected attributes: #attr-presence-select3 option[selected]	
+Pass	Fragment.querySelector: Attribute presence selector, matching multiple options with selected attributes: #attr-presence-select3 option[selected]	
+Pass	Fragment.querySelectorAll: Attribute value selector, matching align attribute with value: #attr-value [align="center"]	
+Pass	Fragment.querySelector: Attribute value selector, matching align attribute with value: #attr-value [align="center"]	
+Pass	Fragment.querySelectorAll: Attribute value selector, matching align attribute with value, unclosed bracket: #attr-value [align="center"	
+Pass	Fragment.querySelector: Attribute value selector, matching align attribute with value, unclosed bracket: #attr-value [align="center"	
+Pass	Fragment.querySelectorAll: Attribute value selector, matching align attribute with empty value: #attr-value [align=""]	
+Pass	Fragment.querySelector: Attribute value selector, matching align attribute with empty value: #attr-value [align=""]	
+Pass	Fragment.querySelectorAll: Attribute value selector, not matching align attribute with partial value: #attr-value [align="c"]	
+Pass	Fragment.querySelector: Attribute value selector, not matching align attribute with partial value: #attr-value [align="c"]	
+Pass	Fragment.querySelectorAll: Attribute value selector, not matching align attribute with incorrect value: #attr-value [align="centera"]	
+Pass	Fragment.querySelector: Attribute value selector, not matching align attribute with incorrect value: #attr-value [align="centera"]	
+Pass	Fragment.querySelectorAll: Attribute value selector, matching custom data-* attribute with unicode escaped value: [data-attr-value="\e9"]	
+Pass	Fragment.querySelector: Attribute value selector, matching custom data-* attribute with unicode escaped value: [data-attr-value="\e9"]	
+Pass	Fragment.querySelectorAll: Attribute value selector, matching custom data-* attribute with escaped character: [data-attr-value_foo="\e9"]	
+Pass	Fragment.querySelector: Attribute value selector, matching custom data-* attribute with escaped character: [data-attr-value_foo="\e9"]	
+Pass	Fragment.querySelectorAll: Attribute value selector with single-quoted value, matching multiple inputs with type attributes: #attr-value input[type='hidden'],#attr-value input[type='radio']	
+Pass	Fragment.querySelector: Attribute value selector with single-quoted value, matching multiple inputs with type attributes: #attr-value input[type='hidden'],#attr-value input[type='radio']	
+Pass	Fragment.querySelectorAll: Attribute value selector with double-quoted value, matching multiple inputs with type attributes: #attr-value input[type="hidden"],#attr-value input[type='radio']	
+Pass	Fragment.querySelector: Attribute value selector with double-quoted value, matching multiple inputs with type attributes: #attr-value input[type="hidden"],#attr-value input[type='radio']	
+Pass	Fragment.querySelectorAll: Attribute value selector with unquoted value, matching multiple inputs with type attributes: #attr-value input[type=hidden],#attr-value input[type=radio]	
+Pass	Fragment.querySelector: Attribute value selector with unquoted value, matching multiple inputs with type attributes: #attr-value input[type=hidden],#attr-value input[type=radio]	
+Pass	Fragment.querySelectorAll: Attribute value selector, matching attribute with value using non-ASCII characters: [data-attr-value=中文]	
+Pass	Fragment.querySelector: Attribute value selector, matching attribute with value using non-ASCII characters: [data-attr-value=中文]	
+Pass	Fragment.querySelectorAll: Attribute whitespace-separated list selector, matching class attribute with value: #attr-whitespace [class~="div1"]	
+Pass	Fragment.querySelector: Attribute whitespace-separated list selector, matching class attribute with value: #attr-whitespace [class~="div1"]	
+Pass	Fragment.querySelectorAll: Attribute whitespace-separated list selector, not matching class attribute with empty value: #attr-whitespace [class~=""]	
+Pass	Fragment.querySelector: Attribute whitespace-separated list selector, not matching class attribute with empty value: #attr-whitespace [class~=""]	
+Pass	Fragment.querySelectorAll: Attribute whitespace-separated list selector, not matching class attribute with partial value: [data-attr-whitespace~="div"]	
+Pass	Fragment.querySelector: Attribute whitespace-separated list selector, not matching class attribute with partial value: [data-attr-whitespace~="div"]	
+Pass	Fragment.querySelectorAll: Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value: [data-attr-whitespace~="\0000e9"]	
+Pass	Fragment.querySelector: Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value: [data-attr-whitespace~="\0000e9"]	
+Pass	Fragment.querySelectorAll: Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character: [data-attr-whitespace_foo~="\e9"]	
+Pass	Fragment.querySelector: Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character: [data-attr-whitespace_foo~="\e9"]	
+Pass	Fragment.querySelectorAll: Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~='bookmark'], #attr-whitespace a[rel~='nofollow']	
+Pass	Fragment.querySelector: Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~='bookmark'], #attr-whitespace a[rel~='nofollow']	
+Pass	Fragment.querySelectorAll: Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~="bookmark"],#attr-whitespace a[rel~='nofollow']	
+Pass	Fragment.querySelector: Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~="bookmark"],#attr-whitespace a[rel~='nofollow']	
+Pass	Fragment.querySelectorAll: Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~=bookmark], #attr-whitespace a[rel~=nofollow]	
+Pass	Fragment.querySelector: Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~=bookmark], #attr-whitespace a[rel~=nofollow]	
+Pass	Fragment.querySelectorAll: Attribute whitespace-separated list selector with double-quoted value, not matching value with space: #attr-whitespace a[rel~="book mark"]	
+Pass	Fragment.querySelector: Attribute whitespace-separated list selector with double-quoted value, not matching value with space: #attr-whitespace a[rel~="book mark"]	
+Pass	Fragment.querySelectorAll: Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters: #attr-whitespace [title~=中文]	
+Pass	Fragment.querySelector: Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters: #attr-whitespace [title~=中文]	
+Pass	Fragment.querySelectorAll: Attribute hyphen-separated list selector, not matching unspecified lang attribute: #attr-hyphen-div1[lang|="en"]	
+Pass	Fragment.querySelector: Attribute hyphen-separated list selector, not matching unspecified lang attribute: #attr-hyphen-div1[lang|="en"]	
+Pass	Fragment.querySelectorAll: Attribute hyphen-separated list selector, matching lang attribute with exact value: #attr-hyphen-div2[lang|="fr"]	
+Pass	Fragment.querySelector: Attribute hyphen-separated list selector, matching lang attribute with exact value: #attr-hyphen-div2[lang|="fr"]	
+Pass	Fragment.querySelectorAll: Attribute hyphen-separated list selector, matching lang attribute with partial value: #attr-hyphen-div3[lang|="en"]	
+Pass	Fragment.querySelector: Attribute hyphen-separated list selector, matching lang attribute with partial value: #attr-hyphen-div3[lang|="en"]	
+Pass	Fragment.querySelectorAll: Attribute hyphen-separated list selector, not matching incorrect value: #attr-hyphen-div4[lang|="es-AR"]	
+Pass	Fragment.querySelector: Attribute hyphen-separated list selector, not matching incorrect value: #attr-hyphen-div4[lang|="es-AR"]	
+Pass	Fragment.querySelectorAll: Attribute begins with selector, matching href attributes beginning with specified substring: #attr-begins a[href^="http://www"]	
+Pass	Fragment.querySelector: Attribute begins with selector, matching href attributes beginning with specified substring: #attr-begins a[href^="http://www"]	
+Pass	Fragment.querySelectorAll: Attribute begins with selector, matching lang attributes beginning with specified substring, : #attr-begins [lang^="en-"]	
+Pass	Fragment.querySelector: Attribute begins with selector, matching lang attributes beginning with specified substring, : #attr-begins [lang^="en-"]	
+Pass	Fragment.querySelectorAll: Attribute begins with selector, not matching class attribute with empty value: #attr-begins [class^=""]	
+Pass	Fragment.querySelector: Attribute begins with selector, not matching class attribute with empty value: #attr-begins [class^=""]	
+Pass	Fragment.querySelectorAll: Attribute begins with selector, not matching class attribute not beginning with specified substring: #attr-begins [class^=apple]	
+Pass	Fragment.querySelector: Attribute begins with selector, not matching class attribute not beginning with specified substring: #attr-begins [class^=apple]	
+Pass	Fragment.querySelectorAll: Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=' apple']	
+Pass	Fragment.querySelector: Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=' apple']	
+Pass	Fragment.querySelectorAll: Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=" apple"]	
+Pass	Fragment.querySelector: Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=" apple"]	
+Pass	Fragment.querySelectorAll: Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring: #attr-begins [class^= apple]	
+Pass	Fragment.querySelector: Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring: #attr-begins [class^= apple]	
+Pass	Fragment.querySelectorAll: Attribute ends with selector, matching href attributes ending with specified substring: #attr-ends a[href$=".org"]	
+Pass	Fragment.querySelector: Attribute ends with selector, matching href attributes ending with specified substring: #attr-ends a[href$=".org"]	
+Pass	Fragment.querySelectorAll: Attribute ends with selector, matching lang attributes ending with specified substring, : #attr-ends [lang$="-CH"]	
+Pass	Fragment.querySelector: Attribute ends with selector, matching lang attributes ending with specified substring, : #attr-ends [lang$="-CH"]	
+Pass	Fragment.querySelectorAll: Attribute ends with selector, not matching class attribute with empty value: #attr-ends [class$=""]	
+Pass	Fragment.querySelector: Attribute ends with selector, not matching class attribute with empty value: #attr-ends [class$=""]	
+Pass	Fragment.querySelectorAll: Attribute ends with selector, not matching class attribute not ending with specified substring: #attr-ends [class$=apple]	
+Pass	Fragment.querySelector: Attribute ends with selector, not matching class attribute not ending with specified substring: #attr-ends [class$=apple]	
+Pass	Fragment.querySelectorAll: Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring: #attr-ends [class$='apple ']	
+Pass	Fragment.querySelector: Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring: #attr-ends [class$='apple ']	
+Pass	Fragment.querySelectorAll: Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring: #attr-ends [class$="apple "]	
+Pass	Fragment.querySelector: Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring: #attr-ends [class$="apple "]	
+Pass	Fragment.querySelectorAll: Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring: #attr-ends [class$=apple ]	
+Pass	Fragment.querySelector: Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring: #attr-ends [class$=apple ]	
+Pass	Fragment.querySelectorAll: Attribute contains selector, matching href attributes beginning with specified substring: #attr-contains a[href*="http://www"]	
+Pass	Fragment.querySelector: Attribute contains selector, matching href attributes beginning with specified substring: #attr-contains a[href*="http://www"]	
+Pass	Fragment.querySelectorAll: Attribute contains selector, matching href attributes ending with specified substring: #attr-contains a[href*=".org"]	
+Pass	Fragment.querySelector: Attribute contains selector, matching href attributes ending with specified substring: #attr-contains a[href*=".org"]	
+Pass	Fragment.querySelectorAll: Attribute contains selector, matching href attributes containing specified substring: #attr-contains a[href*=".example."]	
+Pass	Fragment.querySelector: Attribute contains selector, matching href attributes containing specified substring: #attr-contains a[href*=".example."]	
+Pass	Fragment.querySelectorAll: Attribute contains selector, matching lang attributes beginning with specified substring, : #attr-contains [lang*="en-"]	
+Pass	Fragment.querySelector: Attribute contains selector, matching lang attributes beginning with specified substring, : #attr-contains [lang*="en-"]	
+Pass	Fragment.querySelectorAll: Attribute contains selector, matching lang attributes ending with specified substring, : #attr-contains [lang*="-CH"]	
+Pass	Fragment.querySelector: Attribute contains selector, matching lang attributes ending with specified substring, : #attr-contains [lang*="-CH"]	
+Pass	Fragment.querySelectorAll: Attribute contains selector, not matching class attribute with empty value: #attr-contains [class*=""]	
+Pass	Fragment.querySelector: Attribute contains selector, not matching class attribute with empty value: #attr-contains [class*=""]	
+Pass	Fragment.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=' apple']	
+Pass	Fragment.querySelector: Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=' apple']	
+Pass	Fragment.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute ending with specified substring: #attr-contains [class*='orange ']	
+Pass	Fragment.querySelector: Attribute contains selector with single-quoted value, matching class attribute ending with specified substring: #attr-contains [class*='orange ']	
+Pass	Fragment.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute containing specified substring: #attr-contains [class*='ple banana ora']	
+Pass	Fragment.querySelector: Attribute contains selector with single-quoted value, matching class attribute containing specified substring: #attr-contains [class*='ple banana ora']	
+Pass	Fragment.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=" apple"]	
+Pass	Fragment.querySelector: Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=" apple"]	
+Pass	Fragment.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute ending with specified substring: #attr-contains [class*="orange "]	
+Pass	Fragment.querySelector: Attribute contains selector with double-quoted value, matching class attribute ending with specified substring: #attr-contains [class*="orange "]	
+Pass	Fragment.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute containing specified substring: #attr-contains [class*="ple banana ora"]	
+Pass	Fragment.querySelector: Attribute contains selector with double-quoted value, matching class attribute containing specified substring: #attr-contains [class*="ple banana ora"]	
+Pass	Fragment.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute beginning with specified substring: #attr-contains [class*= apple]	
+Pass	Fragment.querySelector: Attribute contains selector with unquoted value, matching class attribute beginning with specified substring: #attr-contains [class*= apple]	
+Pass	Fragment.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute ending with specified substring: #attr-contains [class*=orange ]	
+Pass	Fragment.querySelector: Attribute contains selector with unquoted value, matching class attribute ending with specified substring: #attr-contains [class*=orange ]	
+Pass	Fragment.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute containing specified substring: #attr-contains [class*= banana ]	
+Pass	Fragment.querySelector: Attribute contains selector with unquoted value, matching class attribute containing specified substring: #attr-contains [class*= banana ]	
+Pass	Fragment.querySelectorAll: :root pseudo-class selector, not matching document root element: :root	
+Pass	Fragment.querySelector: :root pseudo-class selector, not matching document root element: :root	
+Pass	Fragment.querySelectorAll: :nth-child selector, matching the third child element: #pseudo-nth-table1 :nth-child(3)	
+Pass	Fragment.querySelector: :nth-child selector, matching the third child element: #pseudo-nth-table1 :nth-child(3)	
+Pass	Fragment.querySelectorAll: :nth-child selector, matching every third child element: #pseudo-nth li:nth-child(3n)	
+Pass	Fragment.querySelector: :nth-child selector, matching every third child element: #pseudo-nth li:nth-child(3n)	
+Pass	Fragment.querySelectorAll: :nth-child selector, matching every second child element, starting from the fourth: #pseudo-nth li:nth-child(2n+4)	
+Pass	Fragment.querySelector: :nth-child selector, matching every second child element, starting from the fourth: #pseudo-nth li:nth-child(2n+4)	
+Pass	Fragment.querySelectorAll: :nth-child selector, matching every fourth child element, starting from the third: #pseudo-nth-p1 :nth-child(4n-1)	
+Pass	Fragment.querySelector: :nth-child selector, matching every fourth child element, starting from the third: #pseudo-nth-p1 :nth-child(4n-1)	
+Pass	Fragment.querySelectorAll: :nth-last-child selector, matching the third last child element: #pseudo-nth-table1 :nth-last-child(3)	
+Pass	Fragment.querySelector: :nth-last-child selector, matching the third last child element: #pseudo-nth-table1 :nth-last-child(3)	
+Pass	Fragment.querySelectorAll: :nth-last-child selector, matching every third child element from the end: #pseudo-nth li:nth-last-child(3n)	
+Pass	Fragment.querySelector: :nth-last-child selector, matching every third child element from the end: #pseudo-nth li:nth-last-child(3n)	
+Pass	Fragment.querySelectorAll: :nth-last-child selector, matching every second child element from the end, starting from the fourth last: #pseudo-nth li:nth-last-child(2n+4)	
+Pass	Fragment.querySelector: :nth-last-child selector, matching every second child element from the end, starting from the fourth last: #pseudo-nth li:nth-last-child(2n+4)	
+Pass	Fragment.querySelectorAll: :nth-last-child selector, matching every fourth element from the end, starting from the third last: #pseudo-nth-p1 :nth-last-child(4n-1)	
+Pass	Fragment.querySelector: :nth-last-child selector, matching every fourth element from the end, starting from the third last: #pseudo-nth-p1 :nth-last-child(4n-1)	
+Pass	Fragment.querySelectorAll: :nth-of-type selector, matching the third em element: #pseudo-nth-p1 em:nth-of-type(3)	
+Pass	Fragment.querySelector: :nth-of-type selector, matching the third em element: #pseudo-nth-p1 em:nth-of-type(3)	
+Pass	Fragment.querySelectorAll: :nth-of-type selector, matching every second element of their type: #pseudo-nth-p1 :nth-of-type(2n)	
+Pass	Fragment.querySelector: :nth-of-type selector, matching every second element of their type: #pseudo-nth-p1 :nth-of-type(2n)	
+Pass	Fragment.querySelectorAll: :nth-of-type selector, matching every second elemetn of their type, starting from the first: #pseudo-nth-p1 span:nth-of-type(2n-1)	
+Pass	Fragment.querySelector: :nth-of-type selector, matching every second elemetn of their type, starting from the first: #pseudo-nth-p1 span:nth-of-type(2n-1)	
+Pass	Fragment.querySelectorAll: :nth-last-of-type selector, matching the third last em element: #pseudo-nth-p1 em:nth-last-of-type(3)	
+Pass	Fragment.querySelector: :nth-last-of-type selector, matching the third last em element: #pseudo-nth-p1 em:nth-last-of-type(3)	
+Pass	Fragment.querySelectorAll: :nth-last-of-type selector, matching every second last element of their type: #pseudo-nth-p1 :nth-last-of-type(2n)	
+Pass	Fragment.querySelector: :nth-last-of-type selector, matching every second last element of their type: #pseudo-nth-p1 :nth-last-of-type(2n)	
+Pass	Fragment.querySelectorAll: :nth-last-of-type selector, matching every second last element of their type, starting from the last: #pseudo-nth-p1 span:nth-last-of-type(2n-1)	
+Pass	Fragment.querySelector: :nth-last-of-type selector, matching every second last element of their type, starting from the last: #pseudo-nth-p1 span:nth-last-of-type(2n-1)	
+Pass	Fragment.querySelectorAll: :first-of-type selector, matching the first em element: #pseudo-nth-p1 em:first-of-type	
+Pass	Fragment.querySelector: :first-of-type selector, matching the first em element: #pseudo-nth-p1 em:first-of-type	
+Pass	Fragment.querySelectorAll: :first-of-type selector, matching the first of every type of element: #pseudo-nth-p1 :first-of-type	
+Pass	Fragment.querySelector: :first-of-type selector, matching the first of every type of element: #pseudo-nth-p1 :first-of-type	
+Pass	Fragment.querySelectorAll: :first-of-type selector, matching the first td element in each table row: #pseudo-nth-table1 tr :first-of-type	
+Pass	Fragment.querySelector: :first-of-type selector, matching the first td element in each table row: #pseudo-nth-table1 tr :first-of-type	
+Pass	Fragment.querySelectorAll: :last-of-type selector, matching the last em elemnet: #pseudo-nth-p1 em:last-of-type	
+Pass	Fragment.querySelector: :last-of-type selector, matching the last em elemnet: #pseudo-nth-p1 em:last-of-type	
+Pass	Fragment.querySelectorAll: :last-of-type selector, matching the last of every type of element: #pseudo-nth-p1 :last-of-type	
+Pass	Fragment.querySelector: :last-of-type selector, matching the last of every type of element: #pseudo-nth-p1 :last-of-type	
+Pass	Fragment.querySelectorAll: :last-of-type selector, matching the last td element in each table row: #pseudo-nth-table1 tr :last-of-type	
+Pass	Fragment.querySelector: :last-of-type selector, matching the last td element in each table row: #pseudo-nth-table1 tr :last-of-type	
+Pass	Fragment.querySelectorAll: :first-child pseudo-class selector, matching first child div element: #pseudo-first-child div:first-child	
+Pass	Fragment.querySelector: :first-child pseudo-class selector, matching first child div element: #pseudo-first-child div:first-child	
+Pass	Fragment.querySelectorAll: :first-child pseudo-class selector, doesn't match non-first-child elements: .pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child	
+Pass	Fragment.querySelector: :first-child pseudo-class selector, doesn't match non-first-child elements: .pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child	
+Pass	Fragment.querySelectorAll: :first-child pseudo-class selector, matching first-child of multiple elements: #pseudo-first-child span:first-child	
+Pass	Fragment.querySelector: :first-child pseudo-class selector, matching first-child of multiple elements: #pseudo-first-child span:first-child	
+Pass	Fragment.querySelectorAll: :last-child pseudo-class selector, matching last child div element: #pseudo-last-child div:last-child	
+Pass	Fragment.querySelector: :last-child pseudo-class selector, matching last child div element: #pseudo-last-child div:last-child	
+Pass	Fragment.querySelectorAll: :last-child pseudo-class selector, doesn't match non-last-child elements: .pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child	
+Pass	Fragment.querySelector: :last-child pseudo-class selector, doesn't match non-last-child elements: .pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child	
+Pass	Fragment.querySelectorAll: :last-child pseudo-class selector, matching first-child of multiple elements: #pseudo-last-child span:last-child	
+Pass	Fragment.querySelector: :last-child pseudo-class selector, matching first-child of multiple elements: #pseudo-last-child span:last-child	
+Pass	Fragment.querySelectorAll: :pseudo-only-child pseudo-class selector, matching all only-child elements: #pseudo-only :only-child	
+Pass	Fragment.querySelector: :pseudo-only-child pseudo-class selector, matching all only-child elements: #pseudo-only :only-child	
+Pass	Fragment.querySelectorAll: :pseudo-only-child pseudo-class selector, matching only-child em elements: #pseudo-only em:only-child	
+Pass	Fragment.querySelector: :pseudo-only-child pseudo-class selector, matching only-child em elements: #pseudo-only em:only-child	
+Pass	Fragment.querySelectorAll: :pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type: #pseudo-only :only-of-type	
+Pass	Fragment.querySelector: :pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type: #pseudo-only :only-of-type	
+Pass	Fragment.querySelectorAll: :pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type: #pseudo-only em:only-of-type	
+Pass	Fragment.querySelector: :pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type: #pseudo-only em:only-of-type	
+Pass	Fragment.querySelectorAll: :empty pseudo-class selector, matching empty p elements: #pseudo-empty p:empty	
+Pass	Fragment.querySelector: :empty pseudo-class selector, matching empty p elements: #pseudo-empty p:empty	
+Pass	Fragment.querySelectorAll: :empty pseudo-class selector, matching all empty elements: #pseudo-empty :empty	
+Pass	Fragment.querySelector: :empty pseudo-class selector, matching all empty elements: #pseudo-empty :empty	
+Pass	Fragment.querySelectorAll: :link and :visited pseudo-class selectors, matching a and area elements with href attributes: #pseudo-link :link, #pseudo-link :visited	
+Pass	Fragment.querySelector: :link and :visited pseudo-class selectors, matching a and area elements with href attributes: #pseudo-link :link, #pseudo-link :visited	
+Pass	Fragment.querySelectorAll: :link and :visited pseudo-class selectors, not matching link elements with href attributes: #head :link, #head :visited	
+Pass	Fragment.querySelector: :link and :visited pseudo-class selectors, not matching link elements with href attributes: #head :link, #head :visited	
+Pass	Fragment.querySelectorAll: :link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing: :link:visited	
+Pass	Fragment.querySelector: :link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing: :link:visited	
+Pass	Fragment.querySelectorAll: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target	
+Pass	Fragment.querySelector: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target	
+Pass	Fragment.querySelectorAll: :lang pseudo-class selector, not matching element with no inherited language: #pseudo-lang-div1:lang(en)	
+Pass	Fragment.querySelector: :lang pseudo-class selector, not matching element with no inherited language: #pseudo-lang-div1:lang(en)	
+Pass	Fragment.querySelectorAll: :lang pseudo-class selector, matching specified language with exact value: #pseudo-lang-div2:lang(fr)	
+Pass	Fragment.querySelector: :lang pseudo-class selector, matching specified language with exact value: #pseudo-lang-div2:lang(fr)	
+Pass	Fragment.querySelectorAll: :lang pseudo-class selector, matching specified language with partial value: #pseudo-lang-div3:lang(en)	
+Pass	Fragment.querySelector: :lang pseudo-class selector, matching specified language with partial value: #pseudo-lang-div3:lang(en)	
+Pass	Fragment.querySelectorAll: :lang pseudo-class selector, not matching incorrect language: #pseudo-lang-div4:lang(es-AR)	
+Pass	Fragment.querySelector: :lang pseudo-class selector, not matching incorrect language: #pseudo-lang-div4:lang(es-AR)	
+Pass	Fragment.querySelectorAll: :enabled pseudo-class selector, matching all enabled form controls: #pseudo-ui :enabled	
+Pass	Fragment.querySelector: :enabled pseudo-class selector, matching all enabled form controls: #pseudo-ui :enabled	
+Pass	Fragment.querySelectorAll: :enabled pseudo-class selector, not matching link elements: #pseudo-link :enabled	
+Pass	Fragment.querySelector: :enabled pseudo-class selector, not matching link elements: #pseudo-link :enabled	
+Pass	Fragment.querySelectorAll: :disabled pseudo-class selector, matching all disabled form controls: #pseudo-ui :disabled	
+Pass	Fragment.querySelector: :disabled pseudo-class selector, matching all disabled form controls: #pseudo-ui :disabled	
+Pass	Fragment.querySelectorAll: :disabled pseudo-class selector, not matching link elements: #pseudo-link :disabled	
+Pass	Fragment.querySelector: :disabled pseudo-class selector, not matching link elements: #pseudo-link :disabled	
+Pass	Fragment.querySelectorAll: :checked pseudo-class selector, matching checked radio buttons and checkboxes: #pseudo-ui :checked	
+Pass	Fragment.querySelector: :checked pseudo-class selector, matching checked radio buttons and checkboxes: #pseudo-ui :checked	
+Pass	Fragment.querySelectorAll: :not pseudo-class selector, matching : #not>:not(div)	
+Pass	Fragment.querySelector: :not pseudo-class selector, matching : #not>:not(div)	
+Pass	Fragment.querySelectorAll: :not pseudo-class selector, matching : #not * :not(:first-child)	
+Pass	Fragment.querySelector: :not pseudo-class selector, matching : #not * :not(:first-child)	
+Pass	Fragment.querySelectorAll: :not pseudo-class selector, matching nothing: :not(*)	
+Pass	Fragment.querySelector: :not pseudo-class selector, matching nothing: :not(*)	
+Pass	Fragment.querySelectorAll: :not pseudo-class selector, matching nothing: :not(*|*)	
+Pass	Fragment.querySelector: :not pseudo-class selector, matching nothing: :not(*|*)	
+Pass	Fragment.querySelectorAll: :not pseudo-class selector argument surrounded by spaces, matching : #not>:not( div )	
+Pass	Fragment.querySelector: :not pseudo-class selector argument surrounded by spaces, matching : #not>:not( div )	
+Pass	Fragment.querySelectorAll: :first-line pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-line	
+Pass	Fragment.querySelector: :first-line pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-line	
+Pass	Fragment.querySelectorAll: ::first-line pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-line	
+Pass	Fragment.querySelector: ::first-line pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-line	
+Pass	Fragment.querySelectorAll: :first-letter pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-letter	
+Pass	Fragment.querySelector: :first-letter pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-letter	
+Pass	Fragment.querySelectorAll: ::first-letter pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-letter	
+Pass	Fragment.querySelector: ::first-letter pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-letter	
+Pass	Fragment.querySelectorAll: :before pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:before	
+Pass	Fragment.querySelector: :before pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:before	
+Pass	Fragment.querySelectorAll: ::before pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::before	
+Pass	Fragment.querySelector: ::before pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::before	
+Pass	Fragment.querySelectorAll: :after pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:after	
+Pass	Fragment.querySelector: :after pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:after	
+Pass	Fragment.querySelectorAll: ::after pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::after	
+Pass	Fragment.querySelector: ::after pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::after	
+Pass	Fragment.querySelectorAll: Class selector, matching element with specified class: .class-p	
+Pass	Fragment.querySelector: Class selector, matching element with specified class: .class-p	
+Pass	Fragment.querySelectorAll: Class selector, chained, matching only elements with all specified classes: #class .apple.orange.banana	
+Pass	Fragment.querySelector: Class selector, chained, matching only elements with all specified classes: #class .apple.orange.banana	
+Pass	Fragment.querySelectorAll: Class Selector, chained, with type selector: div.apple.banana.orange	
+Pass	Fragment.querySelector: Class Selector, chained, with type selector: div.apple.banana.orange	
+Pass	Fragment.querySelectorAll: Class selector, matching element with class value using non-ASCII characters (1): .台北Táiběi	
+Pass	Fragment.querySelector: Class selector, matching element with class value using non-ASCII characters (1): .台北Táiběi	
+Pass	Fragment.querySelectorAll: Class selector, matching multiple elements with class value using non-ASCII characters: .台北	
+Pass	Fragment.querySelector: Class selector, matching multiple elements with class value using non-ASCII characters: .台北	
+Pass	Fragment.querySelectorAll: Class selector, chained, matching element with multiple class values using non-ASCII characters (1): .台北Táiběi.台北	
+Pass	Fragment.querySelector: Class selector, chained, matching element with multiple class values using non-ASCII characters (1): .台北Táiběi.台北	
+Pass	Fragment.querySelectorAll: Class selector, matching element with class with escaped character: .foo\:bar	
+Pass	Fragment.querySelector: Class selector, matching element with class with escaped character: .foo\:bar	
+Pass	Fragment.querySelectorAll: Class selector, matching element with class with escaped character: .test\.foo\[5\]bar	
+Pass	Fragment.querySelector: Class selector, matching element with class with escaped character: .test\.foo\[5\]bar	
+Pass	Fragment.querySelectorAll: ID selector, matching element with specified id: #id #id-div1	
+Pass	Fragment.querySelector: ID selector, matching element with specified id: #id #id-div1	
+Fail	Fragment.querySelectorAll: ID selector, chained, matching element with specified id: #id-div1, #id-div1	
+Pass	Fragment.querySelector: ID selector, chained, matching element with specified id: #id-div1, #id-div1	
+Pass	Fragment.querySelectorAll: ID selector, chained, matching element with specified id: #id-div1, #id-div2	
+Pass	Fragment.querySelector: ID selector, chained, matching element with specified id: #id-div1, #id-div2	
+Pass	Fragment.querySelectorAll: ID Selector, chained, with type selector: div#id-div1, div#id-div2	
+Pass	Fragment.querySelector: ID Selector, chained, with type selector: div#id-div1, div#id-div2	
+Pass	Fragment.querySelectorAll: ID selector, not matching non-existent descendant: #id #none	
+Pass	Fragment.querySelector: ID selector, not matching non-existent descendant: #id #none	
+Pass	Fragment.querySelectorAll: ID selector, not matching non-existent ancestor: #none #id-div1	
+Pass	Fragment.querySelector: ID selector, not matching non-existent ancestor: #none #id-div1	
+Pass	Fragment.querySelectorAll: ID selector, matching multiple elements with duplicate id: #id-li-duplicate	
+Pass	Fragment.querySelector: ID selector, matching multiple elements with duplicate id: #id-li-duplicate	
+Pass	Fragment.querySelectorAll: ID selector, matching id value using non-ASCII characters (1): #台北Táiběi	
+Pass	Fragment.querySelector: ID selector, matching id value using non-ASCII characters (1): #台北Táiběi	
+Pass	Fragment.querySelectorAll: ID selector, matching id value using non-ASCII characters (2): #台北	
+Pass	Fragment.querySelector: ID selector, matching id value using non-ASCII characters (2): #台北	
+Pass	Fragment.querySelectorAll: ID selector, matching id values using non-ASCII characters (1): #台北Táiběi, #台北	
+Pass	Fragment.querySelector: ID selector, matching id values using non-ASCII characters (1): #台北Táiběi, #台北	
+Pass	Fragment.querySelectorAll: ID selector, matching element with id with escaped character: #\#foo\:bar	
+Pass	Fragment.querySelector: ID selector, matching element with id with escaped character: #\#foo\:bar	
+Pass	Fragment.querySelectorAll: ID selector, matching element with id with escaped character: #test\.foo\[5\]bar	
+Pass	Fragment.querySelector: ID selector, matching element with id with escaped character: #test\.foo\[5\]bar	
+Pass	Fragment.querySelectorAll: Namespace selector, matching element with any namespace: #any-namespace *|div	
+Pass	Fragment.querySelector: Namespace selector, matching element with any namespace: #any-namespace *|div	
+Pass	Fragment.querySelectorAll: Namespace selector, matching div elements in no namespace only: #no-namespace |div	
+Pass	Fragment.querySelector: Namespace selector, matching div elements in no namespace only: #no-namespace |div	
+Pass	Fragment.querySelectorAll: Namespace selector, matching any elements in no namespace only: #no-namespace |*	
+Pass	Fragment.querySelector: Namespace selector, matching any elements in no namespace only: #no-namespace |*	
+Pass	Fragment.querySelectorAll: Descendant combinator, matching element that is a descendant of an element with id: #descendant div	
+Pass	Fragment.querySelector: Descendant combinator, matching element that is a descendant of an element with id: #descendant div	
+Pass	Fragment.querySelectorAll: Descendant combinator, matching element with id that is a descendant of an element: div #descendant-div1	
+Pass	Fragment.querySelector: Descendant combinator, matching element with id that is a descendant of an element: div #descendant-div1	
+Pass	Fragment.querySelectorAll: Descendant combinator, matching element with id that is a descendant of an element with id: #descendant #descendant-div2	
+Pass	Fragment.querySelector: Descendant combinator, matching element with id that is a descendant of an element with id: #descendant #descendant-div2	
+Pass	Fragment.querySelectorAll: Descendant combinator, matching element with class that is a descendant of an element with id: #descendant .descendant-div2	
+Pass	Fragment.querySelector: Descendant combinator, matching element with class that is a descendant of an element with id: #descendant .descendant-div2	
+Pass	Fragment.querySelectorAll: Descendant combinator, matching element with class that is a descendant of an element with class: .descendant-div1 .descendant-div3	
+Pass	Fragment.querySelector: Descendant combinator, matching element with class that is a descendant of an element with class: .descendant-div1 .descendant-div3	
+Pass	Fragment.querySelectorAll: Descendant combinator, not matching element with id that is not a descendant of an element with id: #descendant-div1 #descendant-div4	
+Pass	Fragment.querySelector: Descendant combinator, not matching element with id that is not a descendant of an element with id: #descendant-div1 #descendant-div4	
+Pass	Fragment.querySelectorAll: Descendant combinator, whitespace characters: #descendant #descendant-div2	
+Pass	Fragment.querySelector: Descendant combinator, whitespace characters: #descendant #descendant-div2	
+Pass	Fragment.querySelectorAll: Child combinator, matching element that is a child of an element with id: #child>div	
+Pass	Fragment.querySelector: Child combinator, matching element that is a child of an element with id: #child>div	
+Pass	Fragment.querySelectorAll: Child combinator, matching element with id that is a child of an element: div>#child-div1	
+Pass	Fragment.querySelector: Child combinator, matching element with id that is a child of an element: div>#child-div1	
+Pass	Fragment.querySelectorAll: Child combinator, matching element with id that is a child of an element with id: #child>#child-div1	
+Pass	Fragment.querySelector: Child combinator, matching element with id that is a child of an element with id: #child>#child-div1	
+Pass	Fragment.querySelectorAll: Child combinator, matching element with id that is a child of an element with class: #child-div1>.child-div2	
+Pass	Fragment.querySelector: Child combinator, matching element with id that is a child of an element with class: #child-div1>.child-div2	
+Pass	Fragment.querySelectorAll: Child combinator, matching element with class that is a child of an element with class: .child-div1>.child-div2	
+Pass	Fragment.querySelector: Child combinator, matching element with class that is a child of an element with class: .child-div1>.child-div2	
+Pass	Fragment.querySelectorAll: Child combinator, not matching element with id that is not a child of an element with id: #child>#child-div3	
+Pass	Fragment.querySelector: Child combinator, not matching element with id that is not a child of an element with id: #child>#child-div3	
+Pass	Fragment.querySelectorAll: Child combinator, not matching element with id that is not a child of an element with class: #child-div1>.child-div3	
+Pass	Fragment.querySelector: Child combinator, not matching element with id that is not a child of an element with class: #child-div1>.child-div3	
+Pass	Fragment.querySelectorAll: Child combinator, not matching element with class that is not a child of an element with class: .child-div1>.child-div3	
+Pass	Fragment.querySelector: Child combinator, not matching element with class that is not a child of an element with class: .child-div1>.child-div3	
+Pass	Fragment.querySelectorAll: Child combinator, surrounded by whitespace: #child-div1 > #child-div2	
+Pass	Fragment.querySelector: Child combinator, surrounded by whitespace: #child-div1 > #child-div2	
+Pass	Fragment.querySelectorAll: Child combinator, whitespace after: #child-div1> #child-div2	
+Pass	Fragment.querySelector: Child combinator, whitespace after: #child-div1> #child-div2	
+Pass	Fragment.querySelectorAll: Child combinator, whitespace before: #child-div1 >#child-div2	
+Pass	Fragment.querySelector: Child combinator, whitespace before: #child-div1 >#child-div2	
+Pass	Fragment.querySelectorAll: Child combinator, no whitespace: #child-div1>#child-div2	
+Pass	Fragment.querySelector: Child combinator, no whitespace: #child-div1>#child-div2	
+Pass	Fragment.querySelectorAll: Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id: #adjacent-div2+div	
+Pass	Fragment.querySelector: Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id: #adjacent-div2+div	
+Pass	Fragment.querySelectorAll: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element: div+#adjacent-div4	
+Pass	Fragment.querySelector: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element: div+#adjacent-div4	
+Pass	Fragment.querySelectorAll: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id: #adjacent-div2+#adjacent-div4	
+Pass	Fragment.querySelector: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id: #adjacent-div2+#adjacent-div4	
+Pass	Fragment.querySelectorAll: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id: #adjacent-div2+.adjacent-div4	
+Pass	Fragment.querySelector: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id: #adjacent-div2+.adjacent-div4	
+Pass	Fragment.querySelectorAll: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class: .adjacent-div2+.adjacent-div4	
+Pass	Fragment.querySelector: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class: .adjacent-div2+.adjacent-div4	
+Pass	Fragment.querySelectorAll: Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element: #adjacent div+p	
+Pass	Fragment.querySelector: Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element: #adjacent div+p	
+Pass	Fragment.querySelectorAll: Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id: #adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1	
+Pass	Fragment.querySelector: Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id: #adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1	
+Pass	Fragment.querySelectorAll: Adjacent sibling combinator, surrounded by whitespace: #adjacent-p2 + #adjacent-p3	
+Pass	Fragment.querySelector: Adjacent sibling combinator, surrounded by whitespace: #adjacent-p2 + #adjacent-p3	
+Pass	Fragment.querySelectorAll: Adjacent sibling combinator, whitespace after: #adjacent-p2+ #adjacent-p3	
+Pass	Fragment.querySelector: Adjacent sibling combinator, whitespace after: #adjacent-p2+ #adjacent-p3	
+Pass	Fragment.querySelectorAll: Adjacent sibling combinator, whitespace before: #adjacent-p2 +#adjacent-p3	
+Pass	Fragment.querySelector: Adjacent sibling combinator, whitespace before: #adjacent-p2 +#adjacent-p3	
+Pass	Fragment.querySelectorAll: Adjacent sibling combinator, no whitespace: #adjacent-p2+#adjacent-p3	
+Pass	Fragment.querySelector: Adjacent sibling combinator, no whitespace: #adjacent-p2+#adjacent-p3	
+Pass	Fragment.querySelectorAll: General sibling combinator, matching element that is a sibling of an element with id: #sibling-div2~div	
+Pass	Fragment.querySelector: General sibling combinator, matching element that is a sibling of an element with id: #sibling-div2~div	
+Pass	Fragment.querySelectorAll: General sibling combinator, matching element with id that is a sibling of an element: div~#sibling-div4	
+Pass	Fragment.querySelector: General sibling combinator, matching element with id that is a sibling of an element: div~#sibling-div4	
+Pass	Fragment.querySelectorAll: General sibling combinator, matching element with id that is a sibling of an element with id: #sibling-div2~#sibling-div4	
+Pass	Fragment.querySelector: General sibling combinator, matching element with id that is a sibling of an element with id: #sibling-div2~#sibling-div4	
+Pass	Fragment.querySelectorAll: General sibling combinator, matching element with class that is a sibling of an element with id: #sibling-div2~.sibling-div	
+Pass	Fragment.querySelector: General sibling combinator, matching element with class that is a sibling of an element with id: #sibling-div2~.sibling-div	
+Pass	Fragment.querySelectorAll: General sibling combinator, matching p element that is a sibling of a div element: #sibling div~p	
+Pass	Fragment.querySelector: General sibling combinator, matching p element that is a sibling of a div element: #sibling div~p	
+Pass	Fragment.querySelectorAll: General sibling combinator, not matching element with id that is not a sibling after a p element: #sibling>p~div	
+Pass	Fragment.querySelector: General sibling combinator, not matching element with id that is not a sibling after a p element: #sibling>p~div	
+Pass	Fragment.querySelectorAll: General sibling combinator, not matching element with id that is not a sibling after an element with id: #sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1	
+Pass	Fragment.querySelector: General sibling combinator, not matching element with id that is not a sibling after an element with id: #sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1	
+Pass	Fragment.querySelectorAll: General sibling combinator, surrounded by whitespace: #sibling-p2 ~ #sibling-p3	
+Pass	Fragment.querySelector: General sibling combinator, surrounded by whitespace: #sibling-p2 ~ #sibling-p3	
+Pass	Fragment.querySelectorAll: General sibling combinator, whitespace after: #sibling-p2~ #sibling-p3	
+Pass	Fragment.querySelector: General sibling combinator, whitespace after: #sibling-p2~ #sibling-p3	
+Pass	Fragment.querySelectorAll: General sibling combinator, whitespace before: #sibling-p2 ~#sibling-p3	
+Pass	Fragment.querySelector: General sibling combinator, whitespace before: #sibling-p2 ~#sibling-p3	
+Pass	Fragment.querySelectorAll: General sibling combinator, no whitespace: #sibling-p2~#sibling-p3	
+Pass	Fragment.querySelector: General sibling combinator, no whitespace: #sibling-p2~#sibling-p3	
+Pass	Fragment.querySelectorAll: Syntax, group of selectors separator, surrounded by whitespace: #group em , #group strong	
+Pass	Fragment.querySelector: Syntax, group of selectors separator, surrounded by whitespace: #group em , #group strong	
+Pass	Fragment.querySelectorAll: Syntax, group of selectors separator, whitespace after: #group em, #group strong	
+Pass	Fragment.querySelector: Syntax, group of selectors separator, whitespace after: #group em, #group strong	
+Pass	Fragment.querySelectorAll: Syntax, group of selectors separator, whitespace before: #group em ,#group strong	
+Pass	Fragment.querySelector: Syntax, group of selectors separator, whitespace before: #group em ,#group strong	
+Pass	Fragment.querySelectorAll: Syntax, group of selectors separator, no whitespace: #group em,#group strong	
+Pass	Fragment.querySelector: Syntax, group of selectors separator, no whitespace: #group em,#group strong	
+Fail	Fragment.querySelectorAll: Slotted selector: ::slotted(foo)	Failed to parse selector
+Fail	Fragment.querySelector: Slotted selector: ::slotted(foo)	Failed to parse selector
+Fail	Fragment.querySelectorAll: Slotted selector (no matching closing paren): ::slotted(foo	Failed to parse selector
+Fail	Fragment.querySelector: Slotted selector (no matching closing paren): ::slotted(foo	Failed to parse selector
+Pass	In-document Element.querySelectorAll: Type selector, matching html element: html	
+Pass	In-document Element.querySelector: Type selector, matching html element: html	
+Pass	In-document Element.querySelectorAll: Type selector, matching body element: body	
+Pass	In-document Element.querySelector: Type selector, matching body element: body	
+Pass	In-document Element.querySelectorAll: Universal selector, matching all children of element with specified ID: #universal>*	
+Pass	In-document Element.querySelector: Universal selector, matching all children of element with specified ID: #universal>*	
+Pass	In-document Element.querySelectorAll: Universal selector, matching all grandchildren of element with specified ID: #universal>*>*	
+Pass	In-document Element.querySelector: Universal selector, matching all grandchildren of element with specified ID: #universal>*>*	
+Pass	In-document Element.querySelectorAll: Universal selector, matching all children of empty element with specified ID: #empty>*	
+Pass	In-document Element.querySelector: Universal selector, matching all children of empty element with specified ID: #empty>*	
+Pass	In-document Element.querySelectorAll: Universal selector, matching all descendants of element with specified ID: #universal *	
+Pass	In-document Element.querySelector: Universal selector, matching all descendants of element with specified ID: #universal *	
+Pass	In-document Element.querySelectorAll: Attribute presence selector, matching align attribute with value: .attr-presence-div1[align]	
+Pass	In-document Element.querySelector: Attribute presence selector, matching align attribute with value: .attr-presence-div1[align]	
+Pass	In-document Element.querySelectorAll: Attribute presence selector, matching align attribute with empty value: .attr-presence-div2[align]	
+Pass	In-document Element.querySelector: Attribute presence selector, matching align attribute with empty value: .attr-presence-div2[align]	
+Fail	In-document Element.querySelectorAll: Attribute presence selector, matching title attribute, case insensitivity: #attr-presence [*|TiTlE]	
+Fail	In-document Element.querySelector: Attribute presence selector, matching title attribute, case insensitivity: #attr-presence [*|TiTlE]	
+Pass	In-document Element.querySelectorAll: Attribute presence selector, matching custom data-* attribute: [data-attr-presence]	
+Pass	In-document Element.querySelector: Attribute presence selector, matching custom data-* attribute: [data-attr-presence]	
+Pass	In-document Element.querySelectorAll: Attribute presence selector, not matching attribute with similar name: .attr-presence-div3[align], .attr-presence-div4[align]	
+Pass	In-document Element.querySelector: Attribute presence selector, not matching attribute with similar name: .attr-presence-div3[align], .attr-presence-div4[align]	
+Pass	In-document Element.querySelectorAll: Attribute presence selector, matching attribute with non-ASCII characters: ul[data-中文]	
+Pass	In-document Element.querySelector: Attribute presence selector, matching attribute with non-ASCII characters: ul[data-中文]	
+Pass	In-document Element.querySelectorAll: Attribute presence selector, not matching default option without selected attribute: #attr-presence-select1 option[selected]	
+Pass	In-document Element.querySelector: Attribute presence selector, not matching default option without selected attribute: #attr-presence-select1 option[selected]	
+Pass	In-document Element.querySelectorAll: Attribute presence selector, matching option with selected attribute: #attr-presence-select2 option[selected]	
+Pass	In-document Element.querySelector: Attribute presence selector, matching option with selected attribute: #attr-presence-select2 option[selected]	
+Pass	In-document Element.querySelectorAll: Attribute presence selector, matching multiple options with selected attributes: #attr-presence-select3 option[selected]	
+Pass	In-document Element.querySelector: Attribute presence selector, matching multiple options with selected attributes: #attr-presence-select3 option[selected]	
+Pass	In-document Element.querySelectorAll: Attribute value selector, matching align attribute with value: #attr-value [align="center"]	
+Pass	In-document Element.querySelector: Attribute value selector, matching align attribute with value: #attr-value [align="center"]	
+Pass	In-document Element.querySelectorAll: Attribute value selector, matching align attribute with value, unclosed bracket: #attr-value [align="center"	
+Pass	In-document Element.querySelector: Attribute value selector, matching align attribute with value, unclosed bracket: #attr-value [align="center"	
+Pass	In-document Element.querySelectorAll: Attribute value selector, matching align attribute with empty value: #attr-value [align=""]	
+Pass	In-document Element.querySelector: Attribute value selector, matching align attribute with empty value: #attr-value [align=""]	
+Pass	In-document Element.querySelectorAll: Attribute value selector, not matching align attribute with partial value: #attr-value [align="c"]	
+Pass	In-document Element.querySelector: Attribute value selector, not matching align attribute with partial value: #attr-value [align="c"]	
+Pass	In-document Element.querySelectorAll: Attribute value selector, not matching align attribute with incorrect value: #attr-value [align="centera"]	
+Pass	In-document Element.querySelector: Attribute value selector, not matching align attribute with incorrect value: #attr-value [align="centera"]	
+Pass	In-document Element.querySelectorAll: Attribute value selector, matching custom data-* attribute with unicode escaped value: [data-attr-value="\e9"]	
+Pass	In-document Element.querySelector: Attribute value selector, matching custom data-* attribute with unicode escaped value: [data-attr-value="\e9"]	
+Pass	In-document Element.querySelectorAll: Attribute value selector, matching custom data-* attribute with escaped character: [data-attr-value_foo="\e9"]	
+Pass	In-document Element.querySelector: Attribute value selector, matching custom data-* attribute with escaped character: [data-attr-value_foo="\e9"]	
+Pass	In-document Element.querySelectorAll: Attribute value selector with single-quoted value, matching multiple inputs with type attributes: #attr-value input[type='hidden'],#attr-value input[type='radio']	
+Pass	In-document Element.querySelector: Attribute value selector with single-quoted value, matching multiple inputs with type attributes: #attr-value input[type='hidden'],#attr-value input[type='radio']	
+Pass	In-document Element.querySelectorAll: Attribute value selector with double-quoted value, matching multiple inputs with type attributes: #attr-value input[type="hidden"],#attr-value input[type='radio']	
+Pass	In-document Element.querySelector: Attribute value selector with double-quoted value, matching multiple inputs with type attributes: #attr-value input[type="hidden"],#attr-value input[type='radio']	
+Pass	In-document Element.querySelectorAll: Attribute value selector with unquoted value, matching multiple inputs with type attributes: #attr-value input[type=hidden],#attr-value input[type=radio]	
+Pass	In-document Element.querySelector: Attribute value selector with unquoted value, matching multiple inputs with type attributes: #attr-value input[type=hidden],#attr-value input[type=radio]	
+Pass	In-document Element.querySelectorAll: Attribute value selector, matching attribute with value using non-ASCII characters: [data-attr-value=中文]	
+Pass	In-document Element.querySelector: Attribute value selector, matching attribute with value using non-ASCII characters: [data-attr-value=中文]	
+Pass	In-document Element.querySelectorAll: Attribute whitespace-separated list selector, matching class attribute with value: #attr-whitespace [class~="div1"]	
+Pass	In-document Element.querySelector: Attribute whitespace-separated list selector, matching class attribute with value: #attr-whitespace [class~="div1"]	
+Pass	In-document Element.querySelectorAll: Attribute whitespace-separated list selector, not matching class attribute with empty value: #attr-whitespace [class~=""]	
+Pass	In-document Element.querySelector: Attribute whitespace-separated list selector, not matching class attribute with empty value: #attr-whitespace [class~=""]	
+Pass	In-document Element.querySelectorAll: Attribute whitespace-separated list selector, not matching class attribute with partial value: [data-attr-whitespace~="div"]	
+Pass	In-document Element.querySelector: Attribute whitespace-separated list selector, not matching class attribute with partial value: [data-attr-whitespace~="div"]	
+Pass	In-document Element.querySelectorAll: Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value: [data-attr-whitespace~="\0000e9"]	
+Pass	In-document Element.querySelector: Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value: [data-attr-whitespace~="\0000e9"]	
+Pass	In-document Element.querySelectorAll: Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character: [data-attr-whitespace_foo~="\e9"]	
+Pass	In-document Element.querySelector: Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character: [data-attr-whitespace_foo~="\e9"]	
+Pass	In-document Element.querySelectorAll: Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~='bookmark'], #attr-whitespace a[rel~='nofollow']	
+Pass	In-document Element.querySelector: Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~='bookmark'], #attr-whitespace a[rel~='nofollow']	
+Pass	In-document Element.querySelectorAll: Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~="bookmark"],#attr-whitespace a[rel~='nofollow']	
+Pass	In-document Element.querySelector: Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~="bookmark"],#attr-whitespace a[rel~='nofollow']	
+Pass	In-document Element.querySelectorAll: Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~=bookmark], #attr-whitespace a[rel~=nofollow]	
+Pass	In-document Element.querySelector: Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes: #attr-whitespace a[rel~=bookmark], #attr-whitespace a[rel~=nofollow]	
+Pass	In-document Element.querySelectorAll: Attribute whitespace-separated list selector with double-quoted value, not matching value with space: #attr-whitespace a[rel~="book mark"]	
+Pass	In-document Element.querySelector: Attribute whitespace-separated list selector with double-quoted value, not matching value with space: #attr-whitespace a[rel~="book mark"]	
+Pass	In-document Element.querySelectorAll: Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters: #attr-whitespace [title~=中文]	
+Pass	In-document Element.querySelector: Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters: #attr-whitespace [title~=中文]	
+Pass	In-document Element.querySelectorAll: Attribute hyphen-separated list selector, not matching unspecified lang attribute: #attr-hyphen-div1[lang|="en"]	
+Pass	In-document Element.querySelector: Attribute hyphen-separated list selector, not matching unspecified lang attribute: #attr-hyphen-div1[lang|="en"]	
+Pass	In-document Element.querySelectorAll: Attribute hyphen-separated list selector, matching lang attribute with exact value: #attr-hyphen-div2[lang|="fr"]	
+Pass	In-document Element.querySelector: Attribute hyphen-separated list selector, matching lang attribute with exact value: #attr-hyphen-div2[lang|="fr"]	
+Pass	In-document Element.querySelectorAll: Attribute hyphen-separated list selector, matching lang attribute with partial value: #attr-hyphen-div3[lang|="en"]	
+Pass	In-document Element.querySelector: Attribute hyphen-separated list selector, matching lang attribute with partial value: #attr-hyphen-div3[lang|="en"]	
+Pass	In-document Element.querySelectorAll: Attribute hyphen-separated list selector, not matching incorrect value: #attr-hyphen-div4[lang|="es-AR"]	
+Pass	In-document Element.querySelector: Attribute hyphen-separated list selector, not matching incorrect value: #attr-hyphen-div4[lang|="es-AR"]	
+Pass	In-document Element.querySelectorAll: Attribute begins with selector, matching href attributes beginning with specified substring: #attr-begins a[href^="http://www"]	
+Pass	In-document Element.querySelector: Attribute begins with selector, matching href attributes beginning with specified substring: #attr-begins a[href^="http://www"]	
+Pass	In-document Element.querySelectorAll: Attribute begins with selector, matching lang attributes beginning with specified substring, : #attr-begins [lang^="en-"]	
+Pass	In-document Element.querySelector: Attribute begins with selector, matching lang attributes beginning with specified substring, : #attr-begins [lang^="en-"]	
+Pass	In-document Element.querySelectorAll: Attribute begins with selector, not matching class attribute with empty value: #attr-begins [class^=""]	
+Pass	In-document Element.querySelector: Attribute begins with selector, not matching class attribute with empty value: #attr-begins [class^=""]	
+Pass	In-document Element.querySelectorAll: Attribute begins with selector, not matching class attribute not beginning with specified substring: #attr-begins [class^=apple]	
+Pass	In-document Element.querySelector: Attribute begins with selector, not matching class attribute not beginning with specified substring: #attr-begins [class^=apple]	
+Pass	In-document Element.querySelectorAll: Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=' apple']	
+Pass	In-document Element.querySelector: Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=' apple']	
+Pass	In-document Element.querySelectorAll: Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=" apple"]	
+Pass	In-document Element.querySelector: Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring: #attr-begins [class^=" apple"]	
+Pass	In-document Element.querySelectorAll: Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring: #attr-begins [class^= apple]	
+Pass	In-document Element.querySelector: Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring: #attr-begins [class^= apple]	
+Pass	In-document Element.querySelectorAll: Attribute ends with selector, matching href attributes ending with specified substring: #attr-ends a[href$=".org"]	
+Pass	In-document Element.querySelector: Attribute ends with selector, matching href attributes ending with specified substring: #attr-ends a[href$=".org"]	
+Pass	In-document Element.querySelectorAll: Attribute ends with selector, matching lang attributes ending with specified substring, : #attr-ends [lang$="-CH"]	
+Pass	In-document Element.querySelector: Attribute ends with selector, matching lang attributes ending with specified substring, : #attr-ends [lang$="-CH"]	
+Pass	In-document Element.querySelectorAll: Attribute ends with selector, not matching class attribute with empty value: #attr-ends [class$=""]	
+Pass	In-document Element.querySelector: Attribute ends with selector, not matching class attribute with empty value: #attr-ends [class$=""]	
+Pass	In-document Element.querySelectorAll: Attribute ends with selector, not matching class attribute not ending with specified substring: #attr-ends [class$=apple]	
+Pass	In-document Element.querySelector: Attribute ends with selector, not matching class attribute not ending with specified substring: #attr-ends [class$=apple]	
+Pass	In-document Element.querySelectorAll: Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring: #attr-ends [class$='apple ']	
+Pass	In-document Element.querySelector: Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring: #attr-ends [class$='apple ']	
+Pass	In-document Element.querySelectorAll: Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring: #attr-ends [class$="apple "]	
+Pass	In-document Element.querySelector: Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring: #attr-ends [class$="apple "]	
+Pass	In-document Element.querySelectorAll: Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring: #attr-ends [class$=apple ]	
+Pass	In-document Element.querySelector: Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring: #attr-ends [class$=apple ]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector, matching href attributes beginning with specified substring: #attr-contains a[href*="http://www"]	
+Pass	In-document Element.querySelector: Attribute contains selector, matching href attributes beginning with specified substring: #attr-contains a[href*="http://www"]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector, matching href attributes ending with specified substring: #attr-contains a[href*=".org"]	
+Pass	In-document Element.querySelector: Attribute contains selector, matching href attributes ending with specified substring: #attr-contains a[href*=".org"]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector, matching href attributes containing specified substring: #attr-contains a[href*=".example."]	
+Pass	In-document Element.querySelector: Attribute contains selector, matching href attributes containing specified substring: #attr-contains a[href*=".example."]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector, matching lang attributes beginning with specified substring, : #attr-contains [lang*="en-"]	
+Pass	In-document Element.querySelector: Attribute contains selector, matching lang attributes beginning with specified substring, : #attr-contains [lang*="en-"]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector, matching lang attributes ending with specified substring, : #attr-contains [lang*="-CH"]	
+Pass	In-document Element.querySelector: Attribute contains selector, matching lang attributes ending with specified substring, : #attr-contains [lang*="-CH"]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector, not matching class attribute with empty value: #attr-contains [class*=""]	
+Pass	In-document Element.querySelector: Attribute contains selector, not matching class attribute with empty value: #attr-contains [class*=""]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=' apple']	
+Pass	In-document Element.querySelector: Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=' apple']	
+Pass	In-document Element.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute ending with specified substring: #attr-contains [class*='orange ']	
+Pass	In-document Element.querySelector: Attribute contains selector with single-quoted value, matching class attribute ending with specified substring: #attr-contains [class*='orange ']	
+Pass	In-document Element.querySelectorAll: Attribute contains selector with single-quoted value, matching class attribute containing specified substring: #attr-contains [class*='ple banana ora']	
+Pass	In-document Element.querySelector: Attribute contains selector with single-quoted value, matching class attribute containing specified substring: #attr-contains [class*='ple banana ora']	
+Pass	In-document Element.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=" apple"]	
+Pass	In-document Element.querySelector: Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring: #attr-contains [class*=" apple"]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute ending with specified substring: #attr-contains [class*="orange "]	
+Pass	In-document Element.querySelector: Attribute contains selector with double-quoted value, matching class attribute ending with specified substring: #attr-contains [class*="orange "]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector with double-quoted value, matching class attribute containing specified substring: #attr-contains [class*="ple banana ora"]	
+Pass	In-document Element.querySelector: Attribute contains selector with double-quoted value, matching class attribute containing specified substring: #attr-contains [class*="ple banana ora"]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute beginning with specified substring: #attr-contains [class*= apple]	
+Pass	In-document Element.querySelector: Attribute contains selector with unquoted value, matching class attribute beginning with specified substring: #attr-contains [class*= apple]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute ending with specified substring: #attr-contains [class*=orange ]	
+Pass	In-document Element.querySelector: Attribute contains selector with unquoted value, matching class attribute ending with specified substring: #attr-contains [class*=orange ]	
+Pass	In-document Element.querySelectorAll: Attribute contains selector with unquoted value, matching class attribute containing specified substring: #attr-contains [class*= banana ]	
+Pass	In-document Element.querySelector: Attribute contains selector with unquoted value, matching class attribute containing specified substring: #attr-contains [class*= banana ]	
+Pass	In-document Element.querySelectorAll: :root pseudo-class selector, not matching document root element: :root	
+Pass	In-document Element.querySelector: :root pseudo-class selector, not matching document root element: :root	
+Pass	In-document Element.querySelectorAll: :nth-child selector, matching the third child element: #pseudo-nth-table1 :nth-child(3)	
+Pass	In-document Element.querySelector: :nth-child selector, matching the third child element: #pseudo-nth-table1 :nth-child(3)	
+Pass	In-document Element.querySelectorAll: :nth-child selector, matching every third child element: #pseudo-nth li:nth-child(3n)	
+Pass	In-document Element.querySelector: :nth-child selector, matching every third child element: #pseudo-nth li:nth-child(3n)	
+Pass	In-document Element.querySelectorAll: :nth-child selector, matching every second child element, starting from the fourth: #pseudo-nth li:nth-child(2n+4)	
+Pass	In-document Element.querySelector: :nth-child selector, matching every second child element, starting from the fourth: #pseudo-nth li:nth-child(2n+4)	
+Pass	In-document Element.querySelectorAll: :nth-child selector, matching every fourth child element, starting from the third: #pseudo-nth-p1 :nth-child(4n-1)	
+Pass	In-document Element.querySelector: :nth-child selector, matching every fourth child element, starting from the third: #pseudo-nth-p1 :nth-child(4n-1)	
+Pass	In-document Element.querySelectorAll: :nth-last-child selector, matching the third last child element: #pseudo-nth-table1 :nth-last-child(3)	
+Pass	In-document Element.querySelector: :nth-last-child selector, matching the third last child element: #pseudo-nth-table1 :nth-last-child(3)	
+Pass	In-document Element.querySelectorAll: :nth-last-child selector, matching every third child element from the end: #pseudo-nth li:nth-last-child(3n)	
+Pass	In-document Element.querySelector: :nth-last-child selector, matching every third child element from the end: #pseudo-nth li:nth-last-child(3n)	
+Pass	In-document Element.querySelectorAll: :nth-last-child selector, matching every second child element from the end, starting from the fourth last: #pseudo-nth li:nth-last-child(2n+4)	
+Pass	In-document Element.querySelector: :nth-last-child selector, matching every second child element from the end, starting from the fourth last: #pseudo-nth li:nth-last-child(2n+4)	
+Pass	In-document Element.querySelectorAll: :nth-last-child selector, matching every fourth element from the end, starting from the third last: #pseudo-nth-p1 :nth-last-child(4n-1)	
+Pass	In-document Element.querySelector: :nth-last-child selector, matching every fourth element from the end, starting from the third last: #pseudo-nth-p1 :nth-last-child(4n-1)	
+Pass	In-document Element.querySelectorAll: :nth-of-type selector, matching the third em element: #pseudo-nth-p1 em:nth-of-type(3)	
+Pass	In-document Element.querySelector: :nth-of-type selector, matching the third em element: #pseudo-nth-p1 em:nth-of-type(3)	
+Pass	In-document Element.querySelectorAll: :nth-of-type selector, matching every second element of their type: #pseudo-nth-p1 :nth-of-type(2n)	
+Pass	In-document Element.querySelector: :nth-of-type selector, matching every second element of their type: #pseudo-nth-p1 :nth-of-type(2n)	
+Pass	In-document Element.querySelectorAll: :nth-of-type selector, matching every second elemetn of their type, starting from the first: #pseudo-nth-p1 span:nth-of-type(2n-1)	
+Pass	In-document Element.querySelector: :nth-of-type selector, matching every second elemetn of their type, starting from the first: #pseudo-nth-p1 span:nth-of-type(2n-1)	
+Pass	In-document Element.querySelectorAll: :nth-last-of-type selector, matching the third last em element: #pseudo-nth-p1 em:nth-last-of-type(3)	
+Pass	In-document Element.querySelector: :nth-last-of-type selector, matching the third last em element: #pseudo-nth-p1 em:nth-last-of-type(3)	
+Pass	In-document Element.querySelectorAll: :nth-last-of-type selector, matching every second last element of their type: #pseudo-nth-p1 :nth-last-of-type(2n)	
+Pass	In-document Element.querySelector: :nth-last-of-type selector, matching every second last element of their type: #pseudo-nth-p1 :nth-last-of-type(2n)	
+Pass	In-document Element.querySelectorAll: :nth-last-of-type selector, matching every second last element of their type, starting from the last: #pseudo-nth-p1 span:nth-last-of-type(2n-1)	
+Pass	In-document Element.querySelector: :nth-last-of-type selector, matching every second last element of their type, starting from the last: #pseudo-nth-p1 span:nth-last-of-type(2n-1)	
+Pass	In-document Element.querySelectorAll: :first-of-type selector, matching the first em element: #pseudo-nth-p1 em:first-of-type	
+Pass	In-document Element.querySelector: :first-of-type selector, matching the first em element: #pseudo-nth-p1 em:first-of-type	
+Pass	In-document Element.querySelectorAll: :first-of-type selector, matching the first of every type of element: #pseudo-nth-p1 :first-of-type	
+Pass	In-document Element.querySelector: :first-of-type selector, matching the first of every type of element: #pseudo-nth-p1 :first-of-type	
+Pass	In-document Element.querySelectorAll: :first-of-type selector, matching the first td element in each table row: #pseudo-nth-table1 tr :first-of-type	
+Pass	In-document Element.querySelector: :first-of-type selector, matching the first td element in each table row: #pseudo-nth-table1 tr :first-of-type	
+Pass	In-document Element.querySelectorAll: :last-of-type selector, matching the last em elemnet: #pseudo-nth-p1 em:last-of-type	
+Pass	In-document Element.querySelector: :last-of-type selector, matching the last em elemnet: #pseudo-nth-p1 em:last-of-type	
+Pass	In-document Element.querySelectorAll: :last-of-type selector, matching the last of every type of element: #pseudo-nth-p1 :last-of-type	
+Pass	In-document Element.querySelector: :last-of-type selector, matching the last of every type of element: #pseudo-nth-p1 :last-of-type	
+Pass	In-document Element.querySelectorAll: :last-of-type selector, matching the last td element in each table row: #pseudo-nth-table1 tr :last-of-type	
+Pass	In-document Element.querySelector: :last-of-type selector, matching the last td element in each table row: #pseudo-nth-table1 tr :last-of-type	
+Pass	In-document Element.querySelectorAll: :first-child pseudo-class selector, matching first child div element: #pseudo-first-child div:first-child	
+Pass	In-document Element.querySelector: :first-child pseudo-class selector, matching first child div element: #pseudo-first-child div:first-child	
+Pass	In-document Element.querySelectorAll: :first-child pseudo-class selector, doesn't match non-first-child elements: .pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child	
+Pass	In-document Element.querySelector: :first-child pseudo-class selector, doesn't match non-first-child elements: .pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child	
+Pass	In-document Element.querySelectorAll: :first-child pseudo-class selector, matching first-child of multiple elements: #pseudo-first-child span:first-child	
+Pass	In-document Element.querySelector: :first-child pseudo-class selector, matching first-child of multiple elements: #pseudo-first-child span:first-child	
+Pass	In-document Element.querySelectorAll: :last-child pseudo-class selector, matching last child div element: #pseudo-last-child div:last-child	
+Pass	In-document Element.querySelector: :last-child pseudo-class selector, matching last child div element: #pseudo-last-child div:last-child	
+Pass	In-document Element.querySelectorAll: :last-child pseudo-class selector, doesn't match non-last-child elements: .pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child	
+Pass	In-document Element.querySelector: :last-child pseudo-class selector, doesn't match non-last-child elements: .pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child	
+Pass	In-document Element.querySelectorAll: :last-child pseudo-class selector, matching first-child of multiple elements: #pseudo-last-child span:last-child	
+Pass	In-document Element.querySelector: :last-child pseudo-class selector, matching first-child of multiple elements: #pseudo-last-child span:last-child	
+Pass	In-document Element.querySelectorAll: :pseudo-only-child pseudo-class selector, matching all only-child elements: #pseudo-only :only-child	
+Pass	In-document Element.querySelector: :pseudo-only-child pseudo-class selector, matching all only-child elements: #pseudo-only :only-child	
+Pass	In-document Element.querySelectorAll: :pseudo-only-child pseudo-class selector, matching only-child em elements: #pseudo-only em:only-child	
+Pass	In-document Element.querySelector: :pseudo-only-child pseudo-class selector, matching only-child em elements: #pseudo-only em:only-child	
+Pass	In-document Element.querySelectorAll: :pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type: #pseudo-only :only-of-type	
+Pass	In-document Element.querySelector: :pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type: #pseudo-only :only-of-type	
+Pass	In-document Element.querySelectorAll: :pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type: #pseudo-only em:only-of-type	
+Pass	In-document Element.querySelector: :pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type: #pseudo-only em:only-of-type	
+Pass	In-document Element.querySelectorAll: :empty pseudo-class selector, matching empty p elements: #pseudo-empty p:empty	
+Pass	In-document Element.querySelector: :empty pseudo-class selector, matching empty p elements: #pseudo-empty p:empty	
+Pass	In-document Element.querySelectorAll: :empty pseudo-class selector, matching all empty elements: #pseudo-empty :empty	
+Pass	In-document Element.querySelector: :empty pseudo-class selector, matching all empty elements: #pseudo-empty :empty	
+Pass	In-document Element.querySelectorAll: :link and :visited pseudo-class selectors, matching a and area elements with href attributes: #pseudo-link :link, #pseudo-link :visited	
+Pass	In-document Element.querySelector: :link and :visited pseudo-class selectors, matching a and area elements with href attributes: #pseudo-link :link, #pseudo-link :visited	
+Pass	In-document Element.querySelectorAll: :link and :visited pseudo-class selectors, not matching link elements with href attributes: #head :link, #head :visited	
+Pass	In-document Element.querySelector: :link and :visited pseudo-class selectors, not matching link elements with href attributes: #head :link, #head :visited	
+Pass	In-document Element.querySelectorAll: :link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing: :link:visited	
+Pass	In-document Element.querySelector: :link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing: :link:visited	
+Fail	In-document Element.querySelectorAll: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target	
+Fail	In-document Element.querySelector: :target pseudo-class selector, matching the element referenced by the URL fragment identifier: :target	
+Pass	In-document Element.querySelectorAll: :lang pseudo-class selector, matching inherited language: #pseudo-lang-div1:lang(en)	
+Pass	In-document Element.querySelector: :lang pseudo-class selector, matching inherited language: #pseudo-lang-div1:lang(en)	
+Pass	In-document Element.querySelectorAll: :lang pseudo-class selector, matching specified language with exact value: #pseudo-lang-div2:lang(fr)	
+Pass	In-document Element.querySelector: :lang pseudo-class selector, matching specified language with exact value: #pseudo-lang-div2:lang(fr)	
+Pass	In-document Element.querySelectorAll: :lang pseudo-class selector, matching specified language with partial value: #pseudo-lang-div3:lang(en)	
+Pass	In-document Element.querySelector: :lang pseudo-class selector, matching specified language with partial value: #pseudo-lang-div3:lang(en)	
+Pass	In-document Element.querySelectorAll: :lang pseudo-class selector, not matching incorrect language: #pseudo-lang-div4:lang(es-AR)	
+Pass	In-document Element.querySelector: :lang pseudo-class selector, not matching incorrect language: #pseudo-lang-div4:lang(es-AR)	
+Pass	In-document Element.querySelectorAll: :enabled pseudo-class selector, matching all enabled form controls: #pseudo-ui :enabled	
+Pass	In-document Element.querySelector: :enabled pseudo-class selector, matching all enabled form controls: #pseudo-ui :enabled	
+Pass	In-document Element.querySelectorAll: :enabled pseudo-class selector, not matching link elements: #pseudo-link :enabled	
+Pass	In-document Element.querySelector: :enabled pseudo-class selector, not matching link elements: #pseudo-link :enabled	
+Pass	In-document Element.querySelectorAll: :disabled pseudo-class selector, matching all disabled form controls: #pseudo-ui :disabled	
+Pass	In-document Element.querySelector: :disabled pseudo-class selector, matching all disabled form controls: #pseudo-ui :disabled	
+Pass	In-document Element.querySelectorAll: :disabled pseudo-class selector, not matching link elements: #pseudo-link :disabled	
+Pass	In-document Element.querySelector: :disabled pseudo-class selector, not matching link elements: #pseudo-link :disabled	
+Pass	In-document Element.querySelectorAll: :checked pseudo-class selector, matching checked radio buttons and checkboxes: #pseudo-ui :checked	
+Pass	In-document Element.querySelector: :checked pseudo-class selector, matching checked radio buttons and checkboxes: #pseudo-ui :checked	
+Pass	In-document Element.querySelectorAll: :not pseudo-class selector, matching : #not>:not(div)	
+Pass	In-document Element.querySelector: :not pseudo-class selector, matching : #not>:not(div)	
+Pass	In-document Element.querySelectorAll: :not pseudo-class selector, matching : #not * :not(:first-child)	
+Pass	In-document Element.querySelector: :not pseudo-class selector, matching : #not * :not(:first-child)	
+Pass	In-document Element.querySelectorAll: :not pseudo-class selector, matching nothing: :not(*)	
+Pass	In-document Element.querySelector: :not pseudo-class selector, matching nothing: :not(*)	
+Pass	In-document Element.querySelectorAll: :not pseudo-class selector, matching nothing: :not(*|*)	
+Pass	In-document Element.querySelector: :not pseudo-class selector, matching nothing: :not(*|*)	
+Pass	In-document Element.querySelectorAll: :not pseudo-class selector argument surrounded by spaces, matching : #not>:not( div )	
+Pass	In-document Element.querySelector: :not pseudo-class selector argument surrounded by spaces, matching : #not>:not( div )	
+Pass	In-document Element.querySelectorAll: :first-line pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-line	
+Pass	In-document Element.querySelector: :first-line pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-line	
+Pass	In-document Element.querySelectorAll: ::first-line pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-line	
+Pass	In-document Element.querySelector: ::first-line pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-line	
+Pass	In-document Element.querySelectorAll: :first-letter pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-letter	
+Pass	In-document Element.querySelector: :first-letter pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:first-letter	
+Pass	In-document Element.querySelectorAll: ::first-letter pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-letter	
+Pass	In-document Element.querySelector: ::first-letter pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::first-letter	
+Pass	In-document Element.querySelectorAll: :before pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:before	
+Pass	In-document Element.querySelector: :before pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:before	
+Pass	In-document Element.querySelectorAll: ::before pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::before	
+Pass	In-document Element.querySelector: ::before pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::before	
+Pass	In-document Element.querySelectorAll: :after pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:after	
+Pass	In-document Element.querySelector: :after pseudo-element (one-colon syntax) selector, not matching any elements: #pseudo-element:after	
+Pass	In-document Element.querySelectorAll: ::after pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::after	
+Pass	In-document Element.querySelector: ::after pseudo-element (two-colon syntax) selector, not matching any elements: #pseudo-element::after	
+Pass	In-document Element.querySelectorAll: Class selector, matching element with specified class: .class-p	
+Pass	In-document Element.querySelector: Class selector, matching element with specified class: .class-p	
+Pass	In-document Element.querySelectorAll: Class selector, chained, matching only elements with all specified classes: #class .apple.orange.banana	
+Pass	In-document Element.querySelector: Class selector, chained, matching only elements with all specified classes: #class .apple.orange.banana	
+Pass	In-document Element.querySelectorAll: Class Selector, chained, with type selector: div.apple.banana.orange	
+Pass	In-document Element.querySelector: Class Selector, chained, with type selector: div.apple.banana.orange	
+Pass	In-document Element.querySelectorAll: Class selector, matching element with class value using non-ASCII characters (1): .台北Táiběi	
+Pass	In-document Element.querySelector: Class selector, matching element with class value using non-ASCII characters (1): .台北Táiběi	
+Pass	In-document Element.querySelectorAll: Class selector, matching multiple elements with class value using non-ASCII characters: .台北	
+Pass	In-document Element.querySelector: Class selector, matching multiple elements with class value using non-ASCII characters: .台北	
+Pass	In-document Element.querySelectorAll: Class selector, chained, matching element with multiple class values using non-ASCII characters (1): .台北Táiběi.台北	
+Pass	In-document Element.querySelector: Class selector, chained, matching element with multiple class values using non-ASCII characters (1): .台北Táiběi.台北	
+Pass	In-document Element.querySelectorAll: Class selector, matching element with class with escaped character: .foo\:bar	
+Pass	In-document Element.querySelector: Class selector, matching element with class with escaped character: .foo\:bar	
+Pass	In-document Element.querySelectorAll: Class selector, matching element with class with escaped character: .test\.foo\[5\]bar	
+Pass	In-document Element.querySelector: Class selector, matching element with class with escaped character: .test\.foo\[5\]bar	
+Pass	In-document Element.querySelectorAll: ID selector, matching element with specified id: #id #id-div1	
+Pass	In-document Element.querySelector: ID selector, matching element with specified id: #id #id-div1	
+Fail	In-document Element.querySelectorAll: ID selector, chained, matching element with specified id: #id-div1, #id-div1	
+Pass	In-document Element.querySelector: ID selector, chained, matching element with specified id: #id-div1, #id-div1	
+Pass	In-document Element.querySelectorAll: ID selector, chained, matching element with specified id: #id-div1, #id-div2	
+Pass	In-document Element.querySelector: ID selector, chained, matching element with specified id: #id-div1, #id-div2	
+Pass	In-document Element.querySelectorAll: ID Selector, chained, with type selector: div#id-div1, div#id-div2	
+Pass	In-document Element.querySelector: ID Selector, chained, with type selector: div#id-div1, div#id-div2	
+Pass	In-document Element.querySelectorAll: ID selector, not matching non-existent descendant: #id #none	
+Pass	In-document Element.querySelector: ID selector, not matching non-existent descendant: #id #none	
+Pass	In-document Element.querySelectorAll: ID selector, not matching non-existent ancestor: #none #id-div1	
+Pass	In-document Element.querySelector: ID selector, not matching non-existent ancestor: #none #id-div1	
+Pass	In-document Element.querySelectorAll: ID selector, matching multiple elements with duplicate id: #id-li-duplicate	
+Pass	In-document Element.querySelector: ID selector, matching multiple elements with duplicate id: #id-li-duplicate	
+Pass	In-document Element.querySelectorAll: ID selector, matching id value using non-ASCII characters (1): #台北Táiběi	
+Pass	In-document Element.querySelector: ID selector, matching id value using non-ASCII characters (1): #台北Táiběi	
+Pass	In-document Element.querySelectorAll: ID selector, matching id value using non-ASCII characters (2): #台北	
+Pass	In-document Element.querySelector: ID selector, matching id value using non-ASCII characters (2): #台北	
+Pass	In-document Element.querySelectorAll: ID selector, matching id values using non-ASCII characters (1): #台北Táiběi, #台北	
+Pass	In-document Element.querySelector: ID selector, matching id values using non-ASCII characters (1): #台北Táiběi, #台北	
+Pass	In-document Element.querySelectorAll: ID selector, matching element with id with escaped character: #\#foo\:bar	
+Pass	In-document Element.querySelector: ID selector, matching element with id with escaped character: #\#foo\:bar	
+Pass	In-document Element.querySelectorAll: ID selector, matching element with id with escaped character: #test\.foo\[5\]bar	
+Pass	In-document Element.querySelector: ID selector, matching element with id with escaped character: #test\.foo\[5\]bar	
+Pass	In-document Element.querySelectorAll: Namespace selector, matching element with any namespace: #any-namespace *|div	
+Pass	In-document Element.querySelector: Namespace selector, matching element with any namespace: #any-namespace *|div	
+Pass	In-document Element.querySelectorAll: Namespace selector, matching div elements in no namespace only: #no-namespace |div	
+Pass	In-document Element.querySelector: Namespace selector, matching div elements in no namespace only: #no-namespace |div	
+Pass	In-document Element.querySelectorAll: Namespace selector, matching any elements in no namespace only: #no-namespace |*	
+Pass	In-document Element.querySelector: Namespace selector, matching any elements in no namespace only: #no-namespace |*	
+Pass	In-document Element.querySelectorAll: Descendant combinator, matching element that is a descendant of an element with id: #descendant div	
+Pass	In-document Element.querySelector: Descendant combinator, matching element that is a descendant of an element with id: #descendant div	
+Pass	In-document Element.querySelectorAll: Descendant combinator, matching element with id that is a descendant of an element: body #descendant-div1	
+Pass	In-document Element.querySelector: Descendant combinator, matching element with id that is a descendant of an element: body #descendant-div1	
+Pass	In-document Element.querySelectorAll: Descendant combinator, matching element with id that is a descendant of an element: div #descendant-div1	
+Pass	In-document Element.querySelector: Descendant combinator, matching element with id that is a descendant of an element: div #descendant-div1	
+Pass	In-document Element.querySelectorAll: Descendant combinator, matching element with id that is a descendant of an element with id: #descendant #descendant-div2	
+Pass	In-document Element.querySelector: Descendant combinator, matching element with id that is a descendant of an element with id: #descendant #descendant-div2	
+Pass	In-document Element.querySelectorAll: Descendant combinator, matching element with class that is a descendant of an element with id: #descendant .descendant-div2	
+Pass	In-document Element.querySelector: Descendant combinator, matching element with class that is a descendant of an element with id: #descendant .descendant-div2	
+Pass	In-document Element.querySelectorAll: Descendant combinator, matching element with class that is a descendant of an element with class: .descendant-div1 .descendant-div3	
+Pass	In-document Element.querySelector: Descendant combinator, matching element with class that is a descendant of an element with class: .descendant-div1 .descendant-div3	
+Pass	In-document Element.querySelectorAll: Descendant combinator, not matching element with id that is not a descendant of an element with id: #descendant-div1 #descendant-div4	
+Pass	In-document Element.querySelector: Descendant combinator, not matching element with id that is not a descendant of an element with id: #descendant-div1 #descendant-div4	
+Pass	In-document Element.querySelectorAll: Descendant combinator, whitespace characters: #descendant #descendant-div2	
+Pass	In-document Element.querySelector: Descendant combinator, whitespace characters: #descendant #descendant-div2	
+Pass	In-document Element.querySelectorAll: Child combinator, matching element that is a child of an element with id: #child>div	
+Pass	In-document Element.querySelector: Child combinator, matching element that is a child of an element with id: #child>div	
+Pass	In-document Element.querySelectorAll: Child combinator, matching element with id that is a child of an element: div>#child-div1	
+Pass	In-document Element.querySelector: Child combinator, matching element with id that is a child of an element: div>#child-div1	
+Pass	In-document Element.querySelectorAll: Child combinator, matching element with id that is a child of an element with id: #child>#child-div1	
+Pass	In-document Element.querySelector: Child combinator, matching element with id that is a child of an element with id: #child>#child-div1	
+Pass	In-document Element.querySelectorAll: Child combinator, matching element with id that is a child of an element with class: #child-div1>.child-div2	
+Pass	In-document Element.querySelector: Child combinator, matching element with id that is a child of an element with class: #child-div1>.child-div2	
+Pass	In-document Element.querySelectorAll: Child combinator, matching element with class that is a child of an element with class: .child-div1>.child-div2	
+Pass	In-document Element.querySelector: Child combinator, matching element with class that is a child of an element with class: .child-div1>.child-div2	
+Pass	In-document Element.querySelectorAll: Child combinator, not matching element with id that is not a child of an element with id: #child>#child-div3	
+Pass	In-document Element.querySelector: Child combinator, not matching element with id that is not a child of an element with id: #child>#child-div3	
+Pass	In-document Element.querySelectorAll: Child combinator, not matching element with id that is not a child of an element with class: #child-div1>.child-div3	
+Pass	In-document Element.querySelector: Child combinator, not matching element with id that is not a child of an element with class: #child-div1>.child-div3	
+Pass	In-document Element.querySelectorAll: Child combinator, not matching element with class that is not a child of an element with class: .child-div1>.child-div3	
+Pass	In-document Element.querySelector: Child combinator, not matching element with class that is not a child of an element with class: .child-div1>.child-div3	
+Pass	In-document Element.querySelectorAll: Child combinator, surrounded by whitespace: #child-div1 > #child-div2	
+Pass	In-document Element.querySelector: Child combinator, surrounded by whitespace: #child-div1 > #child-div2	
+Pass	In-document Element.querySelectorAll: Child combinator, whitespace after: #child-div1> #child-div2	
+Pass	In-document Element.querySelector: Child combinator, whitespace after: #child-div1> #child-div2	
+Pass	In-document Element.querySelectorAll: Child combinator, whitespace before: #child-div1 >#child-div2	
+Pass	In-document Element.querySelector: Child combinator, whitespace before: #child-div1 >#child-div2	
+Pass	In-document Element.querySelectorAll: Child combinator, no whitespace: #child-div1>#child-div2	
+Pass	In-document Element.querySelector: Child combinator, no whitespace: #child-div1>#child-div2	
+Pass	In-document Element.querySelectorAll: Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id: #adjacent-div2+div	
+Pass	In-document Element.querySelector: Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id: #adjacent-div2+div	
+Pass	In-document Element.querySelectorAll: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element: div+#adjacent-div4	
+Pass	In-document Element.querySelector: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element: div+#adjacent-div4	
+Pass	In-document Element.querySelectorAll: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id: #adjacent-div2+#adjacent-div4	
+Pass	In-document Element.querySelector: Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id: #adjacent-div2+#adjacent-div4	
+Pass	In-document Element.querySelectorAll: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id: #adjacent-div2+.adjacent-div4	
+Pass	In-document Element.querySelector: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id: #adjacent-div2+.adjacent-div4	
+Pass	In-document Element.querySelectorAll: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class: .adjacent-div2+.adjacent-div4	
+Pass	In-document Element.querySelector: Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class: .adjacent-div2+.adjacent-div4	
+Pass	In-document Element.querySelectorAll: Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element: #adjacent div+p	
+Pass	In-document Element.querySelector: Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element: #adjacent div+p	
+Pass	In-document Element.querySelectorAll: Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id: #adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1	
+Pass	In-document Element.querySelector: Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id: #adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1	
+Pass	In-document Element.querySelectorAll: Adjacent sibling combinator, surrounded by whitespace: #adjacent-p2 + #adjacent-p3	
+Pass	In-document Element.querySelector: Adjacent sibling combinator, surrounded by whitespace: #adjacent-p2 + #adjacent-p3	
+Pass	In-document Element.querySelectorAll: Adjacent sibling combinator, whitespace after: #adjacent-p2+ #adjacent-p3	
+Pass	In-document Element.querySelector: Adjacent sibling combinator, whitespace after: #adjacent-p2+ #adjacent-p3	
+Pass	In-document Element.querySelectorAll: Adjacent sibling combinator, whitespace before: #adjacent-p2 +#adjacent-p3	
+Pass	In-document Element.querySelector: Adjacent sibling combinator, whitespace before: #adjacent-p2 +#adjacent-p3	
+Pass	In-document Element.querySelectorAll: Adjacent sibling combinator, no whitespace: #adjacent-p2+#adjacent-p3	
+Pass	In-document Element.querySelector: Adjacent sibling combinator, no whitespace: #adjacent-p2+#adjacent-p3	
+Pass	In-document Element.querySelectorAll: General sibling combinator, matching element that is a sibling of an element with id: #sibling-div2~div	
+Pass	In-document Element.querySelector: General sibling combinator, matching element that is a sibling of an element with id: #sibling-div2~div	
+Pass	In-document Element.querySelectorAll: General sibling combinator, matching element with id that is a sibling of an element: div~#sibling-div4	
+Pass	In-document Element.querySelector: General sibling combinator, matching element with id that is a sibling of an element: div~#sibling-div4	
+Pass	In-document Element.querySelectorAll: General sibling combinator, matching element with id that is a sibling of an element with id: #sibling-div2~#sibling-div4	
+Pass	In-document Element.querySelector: General sibling combinator, matching element with id that is a sibling of an element with id: #sibling-div2~#sibling-div4	
+Pass	In-document Element.querySelectorAll: General sibling combinator, matching element with class that is a sibling of an element with id: #sibling-div2~.sibling-div	
+Pass	In-document Element.querySelector: General sibling combinator, matching element with class that is a sibling of an element with id: #sibling-div2~.sibling-div	
+Pass	In-document Element.querySelectorAll: General sibling combinator, matching p element that is a sibling of a div element: #sibling div~p	
+Pass	In-document Element.querySelector: General sibling combinator, matching p element that is a sibling of a div element: #sibling div~p	
+Pass	In-document Element.querySelectorAll: General sibling combinator, not matching element with id that is not a sibling after a p element: #sibling>p~div	
+Pass	In-document Element.querySelector: General sibling combinator, not matching element with id that is not a sibling after a p element: #sibling>p~div	
+Pass	In-document Element.querySelectorAll: General sibling combinator, not matching element with id that is not a sibling after an element with id: #sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1	
+Pass	In-document Element.querySelector: General sibling combinator, not matching element with id that is not a sibling after an element with id: #sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1	
+Pass	In-document Element.querySelectorAll: General sibling combinator, surrounded by whitespace: #sibling-p2 ~ #sibling-p3	
+Pass	In-document Element.querySelector: General sibling combinator, surrounded by whitespace: #sibling-p2 ~ #sibling-p3	
+Pass	In-document Element.querySelectorAll: General sibling combinator, whitespace after: #sibling-p2~ #sibling-p3	
+Pass	In-document Element.querySelector: General sibling combinator, whitespace after: #sibling-p2~ #sibling-p3	
+Pass	In-document Element.querySelectorAll: General sibling combinator, whitespace before: #sibling-p2 ~#sibling-p3	
+Pass	In-document Element.querySelector: General sibling combinator, whitespace before: #sibling-p2 ~#sibling-p3	
+Pass	In-document Element.querySelectorAll: General sibling combinator, no whitespace: #sibling-p2~#sibling-p3	
+Pass	In-document Element.querySelector: General sibling combinator, no whitespace: #sibling-p2~#sibling-p3	
+Pass	In-document Element.querySelectorAll: Syntax, group of selectors separator, surrounded by whitespace: #group em , #group strong	
+Pass	In-document Element.querySelector: Syntax, group of selectors separator, surrounded by whitespace: #group em , #group strong	
+Pass	In-document Element.querySelectorAll: Syntax, group of selectors separator, whitespace after: #group em, #group strong	
+Pass	In-document Element.querySelector: Syntax, group of selectors separator, whitespace after: #group em, #group strong	
+Pass	In-document Element.querySelectorAll: Syntax, group of selectors separator, whitespace before: #group em ,#group strong	
+Pass	In-document Element.querySelector: Syntax, group of selectors separator, whitespace before: #group em ,#group strong	
+Pass	In-document Element.querySelectorAll: Syntax, group of selectors separator, no whitespace: #group em,#group strong	
+Pass	In-document Element.querySelector: Syntax, group of selectors separator, no whitespace: #group em,#group strong	
+Fail	In-document Element.querySelectorAll: Slotted selector: ::slotted(foo)	Failed to parse selector
+Fail	In-document Element.querySelector: Slotted selector: ::slotted(foo)	Failed to parse selector
+Fail	In-document Element.querySelectorAll: Slotted selector (no matching closing paren): ::slotted(foo	Failed to parse selector
+Fail	In-document Element.querySelector: Slotted selector (no matching closing paren): ::slotted(foo	Failed to parse selector

+ 120 - 0
Tests/LibWeb/Text/input/wpt-import/dom/nodes/ParentNode-querySelector-All.html

@@ -0,0 +1,120 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<meta name=timeout content=long>
+<title>Selectors-API Test Suite: HTML</title>
+<script src="../../resources/testharness.js"></script>
+<script src="../../resources/testharnessreport.js"></script>
+<script src="selectors.js"></script>
+<script src="ParentNode-querySelector-All.js"></script>
+<style>iframe { visibility: hidden; position: absolute; }</style>
+
+<div id="log">This test requires JavaScript.</div>
+
+<script>
+async_test(function() {
+  var frame = document.createElement("iframe");
+  var self = this;
+  frame.onload = function() {
+    // :target doesn't work before a page rendering on some browsers.  We run
+    // tests after an animation frame because it may be later than the first
+    // page rendering.
+    requestAnimationFrame(self.step_func_done(init.bind(self, frame)));
+  };
+  frame.src = "../../../../data/ParentNode-querySelector-All-content.html#target";
+  document.body.appendChild(frame);
+});
+
+function init(target) {
+  /*
+   * This test suite tests Selectors API methods in 4 different contexts:
+   * 1. Document node
+   * 2. In-document Element node
+   * 3. Detached Element node (an element with no parent, not in the document)
+   * 4. Document Fragment node
+   *
+   * For each context, the following tests are run:
+   *
+   * The interface check tests ensure that each type of node exposes the Selectors API methods
+   *
+   * The special selector tests verify the result of passing special values for the selector parameter,
+   * to ensure that the correct WebIDL processing is performed, such as stringification of null and
+   * undefined and missing parameter. The universal selector is also tested here, rather than with the
+   * rest of ordinary selectors for practical reasons.
+   *
+   * The static list verification tests ensure that the node lists returned by the method remain unchanged
+   * due to subsequent document modication, and that a new list is generated each time the method is
+   * invoked based on the current state of the document.
+   *
+   * The invalid selector tests ensure that SyntaxError is thrown for invalid forms of selectors
+   *
+   * The valid selector tests check the result from querying many different types of selectors, with a
+   * list of expected elements. This checks that querySelector() always returns the first result from
+   * querySelectorAll(), and that all matching elements are correctly returned in tree-order. The tests
+   * can be limited by specifying the test types to run, using the testType variable. The constants for this
+   * can be found in selectors.js.
+   *
+   * All the selectors tested for both the valid and invalid selector tests are found in selectors.js.
+   * See comments in that file for documentation of the format used.
+   *
+   * The ParentNode-querySelector-All.js file contains all the common test functions for running each of the aforementioned tests
+   */
+
+  var testType = TEST_QSA;
+  var docType  = "html"; // Only run tests suitable for HTML
+
+  // Prepare the nodes for testing
+  var doc = target.contentDocument;                 // Document Node tests
+
+  var element = doc.getElementById("root");   // In-document Element Node tests
+
+  //Setup the namespace tests
+  setupSpecialElements(doc, element);
+
+  var outOfScope = element.cloneNode(true);   // Append this to the body before running the in-document
+                                               // Element tests, but after running the Document tests. This
+                                               // tests that no elements that are not descendants of element
+                                               // are selected.
+
+  traverse(outOfScope, function(elem) {        // Annotate each element as being a clone; used for verifying
+    elem.setAttribute("data-clone", "");     // that none of these elements ever match.
+  });
+
+
+  var detached = element.cloneNode(true);     // Detached Element Node tests
+
+  var fragment = doc.createDocumentFragment(); // Fragment Node tests
+  fragment.appendChild(element.cloneNode(true));
+
+  var empty = document.createElement("div"); // Empty Node tests
+
+  // Setup Tests
+  interfaceCheck("Document", doc);
+  interfaceCheck("Detached Element", detached);
+  interfaceCheck("Fragment", fragment);
+  interfaceCheck("In-document Element", element);
+
+  runSpecialSelectorTests("Document", doc);
+  runSpecialSelectorTests("Detached Element", detached);
+  runSpecialSelectorTests("Fragment", fragment);
+  runSpecialSelectorTests("In-document Element", element);
+
+  verifyStaticList("Document", doc, doc);
+  verifyStaticList("Detached Element", doc, detached);
+  verifyStaticList("Fragment", doc, fragment);
+  verifyStaticList("In-document Element", doc, element);
+
+  runInvalidSelectorTest("Document", doc, invalidSelectors);
+  runInvalidSelectorTest("Detached Element", detached, invalidSelectors);
+  runInvalidSelectorTest("Fragment", fragment, invalidSelectors);
+  runInvalidSelectorTest("In-document Element", element, invalidSelectors);
+  runInvalidSelectorTest("Empty Element", empty, invalidSelectors);
+
+  runValidSelectorTest("Document", doc, validSelectors, testType, docType);
+  runValidSelectorTest("Detached Element", detached, validSelectors, testType, docType);
+  runValidSelectorTest("Fragment", fragment, validSelectors, testType, docType);
+
+  doc.body.appendChild(outOfScope); // Append before in-document Element tests.
+                                    // None of these elements should match
+  runValidSelectorTest("In-document Element", element, validSelectors, testType, docType);
+}
+</script>

+ 261 - 0
Tests/LibWeb/Text/input/wpt-import/dom/nodes/ParentNode-querySelector-All.js

@@ -0,0 +1,261 @@
+// Require selectors.js to be included before this.
+
+/*
+ * Create and append special elements that cannot be created correctly with HTML markup alone.
+ */
+function setupSpecialElements(doc, parent) {
+  // Setup null and undefined tests
+  parent.appendChild(doc.createElement("null"));
+  parent.appendChild(doc.createElement("undefined"));
+
+  // Setup namespace tests
+  var anyNS = doc.createElement("div");
+  var noNS = doc.createElement("div");
+  anyNS.id = "any-namespace";
+  noNS.id = "no-namespace";
+
+  var divs;
+  div = [doc.createElement("div"),
+         doc.createElementNS("http://www.w3.org/1999/xhtml", "div"),
+         doc.createElementNS("", "div"),
+         doc.createElementNS("http://www.example.org/ns", "div")];
+
+  div[0].id = "any-namespace-div1";
+  div[1].id = "any-namespace-div2";
+  div[2].setAttribute("id", "any-namespace-div3"); // Non-HTML elements can't use .id property
+  div[3].setAttribute("id", "any-namespace-div4");
+
+  for (var i = 0; i < div.length; i++) {
+    anyNS.appendChild(div[i])
+  }
+
+  div = [doc.createElement("div"),
+         doc.createElementNS("http://www.w3.org/1999/xhtml", "div"),
+         doc.createElementNS("", "div"),
+         doc.createElementNS("http://www.example.org/ns", "div")];
+
+  div[0].id = "no-namespace-div1";
+  div[1].id = "no-namespace-div2";
+  div[2].setAttribute("id", "no-namespace-div3"); // Non-HTML elements can't use .id property
+  div[3].setAttribute("id", "no-namespace-div4");
+
+  for (i = 0; i < div.length; i++) {
+    noNS.appendChild(div[i])
+  }
+
+  parent.appendChild(anyNS);
+  parent.appendChild(noNS);
+
+  var span = doc.getElementById("attr-presence-i1");
+  span.setAttributeNS("http://www.example.org/ns", "title", "");
+}
+
+/*
+ * Check that the querySelector and querySelectorAll methods exist on the given Node
+ */
+function interfaceCheck(type, obj) {
+  test(function() {
+    var q = typeof obj.querySelector === "function";
+    assert_true(q, type + " supports querySelector.");
+  }, type + " supports querySelector")
+
+  test(function() {
+    var qa = typeof obj.querySelectorAll === "function";
+    assert_true( qa, type + " supports querySelectorAll.");
+  }, type + " supports querySelectorAll")
+
+  test(function() {
+    var list = obj.querySelectorAll("div");
+    if (obj.ownerDocument) { // The object is not a Document
+      assert_true(list instanceof obj.ownerDocument.defaultView.NodeList, "The result should be an instance of a NodeList")
+    } else { // The object is a Document
+      assert_true(list instanceof obj.defaultView.NodeList, "The result should be an instance of a NodeList")
+    }
+  }, type + ".querySelectorAll returns NodeList instance")
+}
+
+/*
+ * Verify that the NodeList returned by querySelectorAll is static and and that a new list is created after
+ * each call. A static list should not be affected by subsequent changes to the DOM.
+ */
+function verifyStaticList(type, doc, root) {
+  var pre, post, preLength;
+
+  test(function() {
+    pre = root.querySelectorAll("div");
+    preLength = pre.length;
+
+    var div = doc.createElement("div");
+    (root.body || root).appendChild(div);
+
+    assert_equals(pre.length, preLength, "The length of the NodeList should not change.")
+  }, type + ": static NodeList")
+
+  test(function() {
+    post = root.querySelectorAll("div"),
+    assert_equals(post.length, preLength + 1, "The length of the new NodeList should be 1 more than the previous list.")
+  }, type + ": new NodeList")
+}
+
+/*
+ * Verify handling of special values for the selector parameter, including stringification of
+ * null and undefined, and the handling of the empty string.
+ */
+function runSpecialSelectorTests(type, root) {
+  let global = (root.ownerDocument || root).defaultView;
+
+  test(function() { // 1
+    assert_equals(root.querySelectorAll(null).length, 1, "This should find one element with the tag name 'NULL'.");
+  }, type + ".querySelectorAll null")
+
+  test(function() { // 2
+    assert_equals(root.querySelectorAll(undefined).length, 1, "This should find one element with the tag name 'UNDEFINED'.");
+  }, type + ".querySelectorAll undefined")
+
+  test(function() { // 3
+    assert_throws_js(global.TypeError, function() {
+      root.querySelectorAll();
+    }, "This should throw a TypeError.")
+  }, type + ".querySelectorAll no parameter")
+
+  test(function() { // 4
+    var elm = root.querySelector(null)
+    assert_not_equals(elm, null, "This should find an element.");
+    assert_equals(elm.tagName.toUpperCase(), "NULL", "The tag name should be 'NULL'.")
+  }, type + ".querySelector null")
+
+  test(function() { // 5
+    var elm = root.querySelector(undefined)
+    assert_not_equals(elm, undefined, "This should find an element.");
+    assert_equals(elm.tagName.toUpperCase(), "UNDEFINED", "The tag name should be 'UNDEFINED'.")
+  }, type + ".querySelector undefined")
+
+  test(function() { // 6
+    assert_throws_js(global.TypeError, function() {
+      root.querySelector();
+    }, "This should throw a TypeError.")
+  }, type + ".querySelector no parameter")
+
+  test(function() { // 7
+    result = root.querySelectorAll("*");
+    var i = 0;
+    traverse(root, function(elem) {
+      if (elem !== root) {
+        assert_equals(elem, result[i], "The result in index " + i + " should be in tree order.");
+        i++;
+      }
+    })
+  }, type + ".querySelectorAll tree order");
+}
+
+/*
+ * Execute queries with the specified valid selectors for both querySelector() and querySelectorAll()
+ * Only run these tests when results are expected. Don't run for syntax error tests.
+ */
+function runValidSelectorTest(type, root, selectors, testType, docType) {
+  var nodeType = "";
+  switch (root.nodeType) {
+    case Node.DOCUMENT_NODE:
+      nodeType = "document";
+      break;
+    case Node.ELEMENT_NODE:
+      nodeType = root.parentNode ? "element" : "detached";
+      break;
+    case Node.DOCUMENT_FRAGMENT_NODE:
+      nodeType = "fragment";
+      break;
+    default:
+      assert_unreached();
+      nodeType = "unknown"; // This should never happen.
+  }
+
+  for (var i = 0; i < selectors.length; i++) {
+    var s = selectors[i];
+    var n = s["name"];
+    var q = s["selector"];
+    var e = s["expect"];
+
+    if ((!s["exclude"] || (s["exclude"].indexOf(nodeType) === -1 && s["exclude"].indexOf(docType) === -1))
+     && (s["testType"] & testType) ) {
+      var foundall, found;
+
+      test(function() {
+        foundall = root.querySelectorAll(q);
+        assert_not_equals(foundall, null, "The method should not return null.")
+        assert_equals(foundall.length, e.length, "The method should return the expected number of matches.")
+
+        for (var i = 0; i < e.length; i++) {
+          assert_not_equals(foundall[i], null, "The item in index " + i + " should not be null.")
+          assert_equals(foundall[i].getAttribute("id"), e[i], "The item in index " + i + " should have the expected ID.");
+          assert_false(foundall[i].hasAttribute("data-clone"), "This should not be a cloned element.");
+        }
+      }, type + ".querySelectorAll: " + n + ": " + q);
+
+      test(function() {
+        found = root.querySelector(q);
+
+        if (e.length > 0) {
+          assert_not_equals(found, null, "The method should return a match.")
+          assert_equals(found.getAttribute("id"), e[0], "The method should return the first match.");
+          assert_equals(found, foundall[0], "The result should match the first item from querySelectorAll.");
+          assert_false(found.hasAttribute("data-clone"), "This should not be annotated as a cloned element.");
+        } else {
+          assert_equals(found, null, "The method should not match anything.");
+        }
+      }, type + ".querySelector: " + n + ": " + q);
+    }
+  }
+}
+
+function windowFor(root) {
+  return root.defaultView || root.ownerDocument.defaultView;
+}
+
+/*
+ * Execute queries with the specified invalid selectors for both querySelector() and querySelectorAll()
+ * Only run these tests when errors are expected. Don't run for valid selector tests.
+ */
+function runInvalidSelectorTest(type, root, selectors) {
+  for (var i = 0; i < selectors.length; i++) {
+    var s = selectors[i];
+    var n = s["name"];
+    var q = s["selector"];
+
+    test(function() {
+      assert_throws_dom("SyntaxError", windowFor(root).DOMException, function() {
+        root.querySelector(q)
+      });
+    }, type + ".querySelector: " + n + ": " + q);
+
+    test(function() {
+      assert_throws_dom("SyntaxError", windowFor(root).DOMException, function() {
+        root.querySelectorAll(q)
+      });
+    }, type + ".querySelectorAll: " + n + ": " + q);
+  }
+}
+
+function traverse(elem, fn) {
+  if (elem.nodeType === elem.ELEMENT_NODE) {
+    fn(elem);
+  }
+  elem = elem.firstChild;
+  while (elem) {
+    traverse(elem, fn);
+    elem = elem.nextSibling;
+  }
+}
+
+function getNodeType(node) {
+  switch (node.nodeType) {
+    case Node.DOCUMENT_NODE:
+      return "document";
+    case Node.ELEMENT_NODE:
+      return node.parentNode ? "element" : "detached";
+    case Node.DOCUMENT_FRAGMENT_NODE:
+      return "fragment";
+    default:
+      assert_unreached();
+      return "unknown"; // This should never happen.
+  }
+}

+ 755 - 0
Tests/LibWeb/Text/input/wpt-import/dom/nodes/selectors.js

@@ -0,0 +1,755 @@
+// Bit-mapped flags to indicate which tests the selector is suitable for
+var TEST_QSA              = 0x01; // querySelector() and querySelectorAll() tests
+var TEST_FIND             = 0x04; // find() and findAll() tests, may be unsuitable for querySelector[All]
+var TEST_MATCH            = 0x10; // matches() tests
+
+/*
+ * All of these invalid selectors should result in a SyntaxError being thrown by the APIs.
+ *
+ *   name:     A descriptive name of the selector being tested
+ *   selector: The selector to test
+ */
+var invalidSelectors = [
+  {name: "Empty String",                 selector: ""},
+  {name: "Invalid character",            selector: "["},
+  {name: "Invalid character",            selector: "]"},
+  {name: "Invalid character",            selector: "("},
+  {name: "Invalid character",            selector: ")"},
+  {name: "Invalid character",            selector: "{"},
+  {name: "Invalid character",            selector: "}"},
+  {name: "Invalid character",            selector: "<"},
+  {name: "Invalid character",            selector: ">"},
+  {name: "Invalid ID",                   selector: "#"},
+  {name: "Invalid group of selectors",   selector: "div,"},
+  {name: "Invalid class",                selector: "."},
+  {name: "Invalid class",                selector: ".5cm"},
+  {name: "Invalid class",                selector: "..test"},
+  {name: "Invalid class",                selector: ".foo..quux"},
+  {name: "Invalid class",                selector: ".bar."},
+  {name: "Invalid combinator",           selector: "div % address, p"},
+  {name: "Invalid combinator",           selector: "div ++ address, p"},
+  {name: "Invalid combinator",           selector: "div ~~ address, p"},
+  {name: "Invalid [att=value] selector", selector: "[*=test]"},
+  {name: "Invalid [att=value] selector", selector: "[*|*=test]"},
+  {name: "Invalid [att=value] selector", selector: "[class= space unquoted ]"},
+  {name: "Unknown pseudo-class",         selector: "div:example"},
+  {name: "Unknown pseudo-class",         selector: ":example"},
+  {name: "Unknown pseudo-class",         selector: "div:linkexample"},
+  {name: "Unknown pseudo-element",       selector: "div::example"},
+  {name: "Unknown pseudo-element",       selector: "::example"},
+  {name: "Invalid pseudo-element",       selector: ":::before"},
+  {name: "Invalid pseudo-element",       selector: ":: before"},
+  {name: "Undeclared namespace",         selector: "ns|div"},
+  {name: "Undeclared namespace",         selector: ":not(ns|div)"},
+  {name: "Invalid namespace",            selector: "^|div"},
+  {name: "Invalid namespace",            selector: "$|div"},
+  {name: "Relative selector",            selector: ">*"},
+];
+
+/*
+ * All of these should be valid selectors, expected to match zero or more elements in the document.
+ * None should throw any errors.
+ *
+ *   name:     A descriptive name of the selector being tested
+ *   selector: The selector to test
+ *   expect:   A list of IDs of the elements expected to be matched. List must be given in tree order.
+ *   exclude:  An array of contexts to exclude from testing. The valid values are:
+ *             ["document", "element", "fragment", "detached", "html", "xhtml"]
+ *             The "html" and "xhtml" values represent the type of document being queried. These are useful
+ *             for tests that are affected by differences between HTML and XML, such as case sensitivity.
+ *   level:    An integer indicating the CSS or Selectors level in which the selector being tested was introduced.
+ *   testType: A bit-mapped flag indicating the type of test.
+ *
+ * Note: Interactive pseudo-classes (:active :hover and :focus) have not been tested in this test suite.
+ */
+var validSelectors = [
+  // Type Selector
+  {name: "Type selector, matching html element", selector: "html", expect: ["html"],          exclude: ["element", "fragment", "detached"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Type selector, matching html element", selector: "html", expect: [] /*no matches*/, exclude: ["document"],                        level: 1, testType: TEST_QSA},
+  {name: "Type selector, matching body element", selector: "body", expect: ["body"],          exclude: ["element", "fragment", "detached"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Type selector, matching body element", selector: "body", expect: [] /*no matches*/, exclude: ["document"],                        level: 1, testType: TEST_QSA},
+
+  // Universal Selector
+  {name: "Universal selector, matching all elements",                                    selector: "*",              expect: ["universal", "universal-p1", "universal-code1", "universal-hr1", "universal-pre1", "universal-span1", "universal-p2", "universal-a1", "universal-address1", "universal-code2", "universal-a2"], level: 2, testType: TEST_MATCH},
+  {name: "Universal selector, matching all children of element with specified ID",       selector: "#universal>*",   expect: ["universal-p1", "universal-hr1", "universal-pre1", "universal-p2", "universal-address1"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Universal selector, matching all grandchildren of element with specified ID",  selector: "#universal>*>*", expect: ["universal-code1", "universal-span1", "universal-a1", "universal-code2"],                 level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Universal selector, matching all children of empty element with specified ID", selector: "#empty>*",       expect: [] /*no matches*/,                                                                         level: 2, testType: TEST_QSA},
+  {name: "Universal selector, matching all descendants of element with specified ID",    selector: "#universal *",   expect: ["universal-p1", "universal-code1", "universal-hr1", "universal-pre1", "universal-span1", "universal-p2", "universal-a1", "universal-address1", "universal-code2", "universal-a2"], level: 2, testType: TEST_QSA | TEST_MATCH},
+
+  // Attribute Selectors
+  // - presence                  [att]
+  {name: "Attribute presence selector, matching align attribute with value",                    selector: ".attr-presence-div1[align]",                             expect: ["attr-presence-div1"],                                                                   level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute presence selector, matching align attribute with empty value",              selector: ".attr-presence-div2[align]",                             expect: ["attr-presence-div2"],                                                                   level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute presence selector, matching title attribute, case insensitivity",           selector: "#attr-presence [*|TiTlE]",                                 expect: ["attr-presence-a1", "attr-presence-span1", "attr-presence-i1"], exclude: ["xhtml"],    level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute presence selector, not matching title attribute, case sensitivity",         selector: "#attr-presence [*|TiTlE]",                                 expect: [],                                                              exclude: ["html"],     level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute presence selector, matching custom data-* attribute",                       selector: "[data-attr-presence]",                                   expect: ["attr-presence-pre1", "attr-presence-blockquote1"],                                      level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute presence selector, not matching attribute with similar name",               selector: ".attr-presence-div3[align], .attr-presence-div4[align]", expect: [] /*no matches*/,                                                                        level: 2, testType: TEST_QSA},
+  {name: "Attribute presence selector, matching attribute with non-ASCII characters",           selector: "ul[data-中文]",                                            expect: ["attr-presence-ul1"],                                                                    level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute presence selector, not matching default option without selected attribute", selector: "#attr-presence-select1 option[selected]",                expect: [] /* no matches */,                                                                      level: 2, testType: TEST_QSA},
+  {name: "Attribute presence selector, matching option with selected attribute",                selector: "#attr-presence-select2 option[selected]",                expect: ["attr-presence-select2-option4"],                                                        level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute presence selector, matching multiple options with selected attributes",     selector: "#attr-presence-select3 option[selected]",                expect: ["attr-presence-select3-option2", "attr-presence-select3-option3"],                       level: 2, testType: TEST_QSA | TEST_MATCH},
+
+  // - value                     [att=val]
+  {name: "Attribute value selector, matching align attribute with value",                                    selector: "#attr-value [align=\"center\"]",                                     expect: ["attr-value-div1"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute value selector, matching align attribute with value, unclosed bracket",                  selector: "#attr-value [align=\"center\"",                                      expect: ["attr-value-div1"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute value selector, matching align attribute with empty value",                              selector: "#attr-value [align=\"\"]",                                           expect: ["attr-value-div2"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute value selector, not matching align attribute with partial value",                        selector: "#attr-value [align=\"c\"]",                                          expect: [] /*no matches*/,   level: 2, testType: TEST_QSA},
+  {name: "Attribute value selector, not matching align attribute with incorrect value",                      selector: "#attr-value [align=\"centera\"]",                                    expect: [] /*no matches*/,   level: 2, testType: TEST_QSA},
+  {name: "Attribute value selector, matching custom data-* attribute with unicode escaped value",            selector: "[data-attr-value=\"\\e9\"]",                                         expect: ["attr-value-div3"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute value selector, matching custom data-* attribute with escaped character",                selector: "[data-attr-value\_foo=\"\\e9\"]",                                    expect: ["attr-value-div4"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute value selector with single-quoted value, matching multiple inputs with type attributes", selector: "#attr-value input[type='hidden'],#attr-value input[type='radio']",   expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute value selector with double-quoted value, matching multiple inputs with type attributes", selector: "#attr-value input[type=\"hidden\"],#attr-value input[type='radio']", expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute value selector with unquoted value, matching multiple inputs with type attributes",      selector: "#attr-value input[type=hidden],#attr-value input[type=radio]",       expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute value selector, matching attribute with value using non-ASCII characters",               selector: "[data-attr-value=中文]",                                               expect: ["attr-value-div5"], level: 2, testType: TEST_QSA | TEST_MATCH},
+
+  // - whitespace-separated list [att~=val]
+  {name: "Attribute whitespace-separated list selector, matching class attribute with value",                                  selector: "#attr-whitespace [class~=\"div1\"]",                                        expect: ["attr-whitespace-div1"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector, not matching class attribute with empty value",                        selector: "#attr-whitespace [class~=\"\"]",                                            expect: [] /*no matches*/ ,       level: 2, testType: TEST_QSA},
+  {name: "Attribute whitespace-separated list selector, not matching class attribute with partial value",                      selector: "[data-attr-whitespace~=\"div\"]",                                           expect: [] /*no matches*/ ,       level: 2, testType: TEST_QSA},
+  {name: "Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value",          selector: "[data-attr-whitespace~=\"\\0000e9\"]",                                      expect: ["attr-whitespace-div4"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character",              selector: "[data-attr-whitespace\_foo~=\"\\e9\"]",                                     expect: ["attr-whitespace-div5"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes", selector: "#attr-whitespace a[rel~='bookmark'],  #attr-whitespace a[rel~='nofollow']", expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes", selector: "#attr-whitespace a[rel~=\"bookmark\"],#attr-whitespace a[rel~='nofollow']", expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes",      selector: "#attr-whitespace a[rel~=bookmark],    #attr-whitespace a[rel~=nofollow]",   expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector with double-quoted value, not matching value with space",               selector: "#attr-whitespace a[rel~=\"book mark\"]",                                    expect: [] /* no matches */,      level: 2, testType: TEST_QSA},
+  {name: "Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters",       selector: "#attr-whitespace [title~=中文]",                                              expect: ["attr-whitespace-p1"],   level: 2, testType: TEST_QSA | TEST_MATCH},
+
+  // - hyphen-separated list     [att|=val]
+  {name: "Attribute hyphen-separated list selector, not matching unspecified lang attribute",    selector: "#attr-hyphen-div1[lang|=\"en\"]",    expect: [] /*no matches*/,    level: 2, testType: TEST_QSA},
+  {name: "Attribute hyphen-separated list selector, matching lang attribute with exact value",   selector: "#attr-hyphen-div2[lang|=\"fr\"]",    expect: ["attr-hyphen-div2"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute hyphen-separated list selector, matching lang attribute with partial value", selector: "#attr-hyphen-div3[lang|=\"en\"]",    expect: ["attr-hyphen-div3"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute hyphen-separated list selector, not matching incorrect value",               selector: "#attr-hyphen-div4[lang|=\"es-AR\"]", expect: [] /*no matches*/,    level: 2, testType: TEST_QSA},
+
+  // - substring begins-with     [att^=val] (Level 3)
+  {name: "Attribute begins with selector, matching href attributes beginning with specified substring",                             selector: "#attr-begins a[href^=\"http://www\"]", expect: ["attr-begins-a1", "attr-begins-a3"],     level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute begins with selector, matching lang attributes beginning with specified substring, ",                           selector: "#attr-begins [lang^=\"en-\"]",         expect: ["attr-begins-div2", "attr-begins-div4"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute begins with selector, not matching class attribute with empty value",                                           selector: "#attr-begins [class^=\"\"]",          expect: [] /*no matches*/,                        level: 3, testType: TEST_QSA},
+  {name: "Attribute begins with selector, not matching class attribute not beginning with specified substring",                     selector: "#attr-begins [class^=apple]",          expect: [] /*no matches*/,                        level: 3, testType: TEST_QSA},
+  {name: "Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring",    selector: "#attr-begins [class^=' apple']",       expect: ["attr-begins-p1"],                       level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring",    selector: "#attr-begins [class^=\" apple\"]",     expect: ["attr-begins-p1"],                       level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring", selector: "#attr-begins [class^= apple]",         expect: [] /*no matches*/,                        level: 3, testType: TEST_QSA},
+
+  // - substring ends-with       [att$=val] (Level 3)
+  {name: "Attribute ends with selector, matching href attributes ending with specified substring",                             selector: "#attr-ends a[href$=\".org\"]",   expect: ["attr-ends-a1", "attr-ends-a3"],     level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute ends with selector, matching lang attributes ending with specified substring, ",                           selector: "#attr-ends [lang$=\"-CH\"]",     expect: ["attr-ends-div2", "attr-ends-div4"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute ends with selector, not matching class attribute with empty value",                                        selector: "#attr-ends [class$=\"\"]",       expect: [] /*no matches*/,                    level: 3, testType: TEST_QSA},
+  {name: "Attribute ends with selector, not matching class attribute not ending with specified substring",                     selector: "#attr-ends [class$=apple]",      expect: [] /*no matches*/,                    level: 3, testType: TEST_QSA},
+  {name: "Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring",    selector: "#attr-ends [class$='apple ']",   expect: ["attr-ends-p1"],                     level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring",    selector: "#attr-ends [class$=\"apple \"]", expect: ["attr-ends-p1"],                     level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring", selector: "#attr-ends [class$=apple ]",     expect: [] /*no matches*/,                    level: 3, testType: TEST_QSA},
+
+  // - substring contains        [att*=val] (Level 3)
+  {name: "Attribute contains selector, matching href attributes beginning with specified substring",                          selector: "#attr-contains a[href*=\"http://www\"]",     expect: ["attr-contains-a1", "attr-contains-a3"],     level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector, matching href attributes ending with specified substring",                             selector: "#attr-contains a[href*=\".org\"]",           expect: ["attr-contains-a1", "attr-contains-a2"],     level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector, matching href attributes containing specified substring",                              selector: "#attr-contains a[href*=\".example.\"]",      expect: ["attr-contains-a1", "attr-contains-a3"],     level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector, matching lang attributes beginning with specified substring, ",                        selector: "#attr-contains [lang*=\"en-\"]",             expect: ["attr-contains-div2", "attr-contains-div6"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector, matching lang attributes ending with specified substring, ",                           selector: "#attr-contains [lang*=\"-CH\"]",             expect: ["attr-contains-div3", "attr-contains-div5"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector, not matching class attribute with empty value",                                        selector: "#attr-contains [class*=\"\"]",               expect: [] /*no matches*/,                            level: 3, testType: TEST_QSA},
+  {name: "Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring", selector: "#attr-contains [class*=' apple']",           expect: ["attr-contains-p1"],                         level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector with single-quoted value, matching class attribute ending with specified substring",    selector: "#attr-contains [class*='orange ']",          expect: ["attr-contains-p1"],                         level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector with single-quoted value, matching class attribute containing specified substring",     selector: "#attr-contains [class*='ple banana ora']",   expect: ["attr-contains-p1"],                         level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring", selector: "#attr-contains [class*=\" apple\"]",         expect: ["attr-contains-p1"],                         level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector with double-quoted value, matching class attribute ending with specified substring",    selector: "#attr-contains [class*=\"orange \"]",        expect: ["attr-contains-p1"],                         level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector with double-quoted value, matching class attribute containing specified substring",     selector: "#attr-contains [class*=\"ple banana ora\"]", expect: ["attr-contains-p1"],                         level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector with unquoted value, matching class attribute beginning with specified substring",      selector: "#attr-contains [class*= apple]",             expect: ["attr-contains-p1"],                         level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector with unquoted value, matching class attribute ending with specified substring",         selector: "#attr-contains [class*=orange ]",            expect: ["attr-contains-p1"],                         level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "Attribute contains selector with unquoted value, matching class attribute containing specified substring",          selector: "#attr-contains [class*= banana ]",           expect: ["attr-contains-p1"],                         level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // Pseudo-classes
+  // - :root                 (Level 3)
+  {name: ":root pseudo-class selector, matching document root element",      selector: ":root", expect: ["html"],          exclude: ["element", "fragment", "detached"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":root pseudo-class selector, not matching document root element",  selector: ":root", expect: [] /*no matches*/, exclude: ["document"],                        level: 3, testType: TEST_QSA},
+
+  // - :nth-child(n)         (Level 3)
+  // XXX write descriptions
+  {name: ":nth-child selector, matching the third child element",                              selector: "#pseudo-nth-table1 :nth-child(3)", expect: ["pseudo-nth-td3", "pseudo-nth-td9", "pseudo-nth-tr3", "pseudo-nth-td15"],                    level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":nth-child selector, matching every third child element",                            selector: "#pseudo-nth li:nth-child(3n)",     expect: ["pseudo-nth-li3", "pseudo-nth-li6", "pseudo-nth-li9", "pseudo-nth-li12"],                    level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":nth-child selector, matching every second child element, starting from the fourth", selector: "#pseudo-nth li:nth-child(2n+4)",   expect: ["pseudo-nth-li4", "pseudo-nth-li6", "pseudo-nth-li8", "pseudo-nth-li10", "pseudo-nth-li12"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":nth-child selector, matching every fourth child element, starting from the third",  selector: "#pseudo-nth-p1 :nth-child(4n-1)",  expect: ["pseudo-nth-em2", "pseudo-nth-span3"],                                                       level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :nth-last-child       (Level 3)
+  {name: ":nth-last-child selector, matching the third last child element",                                           selector: "#pseudo-nth-table1 :nth-last-child(3)", expect: ["pseudo-nth-tr1", "pseudo-nth-td4", "pseudo-nth-td10", "pseudo-nth-td16"],                 level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":nth-last-child selector, matching every third child element from the end",                                 selector: "#pseudo-nth li:nth-last-child(3n)",     expect: ["pseudo-nth-li1", "pseudo-nth-li4", "pseudo-nth-li7", "pseudo-nth-li10"],                  level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":nth-last-child selector, matching every second child element from the end, starting from the fourth last", selector: "#pseudo-nth li:nth-last-child(2n+4)",   expect: ["pseudo-nth-li1", "pseudo-nth-li3", "pseudo-nth-li5", "pseudo-nth-li7", "pseudo-nth-li9"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":nth-last-child selector, matching every fourth element from the end, starting from the third last",        selector: "#pseudo-nth-p1 :nth-last-child(4n-1)",  expect: ["pseudo-nth-span2", "pseudo-nth-span4"],                                                   level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :nth-of-type(n)       (Level 3)
+  {name: ":nth-of-type selector, matching the third em element",                                        selector: "#pseudo-nth-p1 em:nth-of-type(3)",      expect: ["pseudo-nth-em3"],                                                                                 level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":nth-of-type selector, matching every second element of their type",                          selector: "#pseudo-nth-p1 :nth-of-type(2n)",       expect: ["pseudo-nth-em2", "pseudo-nth-span2", "pseudo-nth-span4", "pseudo-nth-strong2", "pseudo-nth-em4"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":nth-of-type selector, matching every second elemetn of their type, starting from the first", selector: "#pseudo-nth-p1 span:nth-of-type(2n-1)", expect: ["pseudo-nth-span1", "pseudo-nth-span3"],                                                           level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :nth-last-of-type(n)  (Level 3)
+  {name: ":nth-last-of-type selector, matching the third last em element", selector: "#pseudo-nth-p1 em:nth-last-of-type(3)",      expect: ["pseudo-nth-em2"],                                                                                 level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":nth-last-of-type selector, matching every second last element of their type", selector: "#pseudo-nth-p1 :nth-last-of-type(2n)",       expect: ["pseudo-nth-span1", "pseudo-nth-em1", "pseudo-nth-strong1", "pseudo-nth-em3", "pseudo-nth-span3"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":nth-last-of-type selector, matching every second last element of their type, starting from the last", selector: "#pseudo-nth-p1 span:nth-last-of-type(2n-1)", expect: ["pseudo-nth-span2", "pseudo-nth-span4"],                                                           level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :first-of-type        (Level 3)
+  {name: ":first-of-type selector, matching the first em element", selector: "#pseudo-nth-p1 em:first-of-type",      expect: ["pseudo-nth-em1"],                                           level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":first-of-type selector, matching the first of every type of element", selector: "#pseudo-nth-p1 :first-of-type",        expect: ["pseudo-nth-span1", "pseudo-nth-em1", "pseudo-nth-strong1"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":first-of-type selector, matching the first td element in each table row", selector: "#pseudo-nth-table1 tr :first-of-type", expect: ["pseudo-nth-td1", "pseudo-nth-td7", "pseudo-nth-td13"],      level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :last-of-type         (Level 3)
+  {name: ":last-of-type selector, matching the last em elemnet", selector: "#pseudo-nth-p1 em:last-of-type",      expect: ["pseudo-nth-em4"],                                           level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":last-of-type selector, matching the last of every type of element", selector: "#pseudo-nth-p1 :last-of-type",        expect: ["pseudo-nth-span4", "pseudo-nth-strong2", "pseudo-nth-em4"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":last-of-type selector, matching the last td element in each table row", selector: "#pseudo-nth-table1 tr :last-of-type", expect: ["pseudo-nth-td6", "pseudo-nth-td12", "pseudo-nth-td18"],     level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :first-child
+  {name: ":first-child pseudo-class selector, matching first child div element",          selector: "#pseudo-first-child div:first-child",                                        expect: ["pseudo-first-child-div1"],                                                          level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: ":first-child pseudo-class selector, doesn't match non-first-child elements",    selector: ".pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child", expect: [] /*no matches*/,                                                                    level: 2, testType: TEST_QSA},
+  {name: ":first-child pseudo-class selector, matching first-child of multiple elements", selector: "#pseudo-first-child span:first-child",                                       expect: ["pseudo-first-child-span1", "pseudo-first-child-span3", "pseudo-first-child-span5"], level: 2, testType: TEST_QSA | TEST_MATCH},
+
+  // - :last-child           (Level 3)
+  {name: ":last-child pseudo-class selector, matching last child div element",           selector: "#pseudo-last-child div:last-child",                                       expect: ["pseudo-last-child-div3"],                                                        level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":last-child pseudo-class selector, doesn't match non-last-child elements",     selector: ".pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child", expect: [] /*no matches*/,                                                                 level: 3, testType: TEST_QSA},
+  {name: ":last-child pseudo-class selector, matching first-child of multiple elements", selector: "#pseudo-last-child span:last-child",                                      expect: ["pseudo-last-child-span2", "pseudo-last-child-span4", "pseudo-last-child-span6"], level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :only-child           (Level 3)
+  {name: ":pseudo-only-child pseudo-class selector, matching all only-child elements", selector: "#pseudo-only :only-child", expect: ["pseudo-only-span1"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":pseudo-only-child pseudo-class selector, matching only-child em elements",  selector: "#pseudo-only em:only-child", expect: [] /*no matches*/,   level: 3, testType: TEST_QSA},
+
+  // - :only-of-type         (Level 3)
+  {name: ":pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type", selector: "#pseudo-only :only-of-type", expect: ["pseudo-only-span1", "pseudo-only-em1"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type",  selector: "#pseudo-only em:only-of-type", expect: ["pseudo-only-em1"],                    level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :empty                (Level 3)
+  {name: ":empty pseudo-class selector, matching empty p elements",   selector: "#pseudo-empty p:empty", expect: ["pseudo-empty-p1", "pseudo-empty-p2"],                       level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":empty pseudo-class selector, matching all empty elements", selector: "#pseudo-empty :empty",  expect: ["pseudo-empty-p1", "pseudo-empty-p2", "pseudo-empty-span1"], level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :link and :visited
+  // Implementations may treat all visited links as unvisited, so these cannot be tested separately.
+  // The only guarantee is that ":link,:visited" matches the set of all visited and unvisited links and that they are individually mutually exclusive sets.
+  {name: ":link and :visited pseudo-class selectors, matching a and area elements with href attributes",        selector: "#pseudo-link :link, #pseudo-link :visited", expect: ["pseudo-link-a1", "pseudo-link-a2", "pseudo-link-area1"],                                level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: ":link and :visited pseudo-class selectors, matching no elements",                                     selector: "#head :link, #head :visited",               expect: [] /*no matches*/,                          exclude: ["element", "fragment", "detached"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: ":link and :visited pseudo-class selectors, not matching link elements with href attributes",          selector: "#head :link, #head :visited",               expect: [] /*no matches*/,                          exclude: ["document"],                        level: 1, testType: TEST_QSA},
+  {name: ":link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing", selector: ":link:visited",                             expect: [] /*no matches*/,                          exclude: ["document"],                        level: 1, testType: TEST_QSA},
+
+  // - :target               (Level 3)
+  {name: ":target pseudo-class selector, matching the element referenced by the URL fragment identifier", selector: ":target", expect: [] /*no matches*/, exclude: ["document", "element"],  level: 3, testType: TEST_QSA},
+  {name: ":target pseudo-class selector, matching the element referenced by the URL fragment identifier", selector: ":target", expect: ["target"],        exclude: ["fragment", "detached"], level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :lang()
+  {name: ":lang pseudo-class selector, matching inherited language",                     selector: "#pseudo-lang-div1:lang(en)",    expect: ["pseudo-lang-div1"], exclude: ["detached", "fragment"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: ":lang pseudo-class selector, not matching element with no inherited language", selector: "#pseudo-lang-div1:lang(en)",    expect: [] /*no matches*/,    exclude: ["document", "element"],  level: 2, testType: TEST_QSA},
+  {name: ":lang pseudo-class selector, matching specified language with exact value",    selector: "#pseudo-lang-div2:lang(fr)",    expect: ["pseudo-lang-div2"],                                    level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: ":lang pseudo-class selector, matching specified language with partial value",  selector: "#pseudo-lang-div3:lang(en)",    expect: ["pseudo-lang-div3"],                                    level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: ":lang pseudo-class selector, not matching incorrect language",                 selector: "#pseudo-lang-div4:lang(es-AR)", expect: [] /*no matches*/,                                       level: 2, testType: TEST_QSA},
+
+  // - :enabled              (Level 3)
+  {name: ":enabled pseudo-class selector, matching all enabled form controls",  selector: "#pseudo-ui :enabled",  expect: ["pseudo-ui-input1", "pseudo-ui-input2", "pseudo-ui-input3", "pseudo-ui-input4", "pseudo-ui-input5", "pseudo-ui-input6",
+                                                                                                                           "pseudo-ui-input7", "pseudo-ui-input8", "pseudo-ui-input9", "pseudo-ui-textarea1", "pseudo-ui-button1"],    level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":enabled pseudo-class selector, not matching link elements",  selector: "#pseudo-link :enabled",  expect: [] /*no matches*/, unexpected: ["pseudo-link-a1","pseudo-link-a2","pseudo-link-a3","pseudo-link-map1","pseudo-link-area1","pseudo-link-area2"],   level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :disabled             (Level 3)
+  {name: ":disabled pseudo-class selector, matching all disabled form controls", selector: "#pseudo-ui :disabled", expect: ["pseudo-ui-input10", "pseudo-ui-input11", "pseudo-ui-input12", "pseudo-ui-input13", "pseudo-ui-input14", "pseudo-ui-input15",
+                                                                                                                           "pseudo-ui-input16", "pseudo-ui-input17", "pseudo-ui-input18", "pseudo-ui-textarea2", "pseudo-ui-button2"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":disabled pseudo-class selector, not matching link elements", selector: "#pseudo-link :disabled", expect: [] /*no matches*/, unexpected: ["pseudo-link-a1","pseudo-link-a2","pseudo-link-a3","pseudo-link-map1","pseudo-link-area1","pseudo-link-area2"], level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :checked              (Level 3)
+  {name: ":checked pseudo-class selector, matching checked radio buttons and checkboxes", selector: "#pseudo-ui :checked", expect: ["pseudo-ui-input4", "pseudo-ui-input6", "pseudo-ui-input13", "pseudo-ui-input15"],  level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :not(s)               (Level 3)
+  {name: ":not pseudo-class selector, matching ", selector: "#not>:not(div)",   expect: ["not-p1", "not-p2", "not-p3"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":not pseudo-class selector, matching ", selector: "#not * :not(:first-child)",   expect: ["not-em1", "not-em2", "not-em3"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: ":not pseudo-class selector, matching nothing", selector: ":not(*)",   expect: [] /* no matches */, level: 3, testType: TEST_QSA},
+  {name: ":not pseudo-class selector, matching nothing", selector: ":not(*|*)", expect: [] /* no matches */, level: 3, testType: TEST_QSA},
+  {name: ":not pseudo-class selector argument surrounded by spaces, matching ", selector: "#not>:not( div )",   expect: ["not-p1", "not-p2", "not-p3"], level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // Pseudo-elements
+  // - ::first-line
+  {name: ":first-line pseudo-element (one-colon syntax) selector, not matching any elements",    selector: "#pseudo-element:first-line",    expect: [] /*no matches*/, level: 2, testType: TEST_QSA},
+  {name: "::first-line pseudo-element (two-colon syntax) selector, not matching any elements",   selector: "#pseudo-element::first-line",   expect: [] /*no matches*/, level: 3, testType: TEST_QSA},
+
+  // - ::first-letter
+  {name: ":first-letter pseudo-element (one-colon syntax) selector, not matching any elements",  selector: "#pseudo-element:first-letter",  expect: [] /*no matches*/, level: 2, testType: TEST_QSA},
+  {name: "::first-letter pseudo-element (two-colon syntax) selector, not matching any elements", selector: "#pseudo-element::first-letter", expect: [] /*no matches*/, level: 3, testType: TEST_QSA},
+
+  // - ::before
+  {name: ":before pseudo-element (one-colon syntax) selector, not matching any elements",        selector: "#pseudo-element:before",        expect: [] /*no matches*/, level: 2, testType: TEST_QSA},
+  {name: "::before pseudo-element (two-colon syntax) selector, not matching any elements",       selector: "#pseudo-element::before",       expect: [] /*no matches*/, level: 3, testType: TEST_QSA},
+
+  // - ::after
+  {name: ":after pseudo-element (one-colon syntax) selector, not matching any elements",         selector: "#pseudo-element:after",         expect: [] /*no matches*/, level: 2, testType: TEST_QSA},
+  {name: "::after pseudo-element (two-colon syntax) selector, not matching any elements",        selector: "#pseudo-element::after",        expect: [] /*no matches*/, level: 3, testType: TEST_QSA},
+
+  // Class Selectors
+  {name: "Class selector, matching element with specified class",                                           selector: ".class-p",                expect: ["class-p1","class-p2", "class-p3"],                                              level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Class selector, chained, matching only elements with all specified classes",                      selector: "#class .apple.orange.banana",    expect: ["class-div1", "class-div2", "class-p4", "class-div3", "class-p6", "class-div4"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Class Selector, chained, with type selector",                                                     selector: "div.apple.banana.orange", expect: ["class-div1", "class-div2", "class-div3", "class-div4"],                         level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Class selector, matching element with class value using non-ASCII characters (1)",                selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci",             expect: ["class-span1"],               level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Class selector, matching multiple elements with class value using non-ASCII characters",          selector: ".\u53F0\u5317",                     expect: ["class-span1","class-span2"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Class selector, chained, matching element with multiple class values using non-ASCII characters (1)", selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci.\u53F0\u5317",          expect: ["class-span1"],               level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Class selector, matching element with class with escaped character",                              selector: ".foo\\:bar",              expect: ["class-span3"],               level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Class selector, matching element with class with escaped character",                              selector: ".test\\.foo\\[5\\]bar",   expect: ["class-span4"],               level: 1, testType: TEST_QSA | TEST_MATCH},
+
+  // ID Selectors
+  {name: "ID selector, matching element with specified id",           selector: "#id #id-div1",              expect: ["id-div1"],            level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "ID selector, chained, matching element with specified id",  selector: "#id-div1, #id-div1",        expect: ["id-div1"],            level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "ID selector, chained, matching element with specified id",  selector: "#id-div1, #id-div2",        expect: ["id-div1", "id-div2"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "ID Selector, chained, with type selector",                  selector: "div#id-div1, div#id-div2",  expect: ["id-div1", "id-div2"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "ID selector, not matching non-existent descendant",         selector: "#id #none",                 expect: [] /*no matches*/,      level: 1, testType: TEST_QSA},
+  {name: "ID selector, not matching non-existent ancestor",           selector: "#none #id-div1",            expect: [] /*no matches*/,      level: 1, testType: TEST_QSA},
+  {name: "ID selector, matching multiple elements with duplicate id", selector: "#id-li-duplicate",          expect: ["id-li-duplicate", "id-li-duplicate", "id-li-duplicate", "id-li-duplicate"], level: 1, testType: TEST_QSA | TEST_MATCH},
+
+  {name: "ID selector, matching id value using non-ASCII characters (1)",    selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci",           expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci"],       level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "ID selector, matching id value using non-ASCII characters (2)",    selector: "#\u53F0\u5317",                   expect: ["\u53F0\u5317"],               level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "ID selector, matching id values using non-ASCII characters (1)", selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci, #\u53F0\u5317",      expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci", "\u53F0\u5317"], level: 1, testType: TEST_QSA | TEST_MATCH},
+
+  // XXX runMatchesTest() in level2-lib.js can't handle this because obtaining the expected nodes requires escaping characters when generating the selector from 'expect' values
+  {name: "ID selector, matching element with id with escaped character", selector: "#\\#foo\\:bar",         expect: ["#foo:bar"],         level: 1, testType: TEST_QSA},
+  {name: "ID selector, matching element with id with escaped character", selector: "#test\\.foo\\[5\\]bar", expect: ["test.foo[5]bar"],   level: 1, testType: TEST_QSA},
+
+  // Namespaces
+  // XXX runMatchesTest() in level2-lib.js can't handle these because non-HTML elements don't have a recognised id
+  {name: "Namespace selector, matching element with any namespace",        selector: "#any-namespace *|div", expect: ["any-namespace-div1", "any-namespace-div2", "any-namespace-div3", "any-namespace-div4"], level: 3, testType: TEST_QSA},
+  {name: "Namespace selector, matching div elements in no namespace only", selector: "#no-namespace |div",   expect: ["no-namespace-div3"], level: 3, testType: TEST_QSA},
+  {name: "Namespace selector, matching any elements in no namespace only", selector: "#no-namespace |*",     expect: ["no-namespace-div3"], level: 3, testType: TEST_QSA},
+
+  // Combinators
+  // - Descendant combinator ' '
+  {name: "Descendant combinator, matching element that is a descendant of an element with id",                 selector: "#descendant div",                   expect: ["descendant-div1", "descendant-div2", "descendant-div3", "descendant-div4"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Descendant combinator, matching element with id that is a descendant of an element",                 selector: "body #descendant-div1",             expect: ["descendant-div1"], exclude: ["detached", "fragment"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Descendant combinator, matching element with id that is a descendant of an element",                 selector: "div #descendant-div1",              expect: ["descendant-div1"],                                    level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Descendant combinator, matching element with id that is a descendant of an element with id",         selector: "#descendant #descendant-div2",      expect: ["descendant-div2"],                                    level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Descendant combinator, matching element with class that is a descendant of an element with id",      selector: "#descendant .descendant-div2",      expect: ["descendant-div2"],                                    level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Descendant combinator, matching element with class that is a descendant of an element with class",   selector: ".descendant-div1 .descendant-div3", expect: ["descendant-div3"],                                    level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Descendant combinator, not matching element with id that is not a descendant of an element with id", selector: "#descendant-div1 #descendant-div4", expect: [] /*no matches*/,                                      level: 1, testType: TEST_QSA},
+  {name: "Descendant combinator, whitespace characters",                                                       selector: "#descendant\t\r\n#descendant-div2", expect: ["descendant-div2"],                                    level: 1, testType: TEST_QSA | TEST_MATCH},
+
+  /* The future of this combinator is uncertain, see
+   * https://github.com/w3c/csswg-drafts/issues/641
+   * These tests are commented out until a final decision is made on whether to
+   * keep the feature in the spec.
+   */
+
+  // // - Descendant combinator '>>'
+  // {name: "Descendant combinator '>>', matching element that is a descendant of an element with id",                 selector: "#descendant>>div",                   expect: ["descendant-div1", "descendant-div2", "descendant-div3", "descendant-div4"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element",                 selector: "body>>#descendant-div1",             expect: ["descendant-div1"], exclude: ["detached", "fragment"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element",                 selector: "div>>#descendant-div1",              expect: ["descendant-div1"],                                    level: 1, testType: TEST_QSA | TEST_MATCH},
+  // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element with id",         selector: "#descendant>>#descendant-div2",      expect: ["descendant-div2"],                                    level: 1, testType: TEST_QSA | TEST_MATCH},
+  // {name: "Descendant combinator '>>', matching element with class that is a descendant of an element with id",      selector: "#descendant>>.descendant-div2",      expect: ["descendant-div2"],                                    level: 1, testType: TEST_QSA | TEST_MATCH},
+  // {name: "Descendant combinator '>>', matching element with class that is a descendant of an element with class",   selector: ".descendant-div1>>.descendant-div3", expect: ["descendant-div3"],                                    level: 1, testType: TEST_QSA | TEST_MATCH},
+  // {name: "Descendant combinator '>>', not matching element with id that is not a descendant of an element with id", selector: "#descendant-div1>>#descendant-div4", expect: [] /*no matches*/,                                      level: 1, testType: TEST_QSA},
+
+  // - Child combinator '>'
+  {name: "Child combinator, matching element that is a child of an element with id",                       selector: "#child>div",                          expect: ["child-div1", "child-div4"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Child combinator, matching element with id that is a child of an element",                       selector: "div>#child-div1",                     expect: ["child-div1"],               level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Child combinator, matching element with id that is a child of an element with id",               selector: "#child>#child-div1",                  expect: ["child-div1"],               level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Child combinator, matching element with id that is a child of an element with class",            selector: "#child-div1>.child-div2",             expect: ["child-div2"],               level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Child combinator, matching element with class that is a child of an element with class",         selector: ".child-div1>.child-div2",             expect: ["child-div2"],               level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Child combinator, not matching element with id that is not a child of an element with id",       selector: "#child>#child-div3",                  expect: [] /*no matches*/,            level: 2, testType: TEST_QSA},
+  {name: "Child combinator, not matching element with id that is not a child of an element with class",    selector: "#child-div1>.child-div3",             expect: [] /*no matches*/,            level: 2, testType: TEST_QSA},
+  {name: "Child combinator, not matching element with class that is not a child of an element with class", selector: ".child-div1>.child-div3",             expect: [] /*no matches*/,            level: 2, testType: TEST_QSA},
+  {name: "Child combinator, surrounded by whitespace",                                                     selector: "#child-div1\t\r\n>\t\r\n#child-div2", expect: ["child-div2"],               level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Child combinator, whitespace after",                                                             selector: "#child-div1>\t\r\n#child-div2",       expect: ["child-div2"],               level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Child combinator, whitespace before",                                                            selector: "#child-div1\t\r\n>#child-div2",       expect: ["child-div2"],               level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Child combinator, no whitespace",                                                                selector: "#child-div1>#child-div2",             expect: ["child-div2"],               level: 2, testType: TEST_QSA | TEST_MATCH},
+
+  // - Adjacent sibling combinator '+'
+  {name: "Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id",                 selector: "#adjacent-div2+div",                                         expect: ["adjacent-div4"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element",                 selector: "div+#adjacent-div4",                                         expect: ["adjacent-div4"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id",         selector: "#adjacent-div2+#adjacent-div4",                              expect: ["adjacent-div4"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id",      selector: "#adjacent-div2+.adjacent-div4",                              expect: ["adjacent-div4"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class",   selector: ".adjacent-div2+.adjacent-div4",                              expect: ["adjacent-div4"], level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element",                    selector: "#adjacent div+p",                                            expect: ["adjacent-p2"],   level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id", selector: "#adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1", expect: [] /*no matches*/, level: 2, testType: TEST_QSA},
+  {name: "Adjacent sibling combinator, surrounded by whitespace",                                                           selector: "#adjacent-p2\t\r\n+\t\r\n#adjacent-p3",                      expect: ["adjacent-p3"],   level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Adjacent sibling combinator, whitespace after",                                                                   selector: "#adjacent-p2+\t\r\n#adjacent-p3",                            expect: ["adjacent-p3"],   level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Adjacent sibling combinator, whitespace before",                                                                  selector: "#adjacent-p2\t\r\n+#adjacent-p3",                            expect: ["adjacent-p3"],   level: 2, testType: TEST_QSA | TEST_MATCH},
+  {name: "Adjacent sibling combinator, no whitespace",                                                                      selector: "#adjacent-p2+#adjacent-p3",                                  expect: ["adjacent-p3"],   level: 2, testType: TEST_QSA | TEST_MATCH},
+
+  // - General sibling combinator ~ (Level 3)
+  {name: "General sibling combinator, matching element that is a sibling of an element with id",                    selector: "#sibling-div2~div",                                        expect: ["sibling-div4", "sibling-div6"], level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "General sibling combinator, matching element with id that is a sibling of an element",                    selector: "div~#sibling-div4",                                        expect: ["sibling-div4"],                 level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "General sibling combinator, matching element with id that is a sibling of an element with id",            selector: "#sibling-div2~#sibling-div4",                              expect: ["sibling-div4"],                 level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "General sibling combinator, matching element with class that is a sibling of an element with id",         selector: "#sibling-div2~.sibling-div",                               expect: ["sibling-div4", "sibling-div6"],                 level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "General sibling combinator, matching p element that is a sibling of a div element",                       selector: "#sibling div~p",                                           expect: ["sibling-p2", "sibling-p3"],                   level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "General sibling combinator, not matching element with id that is not a sibling after a p element",        selector: "#sibling>p~div",                                           expect: [] /*no matches*/,                level: 3, testType: TEST_QSA},
+  {name: "General sibling combinator, not matching element with id that is not a sibling after an element with id", selector: "#sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1", expect: [] /*no matches*/,                level: 3, testType: TEST_QSA},
+  {name: "General sibling combinator, surrounded by whitespace",                                                    selector: "#sibling-p2\t\r\n~\t\r\n#sibling-p3",                      expect: ["sibling-p3"],                   level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "General sibling combinator, whitespace after",                                                            selector: "#sibling-p2~\t\r\n#sibling-p3",                            expect: ["sibling-p3"],                   level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "General sibling combinator, whitespace before",                                                           selector: "#sibling-p2\t\r\n~#sibling-p3",                            expect: ["sibling-p3"],                   level: 3, testType: TEST_QSA | TEST_MATCH},
+  {name: "General sibling combinator, no whitespace",                                                               selector: "#sibling-p2~#sibling-p3",                                  expect: ["sibling-p3"],                   level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // Group of selectors (comma)
+  {name: "Syntax, group of selectors separator, surrounded by whitespace", selector: "#group em\t\r \n,\t\r \n#group strong", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Syntax, group of selectors separator, whitespace after",         selector: "#group em,\t\r\n#group strong",         expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Syntax, group of selectors separator, whitespace before",        selector: "#group em\t\r\n,#group strong",         expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_QSA | TEST_MATCH},
+  {name: "Syntax, group of selectors separator, no whitespace",            selector: "#group em,#group strong",               expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_QSA | TEST_MATCH},
+
+  // ::slotted (shouldn't match anything, but is a valid selector)
+  {name: "Slotted selector", selector: "::slotted(foo)", expect: [], level: 3, testType: TEST_QSA},
+  {name: "Slotted selector (no matching closing paren)", selector: "::slotted(foo", expect: [], level: 3, testType: TEST_QSA},
+];
+
+
+/*
+ * These selectors are intended to be used with the find(), findAll() and matches() methods.  Expected results
+ * should be determined under the assumption that :scope will be prepended to the selector where appropriate,
+ * in accordance with the specification.
+ *
+ * All of these should be valid relative selectors, expected to match zero or more elements in the document.
+ * None should throw any errors.
+ *
+ *   name:      A descriptive name of the selector being tested
+ *
+ *   selector:  The selector to test
+ *
+ *   ctx:       A selector to obtain the context object to use for tests invoking context.find(),
+ *              and to use as a single reference node for tests invoking document.find().
+ *              Note: context = root.querySelector(ctx);
+ *
+ *   ref:       A selector to obtain the reference nodes to be used for the selector.
+ *              Note: If root is the document or an in-document element:
+ *                      refNodes = document.querySelectorAll(ref);
+ *                    Otherwise, if root is a fragment or detached element:
+ *                      refNodes = root.querySelectorAll(ref);
+ *
+ *   expect:    A list of IDs of the elements expected to be matched. List must be given in tree order.
+ *
+ *   unexpected: A list of IDs of some elements that are not expected to match the given selector.
+ *               This is used to verify that unexpected.matches(selector, refNode) does not match.
+ *
+ *   exclude:   An array of contexts to exclude from testing. The valid values are:
+ *              ["document", "element", "fragment", "detached", "html", "xhtml"]
+ *              The "html" and "xhtml" values represent the type of document being queried. These are useful
+ *              for tests that are affected by differences between HTML and XML, such as case sensitivity.
+ *
+ *   level:     An integer indicating the CSS or Selectors level in which the selector being tested was introduced.
+ *
+ *   testType:  A bit-mapped flag indicating the type of test.
+ *
+ * The test function for these tests accepts a specified root node, on which the methods will be invoked during the tests.
+ *
+ * Based on whether either 'context' or 'refNodes', or both, are specified the tests will execute the following methods:
+ *
+ * Where testType is TEST_FIND:
+ *
+ * context.findAll(selector, refNodes)
+ * context.findAll(selector)        // Only if refNodes is not specified
+ * root.findAll(selector, context)  // Only if refNodes is not specified
+ * root.findAll(selector, refNodes) // Only if context is not specified
+ * root.findAll(selector)           // Only if neither context nor refNodes is specified
+ *
+ * Where testType is TEST_QSA
+ *
+ * context.querySelectorAll(selector)
+ * root.querySelectorAll(selector)  // Only if neither context nor refNodes is specified
+ *
+ * Equivalent tests will be run for .find() as well.
+ * Note: Do not specify a testType of TEST_QSA where either implied :scope or explicit refNodes
+ * are required.
+ *
+ * Where testType is TEST_MATCH:
+ * For each expected result given, within the specified root:
+ *
+ * expect.matches(selector, context)    // Only where refNodes is not specified
+ * expect.matches(selector, refNodes)
+ * expect.matches(selector)             // Only if neither context nor refNodes is specified
+ *
+ * The tests involving refNodes for both find(), findAll() and matches() will each be run by passing the
+ * collection as a NodeList, an Array and, if there is only a single element, an Element node.
+ *
+ * Note: Interactive pseudo-classes (:active :hover and :focus) have not been tested in this test suite.
+ */
+
+var scopedSelectors = [
+  //{name: "", selector: "", ctx: "", ref: "", expect: [], level: 1, testType: TEST_FIND | TEST_MATCH},
+
+  // Attribute Selectors
+  // - presence                  [att]
+  {name: "Attribute presence selector, matching align attribute with value",                    selector: ".attr-presence-div1[align]",                             ctx: "#attr-presence", expect: ["attr-presence-div1"],                                             level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute presence selector, matching align attribute with empty value",              selector: ".attr-presence-div2[align]",                             ctx: "#attr-presence", expect: ["attr-presence-div2"],                                             level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute presence selector, matching title attribute, case insensitivity",           selector: "[TiTlE]",                                                ctx: "#attr-presence", expect: ["attr-presence-a1", "attr-presence-span1"], exclude: ["xhtml"],    level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute presence selector, not matching title attribute, case sensitivity",         selector: "[TiTlE]",                                                ctx: "#attr-presence", expect: [],                                          exclude: ["html"],     level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute presence selector, matching custom data-* attribute",                       selector: "[data-attr-presence]",                                   ctx: "#attr-presence", expect: ["attr-presence-pre1", "attr-presence-blockquote1"],                level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute presence selector, not matching attribute with similar name",               selector: ".attr-presence-div3[align], .attr-presence-div4[align]", ctx: "#attr-presence", expect: [] /*no matches*/,                                                  level: 2, testType: TEST_FIND},
+  {name: "Attribute presence selector, matching attribute with non-ASCII characters",           selector: "ul[data-中文]",                                            ctx: "#attr-presence", expect: ["attr-presence-ul1"],                                              level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute presence selector, not matching default option without selected attribute", selector: "#attr-presence-select1 option[selected]",                ctx: "#attr-presence", expect: [] /* no matches */,                                                level: 2, testType: TEST_FIND},
+  {name: "Attribute presence selector, matching option with selected attribute",                selector: "#attr-presence-select2 option[selected]",                ctx: "#attr-presence", expect: ["attr-presence-select2-option4"],                                  level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute presence selector, matching multiple options with selected attributes",     selector: "#attr-presence-select3 option[selected]",                ctx: "#attr-presence", expect: ["attr-presence-select3-option2", "attr-presence-select3-option3"], level: 2, testType: TEST_FIND | TEST_MATCH},
+
+  // - value                     [att=val]
+  {name: "Attribute value selector, matching align attribute with value",                                    selector: "[align=\"center\"]",                                     ctx: "#attr-value", expect: ["attr-value-div1"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute value selector, matching align attribute with empty value",                              selector: "[align=\"\"]",                                           ctx: "#attr-value", expect: ["attr-value-div2"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute value selector, not matching align attribute with partial value",                        selector: "[align=\"c\"]",                                          ctx: "#attr-value", expect: [] /*no matches*/,   level: 2, testType: TEST_FIND},
+  {name: "Attribute value selector, not matching align attribute with incorrect value",                      selector: "[align=\"centera\"]",                                    ctx: "#attr-value", expect: [] /*no matches*/,   level: 2, testType: TEST_FIND},
+  {name: "Attribute value selector, matching custom data-* attribute with unicode escaped value",            selector: "[data-attr-value=\"\\e9\"]",                             ctx: "#attr-value", expect: ["attr-value-div3"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute value selector, matching custom data-* attribute with escaped character",                selector: "[data-attr-value\_foo=\"\\e9\"]",                        ctx: "#attr-value", expect: ["attr-value-div4"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute value selector with single-quoted value, matching multiple inputs with type attributes", selector: "input[type='hidden'],#attr-value input[type='radio']",   ctx: "#attr-value", expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute value selector with double-quoted value, matching multiple inputs with type attributes", selector: "input[type=\"hidden\"],#attr-value input[type='radio']", ctx: "#attr-value", expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute value selector with unquoted value, matching multiple inputs with type attributes",      selector: "input[type=hidden],#attr-value input[type=radio]",       ctx: "#attr-value", expect: ["attr-value-input3", "attr-value-input4", "attr-value-input6", "attr-value-input8", "attr-value-input9"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute value selector, matching attribute with value using non-ASCII characters",               selector: "[data-attr-value=中文]",                                   ctx: "#attr-value", expect: ["attr-value-div5"], level: 2, testType: TEST_FIND | TEST_MATCH},
+
+  // - whitespace-separated list [att~=val]
+  {name: "Attribute whitespace-separated list selector, matching class attribute with value",                                  selector: "[class~=\"div1\"]",                                        ctx: "#attr-whitespace", expect: ["attr-whitespace-div1"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector, not matching class attribute with empty value",                        selector: "[class~=\"\"]",                                            ctx: "#attr-whitespace", expect: [] /*no matches*/ ,       level: 2, testType: TEST_FIND},
+  {name: "Attribute whitespace-separated list selector, not matching class attribute with partial value",                      selector: "[data-attr-whitespace~=\"div\"]",                                           ctx: "#attr-whitespace", expect: [] /*no matches*/ ,       level: 2, testType: TEST_FIND},
+  {name: "Attribute whitespace-separated list selector, matching custom data-* attribute with unicode escaped value",          selector: "[data-attr-whitespace~=\"\\0000e9\"]",                                      ctx: "#attr-whitespace", expect: ["attr-whitespace-div4"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector, matching custom data-* attribute with escaped character",              selector: "[data-attr-whitespace\_foo~=\"\\e9\"]",                                     ctx: "#attr-whitespace", expect: ["attr-whitespace-div5"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector with single-quoted value, matching multiple links with rel attributes", selector: "a[rel~='bookmark'],  #attr-whitespace a[rel~='nofollow']", ctx: "#attr-whitespace", expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector with double-quoted value, matching multiple links with rel attributes", selector: "a[rel~=\"bookmark\"],#attr-whitespace a[rel~='nofollow']", ctx: "#attr-whitespace", expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector with unquoted value, matching multiple links with rel attributes",      selector: "a[rel~=bookmark],    #attr-whitespace a[rel~=nofollow]",   ctx: "#attr-whitespace", expect: ["attr-whitespace-a1", "attr-whitespace-a2", "attr-whitespace-a3", "attr-whitespace-a5", "attr-whitespace-a7"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute whitespace-separated list selector with double-quoted value, not matching value with space",               selector: "a[rel~=\"book mark\"]",                                    ctx: "#attr-whitespace", expect: [] /* no matches */,      level: 2, testType: TEST_FIND},
+  {name: "Attribute whitespace-separated list selector, matching title attribute with value using non-ASCII characters",       selector: "[title~=中文]",                                              ctx: "#attr-whitespace", expect: ["attr-whitespace-p1"],   level: 2, testType: TEST_FIND | TEST_MATCH},
+
+  // - hyphen-separated list     [att|=val]
+  {name: "Attribute hyphen-separated list selector, not matching unspecified lang attribute",    selector: "#attr-hyphen-div1[lang|=\"en\"]",    ctx: "#attr-hyphen", expect: [] /*no matches*/,    level: 2, testType: TEST_FIND},
+  {name: "Attribute hyphen-separated list selector, matching lang attribute with exact value",   selector: "#attr-hyphen-div2[lang|=\"fr\"]",    ctx: "#attr-hyphen", expect: ["attr-hyphen-div2"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute hyphen-separated list selector, matching lang attribute with partial value", selector: "#attr-hyphen-div3[lang|=\"en\"]",    ctx: "#attr-hyphen", expect: ["attr-hyphen-div3"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute hyphen-separated list selector, not matching incorrect value",               selector: "#attr-hyphen-div4[lang|=\"es-AR\"]", ctx: "#attr-hyphen", expect: [] /*no matches*/,    level: 2, testType: TEST_FIND},
+
+  // - substring begins-with     [att^=val] (Level 3)
+  {name: "Attribute begins with selector, matching href attributes beginning with specified substring",                             selector: "a[href^=\"http://www\"]", ctx: "#attr-begins", expect: ["attr-begins-a1", "attr-begins-a3"],     level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute begins with selector, matching lang attributes beginning with specified substring, ",                           selector: "[lang^=\"en-\"]",         ctx: "#attr-begins", expect: ["attr-begins-div2", "attr-begins-div4"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute begins with selector, not matching class attribute with empty value",                                           selector: "[class^=\"\"]",          ctx: "#attr-begins", expect: [] /*no matches*/,                        level: 3, testType: TEST_FIND},
+  {name: "Attribute begins with selector, not matching class attribute not beginning with specified substring",                     selector: "[class^=apple]",          ctx: "#attr-begins", expect: [] /*no matches*/,                        level: 3, testType: TEST_FIND},
+  {name: "Attribute begins with selector with single-quoted value, matching class attribute beginning with specified substring",    selector: "[class^=' apple']",       ctx: "#attr-begins", expect: ["attr-begins-p1"],                       level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute begins with selector with double-quoted value, matching class attribute beginning with specified substring",    selector: "[class^=\" apple\"]",     ctx: "#attr-begins", expect: ["attr-begins-p1"],                       level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute begins with selector with unquoted value, not matching class attribute not beginning with specified substring", selector: "[class^= apple]",         ctx: "#attr-begins", expect: [] /*no matches*/,                        level: 3, testType: TEST_FIND},
+
+  // - substring ends-with       [att$=val] (Level 3)
+  {name: "Attribute ends with selector, matching href attributes ending with specified substring",                             selector: "a[href$=\".org\"]",   ctx: "#attr-ends", expect: ["attr-ends-a1", "attr-ends-a3"],     level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute ends with selector, matching lang attributes ending with specified substring, ",                           selector: "[lang$=\"-CH\"]",     ctx: "#attr-ends", expect: ["attr-ends-div2", "attr-ends-div4"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute ends with selector, not matching class attribute with empty value",                                        selector: "[class$=\"\"]",       ctx: "#attr-ends", expect: [] /*no matches*/,                    level: 3, testType: TEST_FIND},
+  {name: "Attribute ends with selector, not matching class attribute not ending with specified substring",                     selector: "[class$=apple]",      ctx: "#attr-ends", expect: [] /*no matches*/,                    level: 3, testType: TEST_FIND},
+  {name: "Attribute ends with selector with single-quoted value, matching class attribute ending with specified substring",    selector: "[class$='apple ']",   ctx: "#attr-ends", expect: ["attr-ends-p1"],                     level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute ends with selector with double-quoted value, matching class attribute ending with specified substring",    selector: "[class$=\"apple \"]", ctx: "#attr-ends", expect: ["attr-ends-p1"],                     level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute ends with selector with unquoted value, not matching class attribute not ending with specified substring", selector: "[class$=apple ]",     ctx: "#attr-ends", expect: [] /*no matches*/,                    level: 3, testType: TEST_FIND},
+
+  // - substring contains        [att*=val] (Level 3)
+  {name: "Attribute contains selector, matching href attributes beginning with specified substring",                          selector: "a[href*=\"http://www\"]",     ctx: "#attr-contains", expect: ["attr-contains-a1", "attr-contains-a3"],     level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector, matching href attributes ending with specified substring",                             selector: "a[href*=\".org\"]",           ctx: "#attr-contains", expect: ["attr-contains-a1", "attr-contains-a2"],     level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector, matching href attributes containing specified substring",                              selector: "a[href*=\".example.\"]",      ctx: "#attr-contains", expect: ["attr-contains-a1", "attr-contains-a3"],     level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector, matching lang attributes beginning with specified substring, ",                        selector: "[lang*=\"en-\"]",             ctx: "#attr-contains", expect: ["attr-contains-div2", "attr-contains-div6"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector, matching lang attributes ending with specified substring, ",                           selector: "[lang*=\"-CH\"]",             ctx: "#attr-contains", expect: ["attr-contains-div3", "attr-contains-div5"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector, not matching class attribute with empty value",                                        selector: "[class*=\"\"]",               ctx: "#attr-contains", expect: [] /*no matches*/,                            level: 3, testType: TEST_FIND},
+  {name: "Attribute contains selector with single-quoted value, matching class attribute beginning with specified substring", selector: "[class*=' apple']",           ctx: "#attr-contains", expect: ["attr-contains-p1"],                         level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector with single-quoted value, matching class attribute ending with specified substring",    selector: "[class*='orange ']",          ctx: "#attr-contains", expect: ["attr-contains-p1"],                         level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector with single-quoted value, matching class attribute containing specified substring",     selector: "[class*='ple banana ora']",   ctx: "#attr-contains", expect: ["attr-contains-p1"],                         level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector with double-quoted value, matching class attribute beginning with specified substring", selector: "[class*=\" apple\"]",         ctx: "#attr-contains", expect: ["attr-contains-p1"],                         level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector with double-quoted value, matching class attribute ending with specified substring",    selector: "[class*=\"orange \"]",        ctx: "#attr-contains", expect: ["attr-contains-p1"],                         level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector with double-quoted value, matching class attribute containing specified substring",     selector: "[class*=\"ple banana ora\"]", ctx: "#attr-contains", expect: ["attr-contains-p1"],                         level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector with unquoted value, matching class attribute beginning with specified substring",      selector: "[class*= apple]",             ctx: "#attr-contains", expect: ["attr-contains-p1"],                         level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector with unquoted value, matching class attribute ending with specified substring",         selector: "[class*=orange ]",            ctx: "#attr-contains", expect: ["attr-contains-p1"],                         level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "Attribute contains selector with unquoted value, matching class attribute containing specified substring",          selector: "[class*= banana ]",           ctx: "#attr-contains", expect: ["attr-contains-p1"],                         level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // Pseudo-classes
+  // - :root                 (Level 3)
+  {name: ":root pseudo-class selector, matching document root element",      selector: ":root",               expect: ["html"],          exclude: ["element", "fragment", "detached"], level: 3, testType: TEST_FIND},
+  {name: ":root pseudo-class selector, not matching document root element",  selector: ":root",               expect: [] /*no matches*/, exclude: ["document"],                        level: 3, testType: TEST_FIND},
+  {name: ":root pseudo-class selector, not matching document root element",  selector: ":root", ctx: "#html", expect: [] /*no matches*/, exclude: ["fragment", "detached"],            level: 3, testType: TEST_FIND},
+
+  // - :nth-child(n)         (Level 3)
+  {name: ":nth-child selector, matching the third child element",                                               selector: ":nth-child(3)",                    ctx: "#pseudo-nth-table1", expect: ["pseudo-nth-td3", "pseudo-nth-td9", "pseudo-nth-tr3", "pseudo-nth-td15"],             level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-child selector, matching every third child element",                                             selector: "li:nth-child(3n)",                 ctx: "#pseudo-nth", expect: ["pseudo-nth-li3", "pseudo-nth-li6", "pseudo-nth-li9", "pseudo-nth-li12"],                    level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-child selector, matching every second child element, starting from the fourth",                  selector: "li:nth-child(2n+4)",               ctx: "#pseudo-nth", expect: ["pseudo-nth-li4", "pseudo-nth-li6", "pseudo-nth-li8", "pseudo-nth-li10", "pseudo-nth-li12"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-child selector, matching every second child element, starting from the fourth, with whitespace", selector: "li:nth-child(2n \t\r\n+ \t\r\n4)", ctx: "#pseudo-nth", expect: ["pseudo-nth-li4", "pseudo-nth-li6", "pseudo-nth-li8", "pseudo-nth-li10", "pseudo-nth-li12"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-child selector, matching every fourth child element, starting from the third",                   selector: ":nth-child(4n-1)",                 ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em2", "pseudo-nth-span3"],                                                    level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-child selector, matching every fourth child element, starting from the third, with whitespace",  selector: ":nth-child(4n \t\r\n- \t\r\n1)",   ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em2", "pseudo-nth-span3"],                                                    level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-child selector used twice, matching ",                                                           selector: ":nth-child(1) :nth-child(1)",      ctx: "#pseudo-nth", expect: ["pseudo-nth-table1", "pseudo-nth-tr1"],                                                      level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // - :nth-last-child       (Level 3)
+  {name: ":nth-last-child selector, matching the third last child element",                                           selector: ":nth-last-child(3)",      ctx: "#pseudo-nth-table1", expect: ["pseudo-nth-tr1", "pseudo-nth-td4", "pseudo-nth-td10", "pseudo-nth-td16"],         level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-last-child selector, matching every third child element from the end",                                 selector: "li:nth-last-child(3n)",   ctx: "pseudo-nth", expect: ["pseudo-nth-li1", "pseudo-nth-li4", "pseudo-nth-li7", "pseudo-nth-li10"],                  level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-last-child selector, matching every second child element from the end, starting from the fourth last", selector: "li:nth-last-child(2n+4)", ctx: "pseudo-nth", expect: ["pseudo-nth-li1", "pseudo-nth-li3", "pseudo-nth-li5", "pseudo-nth-li7", "pseudo-nth-li9"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-last-child selector, matching every fourth element from the end, starting from the third last",        selector: ":nth-last-child(4n-1)",   ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-span2", "pseudo-nth-span4"],                                               level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // - :nth-of-type(n)       (Level 3)
+  {name: ":nth-of-type selector, matching the third em element",                                        selector: "em:nth-of-type(3)",      ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em3"],                                                                                 level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-of-type selector, matching every second element of their type",                          selector: ":nth-of-type(2n)",       ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em2", "pseudo-nth-span2", "pseudo-nth-span4", "pseudo-nth-strong2", "pseudo-nth-em4"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-of-type selector, matching every second elemetn of their type, starting from the first", selector: "span:nth-of-type(2n-1)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-span1", "pseudo-nth-span3"],                                                           level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // - :nth-last-of-type(n)  (Level 3)
+  {name: ":nth-last-of-type selector, matching the third last em element",                                       selector: "em:nth-last-of-type(3)",      ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-em2"],                                                                                 level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-last-of-type selector, matching every second last element of their type",                         selector: ":nth-last-of-type(2n)",       ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-span1", "pseudo-nth-em1", "pseudo-nth-strong1", "pseudo-nth-em3", "pseudo-nth-span3"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":nth-last-of-type selector, matching every second last element of their type, starting from the last", selector: "span:nth-last-of-type(2n-1)", ctx: "#pseudo-nth-p1", expect: ["pseudo-nth-span2", "pseudo-nth-span4"],                                                           level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // - :first-of-type        (Level 3)
+  {name: ":first-of-type selector, matching the first em element",                   selector: "em:first-of-type",  ctx: "#pseudo-nth-p1",     expect: ["pseudo-nth-em1"],                                           level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":first-of-type selector, matching the first of every type of element",     selector: ":first-of-type",    ctx: "#pseudo-nth-p1",     expect: ["pseudo-nth-span1", "pseudo-nth-em1", "pseudo-nth-strong1"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":first-of-type selector, matching the first td element in each table row", selector: "tr :first-of-type", ctx: "#pseudo-nth-table1", expect: ["pseudo-nth-td1", "pseudo-nth-td7", "pseudo-nth-td13"],      level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // - :last-of-type         (Level 3)
+  {name: ":last-of-type selector, matching the last em elemnet",                     selector: "em:last-of-type",   ctx: "#pseudo-nth-p1",     expect: ["pseudo-nth-em4"],                                           level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":last-of-type selector, matching the last of every type of element",       selector: ":last-of-type",     ctx: "#pseudo-nth-p1",     expect: ["pseudo-nth-span4", "pseudo-nth-strong2", "pseudo-nth-em4"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":last-of-type selector, matching the last td element in each table row",   selector: "tr :last-of-type",  ctx: "#pseudo-nth-table1", expect: ["pseudo-nth-td6", "pseudo-nth-td12", "pseudo-nth-td18"],     level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // - :first-child
+  {name: ":first-child pseudo-class selector, matching first child div element",          selector: "div:first-child",                                                            ctx: "#pseudo-first-child", expect: ["pseudo-first-child-div1"],                                                          level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: ":first-child pseudo-class selector, doesn't match non-first-child elements",    selector: ".pseudo-first-child-div2:first-child, .pseudo-first-child-div3:first-child", ctx: "#pseudo-first-child", expect: [] /*no matches*/,                                                                    level: 2, testType: TEST_FIND},
+  {name: ":first-child pseudo-class selector, matching first-child of multiple elements", selector: "span:first-child",                                                           ctx: "#pseudo-first-child", expect: ["pseudo-first-child-span1", "pseudo-first-child-span3", "pseudo-first-child-span5"], level: 2, testType: TEST_FIND | TEST_MATCH},
+
+  // - :last-child           (Level 3)
+  {name: ":last-child pseudo-class selector, matching last child div element",           selector: "div:last-child",                                                          ctx: "#pseudo-last-child", expect: ["pseudo-last-child-div3"],                                                        level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":last-child pseudo-class selector, doesn't match non-last-child elements",     selector: ".pseudo-last-child-div1:last-child, .pseudo-last-child-div2:first-child", ctx: "#pseudo-last-child", expect: [] /*no matches*/,                                                                 level: 3, testType: TEST_FIND},
+  {name: ":last-child pseudo-class selector, matching first-child of multiple elements", selector: "span:last-child",                                                         ctx: "#pseudo-last-child", expect: ["pseudo-last-child-span2", "pseudo-last-child-span4", "pseudo-last-child-span6"], level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // - :only-child           (Level 3)
+  {name: ":pseudo-only-child pseudo-class selector, matching all only-child elements", selector: ":only-child",   ctx: "#pseudo-only", expect: ["pseudo-only-span1"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":pseudo-only-child pseudo-class selector, matching only-child em elements",  selector: "em:only-child", ctx: "#pseudo-only", expect: [] /*no matches*/,     level: 3, testType: TEST_FIND},
+
+  // - :only-of-type         (Level 3)
+  {name: ":pseudo-only-of-type pseudo-class selector, matching all elements with no siblings of the same type", selector: " :only-of-type",   ctx: "#pseudo-only", expect: ["pseudo-only-span1", "pseudo-only-em1"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":pseudo-only-of-type pseudo-class selector, matching em elements with no siblings of the same type",  selector: " em:only-of-type", ctx: "#pseudo-only", expect: ["pseudo-only-em1"],                    level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // - :empty                (Level 3)
+  {name: ":empty pseudo-class selector, matching empty p elements",   selector: "p:empty", ctx: "#pseudo-empty", expect: ["pseudo-empty-p1", "pseudo-empty-p2"],                       level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":empty pseudo-class selector, matching all empty elements", selector: ":empty",  ctx: "#pseudo-empty", expect: ["pseudo-empty-p1", "pseudo-empty-p2", "pseudo-empty-span1"], level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // - :link and :visited
+  // Implementations may treat all visited links as unvisited, so these cannot be tested separately.
+  // The only guarantee is that ":link,:visited" matches the set of all visited and unvisited links and that they are individually mutually exclusive sets.
+  {name: ":link and :visited pseudo-class selectors, matching a and area elements with href attributes",        selector: " :link, #pseudo-link :visited", ctx: "#pseudo-link", expect: ["pseudo-link-a1", "pseudo-link-a2", "pseudo-link-area1"],                                level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: ":link and :visited pseudo-class selectors, matching no elements",                                     selector: " :link, #head :visited",        ctx: "#head",        expect: [] /*no matches*/,                          exclude: ["element", "fragment", "detached"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: ":link and :visited pseudo-class selectors, not matching link elements with href attributes",          selector: " :link, #head :visited",        ctx: "#head",        expect: [] /*no matches*/,                          exclude: ["document"],                        level: 1, testType: TEST_FIND},
+  {name: ":link and :visited pseudo-class selectors, chained, mutually exclusive pseudo-classes match nothing", selector: ":link:visited",                 ctx: "#html",        expect: [] /*no matches*/,                          exclude: ["document"],                        level: 1, testType: TEST_FIND},
+
+// XXX Figure out context or refNodes for this
+  // - :target               (Level 3)
+  {name: ":target pseudo-class selector, matching the element referenced by the URL fragment identifier", selector: ":target", ctx: "", expect: [] /*no matches*/, exclude: ["document", "element"],  level: 3, testType: TEST_FIND},
+  {name: ":target pseudo-class selector, matching the element referenced by the URL fragment identifier", selector: ":target", ctx: "", expect: ["target"],        exclude: ["fragment", "detached"], level: 3, testType: TEST_FIND},
+
+// XXX Fix ctx in tests below
+
+  // - :lang()
+  {name: ":lang pseudo-class selector, matching inherited language (1)",                     selector: "#pseudo-lang-div1:lang(en)",    ctx: "", expect: ["pseudo-lang-div1"], exclude: ["detached", "fragment"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: ":lang pseudo-class selector, not matching element with no inherited language", selector: "#pseudo-lang-div1:lang(en)",    ctx: "", expect: [] /*no matches*/,    exclude: ["document", "element"],  level: 2, testType: TEST_FIND},
+  {name: ":lang pseudo-class selector, matching specified language with exact value (1)",    selector: "#pseudo-lang-div2:lang(fr)",    ctx: "", expect: ["pseudo-lang-div2"],                                    level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: ":lang pseudo-class selector, matching specified language with partial value (1)",  selector: "#pseudo-lang-div3:lang(en)",    ctx: "", expect: ["pseudo-lang-div3"],                                    level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: ":lang pseudo-class selector, not matching incorrect language",                 selector: "#pseudo-lang-div4:lang(es-AR)", ctx: "", expect: [] /*no matches*/,                                       level: 2, testType: TEST_FIND},
+
+  // - :enabled              (Level 3)
+  {name: ":enabled pseudo-class selector, matching all enabled form controls (1)",  selector: "#pseudo-ui :enabled",  ctx: "", expect: ["pseudo-ui-input1", "pseudo-ui-input2", "pseudo-ui-input3", "pseudo-ui-input4", "pseudo-ui-input5", "pseudo-ui-input6",
+                                                                                                                           "pseudo-ui-input7", "pseudo-ui-input8", "pseudo-ui-input9", "pseudo-ui-textarea1", "pseudo-ui-button1"],    level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":enabled pseudo-class selector, not matching link elements (1)",  selector: "#pseudo-link :enabled",  ctx: "", expect: [] /*no matches*/, unexpected: ["pseudo-link-a1","pseudo-link-a2","pseudo-link-a3","pseudo-link-map1","pseudo-link-area1","pseudo-link-area2"],   level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :disabled             (Level 3)
+  {name: ":disabled pseudo-class selector, matching all disabled form controls (1)", selector: "#pseudo-ui :disabled", ctx: "", expect: ["pseudo-ui-input10", "pseudo-ui-input11", "pseudo-ui-input12", "pseudo-ui-input13", "pseudo-ui-input14", "pseudo-ui-input15",
+                                                                                                                           "pseudo-ui-input16", "pseudo-ui-input17", "pseudo-ui-input18", "pseudo-ui-textarea2", "pseudo-ui-button2"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":disabled pseudo-class selector, not matching link elements (1)", selector: "#pseudo-link :disabled", ctx: "", expect: [] /*no matches*/, unexpected: ["pseudo-link-a1","pseudo-link-a2","pseudo-link-a3","pseudo-link-map1","pseudo-link-area1","pseudo-link-area2"], level: 3, testType: TEST_QSA | TEST_MATCH},
+
+  // - :checked              (Level 3)
+  {name: ":checked pseudo-class selector, matching checked radio buttons and checkboxes (1)", selector: "#pseudo-ui :checked", ctx: "", expect: ["pseudo-ui-input4", "pseudo-ui-input6", "pseudo-ui-input13", "pseudo-ui-input15"],  level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // - :not(s)               (Level 3)
+  {name: ":not pseudo-class selector, matching (1)", selector: "#not>:not(div)",   ctx: "", expect: ["not-p1", "not-p2", "not-p3"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":not pseudo-class selector, matching (1)", selector: "#not * :not(:first-child)",   ctx: "", expect: ["not-em1", "not-em2", "not-em3"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: ":not pseudo-class selector, matching nothing", selector: ":not(*)",   ctx: "", expect: [] /* no matches */, level: 3, testType: TEST_FIND},
+  {name: ":not pseudo-class selector, matching nothing", selector: ":not(*|*)", ctx: "", expect: [] /* no matches */, level: 3, testType: TEST_FIND},
+
+  // Pseudo-elements
+  // - ::first-line
+  {name: ":first-line pseudo-element (one-colon syntax) selector, not matching any elements",    selector: "#pseudo-element:first-line",    ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND},
+  {name: "::first-line pseudo-element (two-colon syntax) selector, not matching any elements",   selector: "#pseudo-element::first-line",   ctx: "", expect: [] /*no matches*/, level: 3, testType: TEST_FIND},
+
+  // - ::first-letter
+  {name: ":first-letter pseudo-element (one-colon syntax) selector, not matching any elements",  selector: "#pseudo-element:first-letter",  ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND},
+  {name: "::first-letter pseudo-element (two-colon syntax) selector, not matching any elements", selector: "#pseudo-element::first-letter", ctx: "", expect: [] /*no matches*/, level: 3, testType: TEST_FIND},
+
+  // - ::before
+  {name: ":before pseudo-element (one-colon syntax) selector, not matching any elements",        selector: "#pseudo-element:before",        ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND},
+  {name: "::before pseudo-element (two-colon syntax) selector, not matching any elements",       selector: "#pseudo-element::before",       ctx: "", expect: [] /*no matches*/, level: 3, testType: TEST_FIND},
+
+  // - ::after
+  {name: ":after pseudo-element (one-colon syntax) selector, not matching any elements",         selector: "#pseudo-element:after",         ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND},
+  {name: "::after pseudo-element (two-colon syntax) selector, not matching any elements",        selector: "#pseudo-element::after",        ctx: "", expect: [] /*no matches*/, level: 3, testType: TEST_FIND},
+
+  // Class Selectors
+  {name: "Class selector, matching element with specified class (1)",                                           selector: ".class-p",                ctx: "", expect: ["class-p1","class-p2", "class-p3"],                                              level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Class selector, chained, matching only elements with all specified classes (1)",                      selector: "#class .apple.orange.banana",    ctx: "", expect: ["class-div1", "class-div2", "class-p4", "class-div3", "class-p6", "class-div4"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Class Selector, chained, with type selector (1)",                                                     selector: "div.apple.banana.orange", ctx: "", expect: ["class-div1", "class-div2", "class-div3", "class-div4"],                         level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Class selector, matching element with class value using non-ASCII characters (2)",                    selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci",             ctx: "", expect: ["class-span1"],               level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Class selector, matching multiple elements with class value using non-ASCII characters (1)",          selector: ".\u53F0\u5317",                     ctx: "", expect: ["class-span1","class-span2"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Class selector, chained, matching element with multiple class values using non-ASCII characters (2)", selector: ".\u53F0\u5317Ta\u0301ibe\u030Ci.\u53F0\u5317",          ctx: "", expect: ["class-span1"],               level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Class selector, matching element with class with escaped character (1)",                              selector: ".foo\\:bar",              ctx: "", expect: ["class-span3"],               level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Class selector, matching element with class with escaped character (1)",                              selector: ".test\\.foo\\[5\\]bar",   ctx: "", expect: ["class-span4"],               level: 1, testType: TEST_FIND | TEST_MATCH},
+
+  // ID Selectors
+  {name: "ID selector, matching element with specified id (1)",           selector: "#id #id-div1",              ctx: "", expect: ["id-div1"],            level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "ID selector, chained, matching element with specified id (1)",  selector: "#id-div1, #id-div1",        ctx: "", expect: ["id-div1"],            level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "ID selector, chained, matching element with specified id (1)",  selector: "#id-div1, #id-div2",        ctx: "", expect: ["id-div1", "id-div2"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "ID Selector, chained, with type selector (1)",                  selector: "div#id-div1, div#id-div2",  ctx: "", expect: ["id-div1", "id-div2"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "ID selector, not matching non-existent descendant",         selector: "#id #none",                 ctx: "", expect: [] /*no matches*/,      level: 1, testType: TEST_FIND},
+  {name: "ID selector, not matching non-existent ancestor",           selector: "#none #id-div1",            ctx: "", expect: [] /*no matches*/,      level: 1, testType: TEST_FIND},
+  {name: "ID selector, matching multiple elements with duplicate id (1)", selector: "#id-li-duplicate",          ctx: "", expect: ["id-li-duplicate", "id-li-duplicate", "id-li-duplicate", "id-li-duplicate"], level: 1, testType: TEST_FIND | TEST_MATCH},
+
+  {name: "ID selector, matching id value using non-ASCII characters (3)",    selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci",           ctx: "", expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci"],       level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "ID selector, matching id value using non-ASCII characters (4)",    selector: "#\u53F0\u5317",                   ctx: "", expect: ["\u53F0\u5317"],               level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "ID selector, matching id values using non-ASCII characters (2)",   selector: "#\u53F0\u5317Ta\u0301ibe\u030Ci, #\u53F0\u5317",      ctx: "", expect: ["\u53F0\u5317Ta\u0301ibe\u030Ci", "\u53F0\u5317"], level: 1, testType: TEST_FIND | TEST_MATCH},
+
+  // XXX runMatchesTest() in level2-lib.js can't handle this because obtaining the expected nodes requires escaping characters when generating the selector from 'expect' values
+  {name: "ID selector, matching element with id with escaped character", selector: "#\\#foo\\:bar",         ctx: "", expect: ["#foo:bar"],         level: 1, testType: TEST_FIND},
+  {name: "ID selector, matching element with id with escaped character", selector: "#test\\.foo\\[5\\]bar", ctx: "", expect: ["test.foo[5]bar"],   level: 1, testType: TEST_FIND},
+
+  // Namespaces
+  // XXX runMatchesTest() in level2-lib.js can't handle these because non-HTML elements don't have a recognised id
+  {name: "Namespace selector, matching element with any namespace",        selector: "#any-namespace *|div", ctx: "", expect: ["any-namespace-div1", "any-namespace-div2", "any-namespace-div3", "any-namespace-div4"], level: 3, testType: TEST_FIND},
+  {name: "Namespace selector, matching div elements in no namespace only", selector: "#no-namespace |div",   ctx: "", expect: ["no-namespace-div3"], level: 3, testType: TEST_FIND},
+  {name: "Namespace selector, matching any elements in no namespace only", selector: "#no-namespace |*",     ctx: "", expect: ["no-namespace-div3"], level: 3, testType: TEST_FIND},
+
+  // Combinators
+  // - Descendant combinator ' '
+  {name: "Descendant combinator, matching element that is a descendant of an element with id (1)",                 selector: "#descendant div",                   ctx: "", expect: ["descendant-div1", "descendant-div2", "descendant-div3", "descendant-div4"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Descendant combinator, matching element with id that is a descendant of an element (1)",                 selector: "body #descendant-div1",             ctx: "", expect: ["descendant-div1"], exclude: ["detached", "fragment"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Descendant combinator, matching element with id that is a descendant of an element (1)",                 selector: "div #descendant-div1",              ctx: "", expect: ["descendant-div1"],                                    level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Descendant combinator, matching element with id that is a descendant of an element with id (1)",         selector: "#descendant #descendant-div2",      ctx: "", expect: ["descendant-div2"],                                    level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Descendant combinator, matching element with class that is a descendant of an element with id (1)",      selector: "#descendant .descendant-div2",      ctx: "", expect: ["descendant-div2"],                                    level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Descendant combinator, matching element with class that is a descendant of an element with class (1)",   selector: ".descendant-div1 .descendant-div3", ctx: "", expect: ["descendant-div3"],                                    level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Descendant combinator, not matching element with id that is not a descendant of an element with id", selector: "#descendant-div1 #descendant-div4", ctx: "", expect: [] /*no matches*/,                                      level: 1, testType: TEST_FIND},
+  {name: "Descendant combinator, whitespace characters (1)",                                                       selector: "#descendant\t\r\n#descendant-div2", ctx: "", expect: ["descendant-div2"],                                    level: 1, testType: TEST_FIND | TEST_MATCH},
+
+  // // - Descendant combinator '>>'
+  // {name: "Descendant combinator '>>', matching element that is a descendant of an element with id (1)",                 selector: "#descendant>>div",                   ctx: "", expect: ["descendant-div1", "descendant-div2", "descendant-div3", "descendant-div4"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element (1)",                 selector: "body>>#descendant-div1",             ctx: "", expect: ["descendant-div1"], exclude: ["detached", "fragment"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element (1)",                 selector: "div>>#descendant-div1",              ctx: "", expect: ["descendant-div1"],                                    level: 1, testType: TEST_FIND | TEST_MATCH},
+  // {name: "Descendant combinator '>>', matching element with id that is a descendant of an element with id (1)",         selector: "#descendant>>#descendant-div2",      ctx: "", expect: ["descendant-div2"],                                    level: 1, testType: TEST_FIND | TEST_MATCH},
+  // {name: "Descendant combinator '>>', matching element with class that is a descendant of an element with id (1)",      selector: "#descendant>>.descendant-div2",      ctx: "", expect: ["descendant-div2"],                                    level: 1, testType: TEST_FIND | TEST_MATCH},
+  // {name: "Descendant combinator, '>>', matching element with class that is a descendant of an element with class (1)",   selector: ".descendant-div1>>.descendant-div3", ctx: "", expect: ["descendant-div3"],                                    level: 1, testType: TEST_FIND | TEST_MATCH},
+  // {name: "Descendant combinator '>>', not matching element with id that is not a descendant of an element with id", selector: "#descendant-div1>>#descendant-div4", ctx: "", expect: [] /*no matches*/,                                      level: 1, testType: TEST_FIND},
+
+  // - Child combinator '>'
+  {name: "Child combinator, matching element that is a child of an element with id (1)",                       selector: "#child>div",                          ctx: "", expect: ["child-div1", "child-div4"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Child combinator, matching element with id that is a child of an element (1)",                       selector: "div>#child-div1",                     ctx: "", expect: ["child-div1"],               level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Child combinator, matching element with id that is a child of an element with id (1)",               selector: "#child>#child-div1",                  ctx: "", expect: ["child-div1"],               level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Child combinator, matching element with id that is a child of an element with class (1)",            selector: "#child-div1>.child-div2",             ctx: "", expect: ["child-div2"],               level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Child combinator, matching element with class that is a child of an element with class (1)",         selector: ".child-div1>.child-div2",             ctx: "", expect: ["child-div2"],               level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Child combinator, not matching element with id that is not a child of an element with id",       selector: "#child>#child-div3",                  ctx: "", expect: [] /*no matches*/,            level: 2, testType: TEST_FIND},
+  {name: "Child combinator, not matching element with id that is not a child of an element with class",    selector: "#child-div1>.child-div3",             ctx: "", expect: [] /*no matches*/,            level: 2, testType: TEST_FIND},
+  {name: "Child combinator, not matching element with class that is not a child of an element with class", selector: ".child-div1>.child-div3",             ctx: "", expect: [] /*no matches*/,            level: 2, testType: TEST_FIND},
+  {name: "Child combinator, surrounded by whitespace (1)",                                                     selector: "#child-div1\t\r\n>\t\r\n#child-div2", ctx: "", expect: ["child-div2"],               level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Child combinator, whitespace after (1)",                                                             selector: "#child-div1>\t\r\n#child-div2",       ctx: "", expect: ["child-div2"],               level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Child combinator, whitespace before (1)",                                                            selector: "#child-div1\t\r\n>#child-div2",       ctx: "", expect: ["child-div2"],               level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Child combinator, no whitespace (1)",                                                                selector: "#child-div1>#child-div2",             ctx: "", expect: ["child-div2"],               level: 2, testType: TEST_FIND | TEST_MATCH},
+
+  // - Adjacent sibling combinator '+'
+  {name: "Adjacent sibling combinator, matching element that is an adjacent sibling of an element with id (1)",                 selector: "#adjacent-div2+div",                                         ctx: "", expect: ["adjacent-div4"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element (1)",                 selector: "div+#adjacent-div4",                                         ctx: "", expect: ["adjacent-div4"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Adjacent sibling combinator, matching element with id that is an adjacent sibling of an element with id (1)",         selector: "#adjacent-div2+#adjacent-div4",                              ctx: "", expect: ["adjacent-div4"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with id (1)",      selector: "#adjacent-div2+.adjacent-div4",                              ctx: "", expect: ["adjacent-div4"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Adjacent sibling combinator, matching element with class that is an adjacent sibling of an element with class (1)",   selector: ".adjacent-div2+.adjacent-div4",                              ctx: "", expect: ["adjacent-div4"], level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Adjacent sibling combinator, matching p element that is an adjacent sibling of a div element (1)",                    selector: "#adjacent div+p",                                            ctx: "", expect: ["adjacent-p2"],   level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Adjacent sibling combinator, not matching element with id that is not an adjacent sibling of an element with id", selector: "#adjacent-div2+#adjacent-p2, #adjacent-div2+#adjacent-div1", ctx: "", expect: [] /*no matches*/, level: 2, testType: TEST_FIND},
+  {name: "Adjacent sibling combinator, surrounded by whitespace (1)",                                                           selector: "#adjacent-p2\t\r\n+\t\r\n#adjacent-p3",                      ctx: "", expect: ["adjacent-p3"],   level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Adjacent sibling combinator, whitespace after (1)",                                                                   selector: "#adjacent-p2+\t\r\n#adjacent-p3",                            ctx: "", expect: ["adjacent-p3"],   level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Adjacent sibling combinator, whitespace before (1)",                                                                  selector: "#adjacent-p2\t\r\n+#adjacent-p3",                            ctx: "", expect: ["adjacent-p3"],   level: 2, testType: TEST_FIND | TEST_MATCH},
+  {name: "Adjacent sibling combinator, no whitespace (1)",                                                                      selector: "#adjacent-p2+#adjacent-p3",                                  ctx: "", expect: ["adjacent-p3"],   level: 2, testType: TEST_FIND | TEST_MATCH},
+
+  // - General sibling combinator ~ (Level 3)
+  {name: "General sibling combinator, matching element that is a sibling of an element with id (1)",                    selector: "#sibling-div2~div",                                        ctx: "", expect: ["sibling-div4", "sibling-div6"], level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "General sibling combinator, matching element with id that is a sibling of an element (1)",                    selector: "div~#sibling-div4",                                        ctx: "", expect: ["sibling-div4"],                 level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "General sibling combinator, matching element with id that is a sibling of an element with id (1)",            selector: "#sibling-div2~#sibling-div4",                              ctx: "", expect: ["sibling-div4"],                 level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "General sibling combinator, matching element with class that is a sibling of an element with id (1)",         selector: "#sibling-div2~.sibling-div",                               ctx: "", expect: ["sibling-div4", "sibling-div6"],                 level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "General sibling combinator, matching p element that is a sibling of a div element (1)",                       selector: "#sibling div~p",                                           ctx: "", expect: ["sibling-p2", "sibling-p3"],                   level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "General sibling combinator, not matching element with id that is not a sibling after a p element (1)",        selector: "#sibling>p~div",                                           ctx: "", expect: [] /*no matches*/,                level: 3, testType: TEST_FIND},
+  {name: "General sibling combinator, not matching element with id that is not a sibling after an element with id", selector: "#sibling-div2~#sibling-div3, #sibling-div2~#sibling-div1", ctx: "", expect: [] /*no matches*/,                level: 3, testType: TEST_FIND},
+  {name: "General sibling combinator, surrounded by whitespace (1)",                                                    selector: "#sibling-p2\t\r\n~\t\r\n#sibling-p3",                      ctx: "", expect: ["sibling-p3"],                   level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "General sibling combinator, whitespace after (1)",                                                            selector: "#sibling-p2~\t\r\n#sibling-p3",                            ctx: "", expect: ["sibling-p3"],                   level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "General sibling combinator, whitespace before (1)",                                                           selector: "#sibling-p2\t\r\n~#sibling-p3",                            ctx: "", expect: ["sibling-p3"],                   level: 3, testType: TEST_FIND | TEST_MATCH},
+  {name: "General sibling combinator, no whitespace (1)",                                                               selector: "#sibling-p2~#sibling-p3",                                  ctx: "", expect: ["sibling-p3"],                   level: 3, testType: TEST_FIND | TEST_MATCH},
+
+  // Group of selectors (comma)
+  {name: "Syntax, group of selectors separator, surrounded by whitespace (1)", selector: "#group em\t\r \n,\t\r \n#group strong", ctx: "", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Syntax, group of selectors separator, whitespace after (1)",         selector: "#group em,\t\r\n#group strong",         ctx: "", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Syntax, group of selectors separator, whitespace before (1)",        selector: "#group em\t\r\n,#group strong",         ctx: "", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_FIND | TEST_MATCH},
+  {name: "Syntax, group of selectors separator, no whitespace (1)",            selector: "#group em,#group strong",               ctx: "", expect: ["group-em1", "group-strong1"], level: 1, testType: TEST_FIND | TEST_MATCH},
+];