From 232395dcddde240665a4456857bc46fea0161cdc Mon Sep 17 00:00:00 2001 From: Pierre Tachoire Date: Wed, 3 Jan 2024 10:14:23 +0100 Subject: [PATCH] wpt: remove tests cases --- .../HTMLCollection-as-prototype.html | 29 - .../collections/HTMLCollection-delete.html | 45 - .../HTMLCollection-empty-name.html | 65 - .../collections/HTMLCollection-iterator.html | 45 - .../HTMLCollection-live-mutations.window.js | 93 - .../collections/HTMLCollection-own-props.html | 109 - ...Collection-supported-property-indices.html | 179 - ...MLCollection-supported-property-names.html | 135 - ...domstringmap-supported-property-names.html | 54 - ...namednodemap-supported-property-names.html | 30 - tests/wpt/dom/nodes/ChildNode-after.html | 166 - ...ment-with-null-browsing-context-crash.html | 13 - .../DOMImplementation-createDocument.html | 170 - .../DOMImplementation-createDocumentType.html | 123 - ...ment-with-null-browsing-context-crash.html | 13 - ...TMLDocument-with-saved-implementation.html | 16 - .../DOMImplementation-createHTMLDocument.html | 96 - .../DOMImplementation-createHTMLDocument.js | 25 - .../nodes/DOMImplementation-hasFeature.html | 155 - .../Document-Element-getElementsByTagName.js | 208 - tests/wpt/dom/nodes/Document-adoptNode.html | 50 - .../dom/nodes/Document-createAttribute.html | 55 - .../Document-createCDATASection-xhtml.xhtml | 22 - .../nodes/Document-createCDATASection.html | 16 - .../Document-createComment-createTextNode.js | 22 - .../wpt/dom/nodes/Document-createComment.html | 21 - .../wpt/dom/nodes/Document-createElement.html | 158 - .../dom/nodes/Document-createElementNS.html | 224 - .../wpt/dom/nodes/Document-createElementNS.js | 189 - ...nt-createProcessingInstruction-xhtml.xhtml | 15 - .../Document-createProcessingInstruction.html | 11 - .../Document-createProcessingInstruction.js | 39 - .../dom/nodes/Document-createTextNode.html | 21 - tests/wpt/dom/nodes/Document-doctype.html | 21 - .../Document-getElementsByClassName.html | 26 - .../nodes/Document-getElementsByTagName.html | 11 - tests/wpt/dom/nodes/Document-importNode.html | 67 - .../nodes/DocumentFragment-constructor.html | 22 - .../DocumentFragment-getElementById.html | 62 - ...t-querySelectorAll-after-modification.html | 24 - tests/wpt/dom/nodes/DocumentType-literal.html | 17 - .../nodes/Element-childElement-null-svg.svg | 20 - .../Element-childElement-null-xhtml.xhtml | 20 - .../dom/nodes/Element-childElement-null.html | 15 - ...ment-childElementCount-dynamic-add-svg.svg | 22 - ...-childElementCount-dynamic-add-xhtml.xhtml | 22 - ...Element-childElementCount-dynamic-add.html | 17 - ...t-childElementCount-dynamic-remove-svg.svg | 22 - ...ildElementCount-dynamic-remove-xhtml.xhtml | 22 - ...ment-childElementCount-dynamic-remove.html | 17 - .../Element-childElementCount-nochild-svg.svg | 19 - ...ment-childElementCount-nochild-xhtml.xhtml | 19 - .../Element-childElementCount-nochild.html | 14 - .../nodes/Element-childElementCount-svg.svg | 25 - .../Element-childElementCount-xhtml.xhtml | 25 - .../dom/nodes/Element-childElementCount.html | 20 - tests/wpt/dom/nodes/Element-children.html | 58 - tests/wpt/dom/nodes/Element-classlist.html | 478 -- tests/wpt/dom/nodes/Element-closest.html | 73 - ...ement-firstElementChild-entity-xhtml.xhtml | 27 - .../Element-firstElementChild-entity.svg | 26 - ...lement-firstElementChild-namespace-svg.svg | 26 - ...nt-firstElementChild-namespace-xhtml.xhtml | 28 - .../Element-firstElementChild-namespace.html | 21 - .../nodes/Element-firstElementChild-svg.svg | 23 - .../Element-firstElementChild-xhtml.xhtml | 23 - .../dom/nodes/Element-firstElementChild.html | 18 - .../nodes/Element-getElementsByClassName.html | 43 - ...agName-change-document-HTMLNess-iframe.xml | 1 - ...ntsByTagName-change-document-HTMLNess.html | 51 - .../nodes/Element-getElementsByTagName.html | 30 - .../nodes/Element-getElementsByTagNameNS.html | 37 - tests/wpt/dom/nodes/Element-hasAttribute.html | 32 - .../wpt/dom/nodes/Element-hasAttributes.html | 40 - .../nodes/Element-insertAdjacentElement.html | 91 - .../dom/nodes/Element-insertAdjacentText.html | 76 - .../nodes/Element-lastElementChild-svg.svg | 22 - .../Element-lastElementChild-xhtml.xhtml | 22 - .../dom/nodes/Element-lastElementChild.html | 17 - tests/wpt/dom/nodes/Element-matches-init.js | 65 - .../Element-matches-namespaced-elements.html | 24 - tests/wpt/dom/nodes/Element-matches.html | 22 - tests/wpt/dom/nodes/Element-matches.js | 135 - .../nodes/Element-nextElementSibling-svg.svg | 23 - .../Element-nextElementSibling-xhtml.xhtml | 23 - .../dom/nodes/Element-nextElementSibling.html | 18 - .../Element-previousElementSibling-svg.svg | 28 - ...Element-previousElementSibling-xhtml.xhtml | 28 - .../nodes/Element-previousElementSibling.html | 23 - tests/wpt/dom/nodes/Element-remove.html | 16 - .../dom/nodes/Element-removeAttribute.html | 58 - .../dom/nodes/Element-removeAttributeNS.html | 18 - .../Element-setAttribute-crbug-1138487.html | 22 - tests/wpt/dom/nodes/Element-setAttribute.html | 38 - .../nodes/Element-siblingElement-null-svg.svg | 20 - .../Element-siblingElement-null-xhtml.xhtml | 20 - .../nodes/Element-siblingElement-null.html | 16 - tests/wpt/dom/nodes/Element-tagName.html | 57 - .../nodes/Element-webkitMatchesSelector.html | 22 - ...ppendChild-cereactions-vs-script.window.js | 27 - tests/wpt/dom/nodes/Node-appendChild.html | 59 - tests/wpt/dom/nodes/Node-baseURI.html | 62 - tests/wpt/dom/nodes/Node-childNodes.html | 117 - .../dom/nodes/Node-cloneNode-XMLDocument.html | 28 - .../Node-cloneNode-document-with-doctype.html | 51 - ...oneNode-external-stylesheet-no-bc.sub.html | 23 - ...-cloneNode-on-inactive-document-crash.html | 6 - tests/wpt/dom/nodes/Node-cloneNode-svg.html | 63 - tests/wpt/dom/nodes/Node-cloneNode.html | 346 -- .../nodes/Node-compareDocumentPosition.html | 87 - tests/wpt/dom/nodes/Node-constants.html | 39 - tests/wpt/dom/nodes/Node-contains-xml.xml | 83 - tests/wpt/dom/nodes/Node-contains.html | 36 - tests/wpt/dom/nodes/Node-insertBefore.html | 297 - .../nodes/Node-isConnected-shadow-dom.html | 29 - tests/wpt/dom/nodes/Node-isConnected.html | 95 - .../dom/nodes/Node-isEqualNode-iframe1.xml | 1 - .../dom/nodes/Node-isEqualNode-iframe2.xml | 1 - .../dom/nodes/Node-isEqualNode-xhtml.xhtml | 84 - tests/wpt/dom/nodes/Node-isEqualNode.html | 161 - tests/wpt/dom/nodes/Node-isSameNode.html | 111 - .../dom/nodes/Node-lookupNamespaceURI.html | 139 - tests/wpt/dom/nodes/Node-lookupPrefix.xhtml | 31 - .../dom/nodes/Node-mutation-adoptNode.html | 23 - tests/wpt/dom/nodes/Node-nodeName-xhtml.xhtml | 42 - tests/wpt/dom/nodes/Node-nodeName.html | 32 - tests/wpt/dom/nodes/Node-nodeValue.html | 71 - tests/wpt/dom/nodes/Node-normalize.html | 83 - tests/wpt/dom/nodes/Node-parentElement.html | 82 - .../wpt/dom/nodes/Node-parentNode-iframe.html | 1 - tests/wpt/dom/nodes/Node-parentNode.html | 33 - tests/wpt/dom/nodes/Node-properties.html | 688 --- tests/wpt/dom/nodes/Node-removeChild.html | 58 - tests/wpt/dom/nodes/Node-replaceChild.html | 349 -- tests/wpt/dom/nodes/Node-textContent.html | 265 - tests/wpt/dom/nodes/NodeList-Iterable.html | 61 - .../nodes/NodeList-live-mutations.window.js | 79 - ...eList-static-length-getter-tampered-1.html | 22 - ...eList-static-length-getter-tampered-2.html | 22 - ...eList-static-length-getter-tampered-3.html | 22 - ...atic-length-getter-tampered-indexOf-1.html | 22 - ...atic-length-getter-tampered-indexOf-2.html | 22 - ...atic-length-getter-tampered-indexOf-3.html | 22 - tests/wpt/dom/nodes/ParentNode-children.html | 27 - .../ParentNode-querySelector-All-content.html | 377 -- .../ParentNode-querySelector-All-content.xht | 372 -- .../ParentNode-querySelector-All-xht.xht | 124 - .../nodes/ParentNode-querySelector-All.html | 120 - .../dom/nodes/ParentNode-querySelector-All.js | 261 - ...ntNode-querySelector-case-insensitive.html | 21 - .../ParentNode-querySelector-escapes.html | 123 - .../nodes/ParentNode-querySelector-scope.html | 33 - ...ode-querySelectorAll-removed-elements.html | 30 - .../ParentNode-querySelectors-exclusive.html | 39 - .../ParentNode-querySelectors-namespaces.html | 21 - ...ectors-space-and-dash-attribute-value.html | 21 - tests/wpt/dom/nodes/append-on-Document.html | 53 - tests/wpt/dom/nodes/attributes.html | 858 --- tests/wpt/dom/nodes/attributes.js | 18 - tests/wpt/dom/nodes/creators.js | 5 - .../pre-insertion-validation-hierarchy.js | 86 - .../pre-insertion-validation-notfound.js | 108 - tests/wpt/dom/nodes/productions.js | 3 - tests/wpt/dom/nodes/selectors.js | 755 --- .../NodeList-static-length-tampered.js | 46 - tests/wpt/failure.html.skip | 11 - tests/wpt/resources/testharness.js | 4941 ----------------- tests/wpt/resources/testharnessreport.js | 34 - tests/wpt/success.html | 10 - 169 files changed, 17572 deletions(-) delete mode 100644 tests/wpt/dom/collections/HTMLCollection-as-prototype.html delete mode 100644 tests/wpt/dom/collections/HTMLCollection-delete.html delete mode 100644 tests/wpt/dom/collections/HTMLCollection-empty-name.html delete mode 100644 tests/wpt/dom/collections/HTMLCollection-iterator.html delete mode 100644 tests/wpt/dom/collections/HTMLCollection-live-mutations.window.js delete mode 100644 tests/wpt/dom/collections/HTMLCollection-own-props.html delete mode 100644 tests/wpt/dom/collections/HTMLCollection-supported-property-indices.html delete mode 100644 tests/wpt/dom/collections/HTMLCollection-supported-property-names.html delete mode 100644 tests/wpt/dom/collections/domstringmap-supported-property-names.html delete mode 100644 tests/wpt/dom/collections/namednodemap-supported-property-names.html delete mode 100644 tests/wpt/dom/nodes/ChildNode-after.html delete mode 100644 tests/wpt/dom/nodes/DOMImplementation-createDocument-with-null-browsing-context-crash.html delete mode 100644 tests/wpt/dom/nodes/DOMImplementation-createDocument.html delete mode 100644 tests/wpt/dom/nodes/DOMImplementation-createDocumentType.html delete mode 100644 tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument-with-null-browsing-context-crash.html delete mode 100644 tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument-with-saved-implementation.html delete mode 100644 tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument.html delete mode 100644 tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument.js delete mode 100644 tests/wpt/dom/nodes/DOMImplementation-hasFeature.html delete mode 100644 tests/wpt/dom/nodes/Document-Element-getElementsByTagName.js delete mode 100644 tests/wpt/dom/nodes/Document-adoptNode.html delete mode 100644 tests/wpt/dom/nodes/Document-createAttribute.html delete mode 100644 tests/wpt/dom/nodes/Document-createCDATASection-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Document-createCDATASection.html delete mode 100644 tests/wpt/dom/nodes/Document-createComment-createTextNode.js delete mode 100644 tests/wpt/dom/nodes/Document-createComment.html delete mode 100644 tests/wpt/dom/nodes/Document-createElement.html delete mode 100644 tests/wpt/dom/nodes/Document-createElementNS.html delete mode 100644 tests/wpt/dom/nodes/Document-createElementNS.js delete mode 100644 tests/wpt/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Document-createProcessingInstruction.html delete mode 100644 tests/wpt/dom/nodes/Document-createProcessingInstruction.js delete mode 100644 tests/wpt/dom/nodes/Document-createTextNode.html delete mode 100644 tests/wpt/dom/nodes/Document-doctype.html delete mode 100644 tests/wpt/dom/nodes/Document-getElementsByClassName.html delete mode 100644 tests/wpt/dom/nodes/Document-getElementsByTagName.html delete mode 100644 tests/wpt/dom/nodes/Document-importNode.html delete mode 100644 tests/wpt/dom/nodes/DocumentFragment-constructor.html delete mode 100644 tests/wpt/dom/nodes/DocumentFragment-getElementById.html delete mode 100644 tests/wpt/dom/nodes/DocumentFragment-querySelectorAll-after-modification.html delete mode 100644 tests/wpt/dom/nodes/DocumentType-literal.html delete mode 100644 tests/wpt/dom/nodes/Element-childElement-null-svg.svg delete mode 100644 tests/wpt/dom/nodes/Element-childElement-null-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-childElement-null.html delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-svg.svg delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount-dynamic-add.html delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-svg.svg delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove.html delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount-nochild-svg.svg delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount-nochild-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount-nochild.html delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount-svg.svg delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-childElementCount.html delete mode 100644 tests/wpt/dom/nodes/Element-children.html delete mode 100644 tests/wpt/dom/nodes/Element-classlist.html delete mode 100644 tests/wpt/dom/nodes/Element-closest.html delete mode 100644 tests/wpt/dom/nodes/Element-firstElementChild-entity-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-firstElementChild-entity.svg delete mode 100644 tests/wpt/dom/nodes/Element-firstElementChild-namespace-svg.svg delete mode 100644 tests/wpt/dom/nodes/Element-firstElementChild-namespace-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-firstElementChild-namespace.html delete mode 100644 tests/wpt/dom/nodes/Element-firstElementChild-svg.svg delete mode 100644 tests/wpt/dom/nodes/Element-firstElementChild-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-firstElementChild.html delete mode 100644 tests/wpt/dom/nodes/Element-getElementsByClassName.html delete mode 100644 tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.xml delete mode 100644 tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html delete mode 100644 tests/wpt/dom/nodes/Element-getElementsByTagName.html delete mode 100644 tests/wpt/dom/nodes/Element-getElementsByTagNameNS.html delete mode 100644 tests/wpt/dom/nodes/Element-hasAttribute.html delete mode 100644 tests/wpt/dom/nodes/Element-hasAttributes.html delete mode 100644 tests/wpt/dom/nodes/Element-insertAdjacentElement.html delete mode 100644 tests/wpt/dom/nodes/Element-insertAdjacentText.html delete mode 100644 tests/wpt/dom/nodes/Element-lastElementChild-svg.svg delete mode 100644 tests/wpt/dom/nodes/Element-lastElementChild-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-lastElementChild.html delete mode 100644 tests/wpt/dom/nodes/Element-matches-init.js delete mode 100644 tests/wpt/dom/nodes/Element-matches-namespaced-elements.html delete mode 100644 tests/wpt/dom/nodes/Element-matches.html delete mode 100644 tests/wpt/dom/nodes/Element-matches.js delete mode 100644 tests/wpt/dom/nodes/Element-nextElementSibling-svg.svg delete mode 100644 tests/wpt/dom/nodes/Element-nextElementSibling-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-nextElementSibling.html delete mode 100644 tests/wpt/dom/nodes/Element-previousElementSibling-svg.svg delete mode 100644 tests/wpt/dom/nodes/Element-previousElementSibling-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-previousElementSibling.html delete mode 100644 tests/wpt/dom/nodes/Element-remove.html delete mode 100644 tests/wpt/dom/nodes/Element-removeAttribute.html delete mode 100644 tests/wpt/dom/nodes/Element-removeAttributeNS.html delete mode 100644 tests/wpt/dom/nodes/Element-setAttribute-crbug-1138487.html delete mode 100644 tests/wpt/dom/nodes/Element-setAttribute.html delete mode 100644 tests/wpt/dom/nodes/Element-siblingElement-null-svg.svg delete mode 100644 tests/wpt/dom/nodes/Element-siblingElement-null-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Element-siblingElement-null.html delete mode 100644 tests/wpt/dom/nodes/Element-tagName.html delete mode 100644 tests/wpt/dom/nodes/Element-webkitMatchesSelector.html delete mode 100644 tests/wpt/dom/nodes/Node-appendChild-cereactions-vs-script.window.js delete mode 100644 tests/wpt/dom/nodes/Node-appendChild.html delete mode 100644 tests/wpt/dom/nodes/Node-baseURI.html delete mode 100644 tests/wpt/dom/nodes/Node-childNodes.html delete mode 100644 tests/wpt/dom/nodes/Node-cloneNode-XMLDocument.html delete mode 100644 tests/wpt/dom/nodes/Node-cloneNode-document-with-doctype.html delete mode 100644 tests/wpt/dom/nodes/Node-cloneNode-external-stylesheet-no-bc.sub.html delete mode 100644 tests/wpt/dom/nodes/Node-cloneNode-on-inactive-document-crash.html delete mode 100644 tests/wpt/dom/nodes/Node-cloneNode-svg.html delete mode 100644 tests/wpt/dom/nodes/Node-cloneNode.html delete mode 100644 tests/wpt/dom/nodes/Node-compareDocumentPosition.html delete mode 100644 tests/wpt/dom/nodes/Node-constants.html delete mode 100644 tests/wpt/dom/nodes/Node-contains-xml.xml delete mode 100644 tests/wpt/dom/nodes/Node-contains.html delete mode 100644 tests/wpt/dom/nodes/Node-insertBefore.html delete mode 100644 tests/wpt/dom/nodes/Node-isConnected-shadow-dom.html delete mode 100644 tests/wpt/dom/nodes/Node-isConnected.html delete mode 100644 tests/wpt/dom/nodes/Node-isEqualNode-iframe1.xml delete mode 100644 tests/wpt/dom/nodes/Node-isEqualNode-iframe2.xml delete mode 100644 tests/wpt/dom/nodes/Node-isEqualNode-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Node-isEqualNode.html delete mode 100644 tests/wpt/dom/nodes/Node-isSameNode.html delete mode 100644 tests/wpt/dom/nodes/Node-lookupNamespaceURI.html delete mode 100644 tests/wpt/dom/nodes/Node-lookupPrefix.xhtml delete mode 100644 tests/wpt/dom/nodes/Node-mutation-adoptNode.html delete mode 100644 tests/wpt/dom/nodes/Node-nodeName-xhtml.xhtml delete mode 100644 tests/wpt/dom/nodes/Node-nodeName.html delete mode 100644 tests/wpt/dom/nodes/Node-nodeValue.html delete mode 100644 tests/wpt/dom/nodes/Node-normalize.html delete mode 100644 tests/wpt/dom/nodes/Node-parentElement.html delete mode 100644 tests/wpt/dom/nodes/Node-parentNode-iframe.html delete mode 100644 tests/wpt/dom/nodes/Node-parentNode.html delete mode 100644 tests/wpt/dom/nodes/Node-properties.html delete mode 100644 tests/wpt/dom/nodes/Node-removeChild.html delete mode 100644 tests/wpt/dom/nodes/Node-replaceChild.html delete mode 100644 tests/wpt/dom/nodes/Node-textContent.html delete mode 100644 tests/wpt/dom/nodes/NodeList-Iterable.html delete mode 100644 tests/wpt/dom/nodes/NodeList-live-mutations.window.js delete mode 100644 tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-1.html delete mode 100644 tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-2.html delete mode 100644 tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-3.html delete mode 100644 tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html delete mode 100644 tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html delete mode 100644 tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html delete mode 100644 tests/wpt/dom/nodes/ParentNode-children.html delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelector-All-content.html delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelector-All-content.xht delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelector-All-xht.xht delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelector-All.html delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelector-All.js delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelector-case-insensitive.html delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelector-escapes.html delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelector-scope.html delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelectorAll-removed-elements.html delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelectors-exclusive.html delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelectors-namespaces.html delete mode 100644 tests/wpt/dom/nodes/ParentNode-querySelectors-space-and-dash-attribute-value.html delete mode 100644 tests/wpt/dom/nodes/append-on-Document.html delete mode 100644 tests/wpt/dom/nodes/attributes.html delete mode 100644 tests/wpt/dom/nodes/attributes.js delete mode 100644 tests/wpt/dom/nodes/creators.js delete mode 100644 tests/wpt/dom/nodes/pre-insertion-validation-hierarchy.js delete mode 100644 tests/wpt/dom/nodes/pre-insertion-validation-notfound.js delete mode 100644 tests/wpt/dom/nodes/productions.js delete mode 100644 tests/wpt/dom/nodes/selectors.js delete mode 100644 tests/wpt/dom/nodes/support/NodeList-static-length-tampered.js delete mode 100644 tests/wpt/failure.html.skip delete mode 100644 tests/wpt/resources/testharness.js delete mode 100644 tests/wpt/resources/testharnessreport.js delete mode 100644 tests/wpt/success.html diff --git a/tests/wpt/dom/collections/HTMLCollection-as-prototype.html b/tests/wpt/dom/collections/HTMLCollection-as-prototype.html deleted file mode 100644 index d572d35c..00000000 --- a/tests/wpt/dom/collections/HTMLCollection-as-prototype.html +++ /dev/null @@ -1,29 +0,0 @@ - - -Objects whose prototype is an HTMLCollection - - -
- diff --git a/tests/wpt/dom/collections/HTMLCollection-delete.html b/tests/wpt/dom/collections/HTMLCollection-delete.html deleted file mode 100644 index 99420d43..00000000 --- a/tests/wpt/dom/collections/HTMLCollection-delete.html +++ /dev/null @@ -1,45 +0,0 @@ - - -Deleting properties from HTMLCollection - - -
- - diff --git a/tests/wpt/dom/collections/HTMLCollection-empty-name.html b/tests/wpt/dom/collections/HTMLCollection-empty-name.html deleted file mode 100644 index 4fc34db7..00000000 --- a/tests/wpt/dom/collections/HTMLCollection-empty-name.html +++ /dev/null @@ -1,65 +0,0 @@ - - -HTMLCollection and empty names - - -
-
-
-
- -
- diff --git a/tests/wpt/dom/collections/HTMLCollection-iterator.html b/tests/wpt/dom/collections/HTMLCollection-iterator.html deleted file mode 100644 index 6296fd1b..00000000 --- a/tests/wpt/dom/collections/HTMLCollection-iterator.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - -HTMLCollection @@iterator Test - - -

-

-

-

-

- diff --git a/tests/wpt/dom/collections/HTMLCollection-live-mutations.window.js b/tests/wpt/dom/collections/HTMLCollection-live-mutations.window.js deleted file mode 100644 index 7dbfc6cc..00000000 --- a/tests/wpt/dom/collections/HTMLCollection-live-mutations.window.js +++ /dev/null @@ -1,93 +0,0 @@ -function testHTMLCollection(name, hooks) { - test(() => { - const nodes = { - root: document.createElement("div"), - div1: document.createElement("div"), - div2: document.createElement("div"), - p: document.createElement("p") - }; - - nodes.div1.id = "div1"; - nodes.div2.id = "div2"; - - const list = nodes.root.getElementsByTagName("div"); - - hooks.initial(list, nodes); - - nodes.root.appendChild(nodes.div1); - nodes.root.appendChild(nodes.p); - nodes.root.appendChild(nodes.div2); - - hooks.afterInsertion(list, nodes); - - nodes.root.removeChild(nodes.div1); - - hooks.afterRemoval(list, nodes); - }, `HTMLCollection live mutations: ${name}`); -} - -testHTMLCollection("HTMLCollection.length", { - initial(list) { - assert_equals(list.length, 0); - }, - afterInsertion(list) { - assert_equals(list.length, 2); - }, - afterRemoval(list) { - assert_equals(list.length, 1); - } -}); - -testHTMLCollection("HTMLCollection.item(index)", { - initial(list) { - assert_equals(list.item(0), null); - }, - afterInsertion(list, nodes) { - assert_equals(list.item(0), nodes.div1); - assert_equals(list.item(1), nodes.div2); - }, - afterRemoval(list, nodes) { - assert_equals(list.item(0), nodes.div2); - } -}); - -testHTMLCollection("HTMLCollection[index]", { - initial(list) { - assert_equals(list[0], undefined); - }, - afterInsertion(list, nodes) { - assert_equals(list[0], nodes.div1); - assert_equals(list[1], nodes.div2); - }, - afterRemoval(list, nodes) { - assert_equals(list[0], nodes.div2); - } -}); - -testHTMLCollection("HTMLCollection.namedItem(index)", { - initial(list) { - assert_equals(list.namedItem("div1"), null); - assert_equals(list.namedItem("div2"), null); - }, - afterInsertion(list, nodes) { - assert_equals(list.namedItem("div1"), nodes.div1); - assert_equals(list.namedItem("div2"), nodes.div2); - }, - afterRemoval(list, nodes) { - assert_equals(list.namedItem("div1"), null); - assert_equals(list.namedItem("div2"), nodes.div2); - } -}); - -testHTMLCollection("HTMLCollection ownPropertyNames", { - initial(list) { - assert_object_equals(Object.getOwnPropertyNames(list), []); - }, - afterInsertion(list) { - assert_object_equals(Object.getOwnPropertyNames(list), ["0", "1", "div1", "div2"]); - }, - afterRemoval(list) { - assert_object_equals(Object.getOwnPropertyNames(list), ["0", "div2"]); - } -}); - diff --git a/tests/wpt/dom/collections/HTMLCollection-own-props.html b/tests/wpt/dom/collections/HTMLCollection-own-props.html deleted file mode 100644 index 99dc425d..00000000 --- a/tests/wpt/dom/collections/HTMLCollection-own-props.html +++ /dev/null @@ -1,109 +0,0 @@ - - -HTMLCollection getters and own properties - - -
- diff --git a/tests/wpt/dom/collections/HTMLCollection-supported-property-indices.html b/tests/wpt/dom/collections/HTMLCollection-supported-property-indices.html deleted file mode 100644 index 5339ec31..00000000 --- a/tests/wpt/dom/collections/HTMLCollection-supported-property-indices.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/wpt/dom/collections/HTMLCollection-supported-property-names.html b/tests/wpt/dom/collections/HTMLCollection-supported-property-names.html deleted file mode 100644 index 3d21e166..00000000 --- a/tests/wpt/dom/collections/HTMLCollection-supported-property-names.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - - -
- - - - - - - - - - - - - - - - - - diff --git a/tests/wpt/dom/collections/domstringmap-supported-property-names.html b/tests/wpt/dom/collections/domstringmap-supported-property-names.html deleted file mode 100644 index 430aa44c..00000000 --- a/tests/wpt/dom/collections/domstringmap-supported-property-names.html +++ /dev/null @@ -1,54 +0,0 @@ - - -DOMStringMap Test: Supported property names - - -
- -
Simple
- -
Simple
- -
- John Doe -
- -
Jane Doe
- -
Jim Doe
- - diff --git a/tests/wpt/dom/collections/namednodemap-supported-property-names.html b/tests/wpt/dom/collections/namednodemap-supported-property-names.html deleted file mode 100644 index 2c5dee4e..00000000 --- a/tests/wpt/dom/collections/namednodemap-supported-property-names.html +++ /dev/null @@ -1,30 +0,0 @@ - - -NamedNodeMap Test: Supported property names - - -
-
Simple
- - \ No newline at end of file diff --git a/tests/wpt/dom/nodes/ChildNode-after.html b/tests/wpt/dom/nodes/ChildNode-after.html deleted file mode 100644 index b5bf7ab5..00000000 --- a/tests/wpt/dom/nodes/ChildNode-after.html +++ /dev/null @@ -1,166 +0,0 @@ - - -ChildNode.after - - - - - diff --git a/tests/wpt/dom/nodes/DOMImplementation-createDocument-with-null-browsing-context-crash.html b/tests/wpt/dom/nodes/DOMImplementation-createDocument-with-null-browsing-context-crash.html deleted file mode 100644 index c9393d0a..00000000 --- a/tests/wpt/dom/nodes/DOMImplementation-createDocument-with-null-browsing-context-crash.html +++ /dev/null @@ -1,13 +0,0 @@ - - -DOMImplementation.createDocument() - - - - - - diff --git a/tests/wpt/dom/nodes/DOMImplementation-createDocument.html b/tests/wpt/dom/nodes/DOMImplementation-createDocument.html deleted file mode 100644 index 835002b4..00000000 --- a/tests/wpt/dom/nodes/DOMImplementation-createDocument.html +++ /dev/null @@ -1,170 +0,0 @@ - - -DOMImplementation.createDocument(namespace, qualifiedName, doctype) - - - - - - - - -
- diff --git a/tests/wpt/dom/nodes/DOMImplementation-createDocumentType.html b/tests/wpt/dom/nodes/DOMImplementation-createDocumentType.html deleted file mode 100644 index 8d23e66a..00000000 --- a/tests/wpt/dom/nodes/DOMImplementation-createDocumentType.html +++ /dev/null @@ -1,123 +0,0 @@ - - -DOMImplementation.createDocumentType(qualifiedName, publicId, systemId) - - - - - - - -
- diff --git a/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument-with-null-browsing-context-crash.html b/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument-with-null-browsing-context-crash.html deleted file mode 100644 index d0cd6f1f..00000000 --- a/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument-with-null-browsing-context-crash.html +++ /dev/null @@ -1,13 +0,0 @@ - - -DOMImplementation.createHTMLDocument() - - - - - - diff --git a/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument-with-saved-implementation.html b/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument-with-saved-implementation.html deleted file mode 100644 index bae22660..00000000 --- a/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument-with-saved-implementation.html +++ /dev/null @@ -1,16 +0,0 @@ - -DOMImplementation.createHTMLDocument - - - -
- diff --git a/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument.html b/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument.html deleted file mode 100644 index c6e0beaf..00000000 --- a/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument.html +++ /dev/null @@ -1,96 +0,0 @@ - - - -DOMImplementation.createHTMLDocument - - - - - - - - -
- diff --git a/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument.js b/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument.js deleted file mode 100644 index 3e7e9aa9..00000000 --- a/tests/wpt/dom/nodes/DOMImplementation-createHTMLDocument.js +++ /dev/null @@ -1,25 +0,0 @@ -function createHTMLDocuments(checkDoc) { - var tests = [ - ["", "", ""], - [null, "null", "null"], - [undefined, undefined, ""], - ["foo bar baz", "foo bar baz", "foo bar baz"], - ["foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz"], - ["foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz"], - ["foo\f\fbar baz", "foo\f\fbar baz", "foo bar baz"], - ["foo\r\rbar baz", "foo\r\rbar baz", "foo bar baz"], - ] - - tests.forEach(function(t, i) { - var title = t[0], expectedtitle = t[1], normalizedtitle = t[2] - test(function() { - var doc = document.implementation.createHTMLDocument(title); - checkDoc(doc, expectedtitle, normalizedtitle) - }, "createHTMLDocument test " + i + ": " + t.map(function(el) { return format_value(el) })) - }) - - test(function() { - var doc = document.implementation.createHTMLDocument(); - checkDoc(doc, undefined, "") - }, "Missing title argument"); -} diff --git a/tests/wpt/dom/nodes/DOMImplementation-hasFeature.html b/tests/wpt/dom/nodes/DOMImplementation-hasFeature.html deleted file mode 100644 index 637565a6..00000000 --- a/tests/wpt/dom/nodes/DOMImplementation-hasFeature.html +++ /dev/null @@ -1,155 +0,0 @@ - - -DOMImplementation.hasFeature(feature, version) - - - -
- diff --git a/tests/wpt/dom/nodes/Document-Element-getElementsByTagName.js b/tests/wpt/dom/nodes/Document-Element-getElementsByTagName.js deleted file mode 100644 index dbbe667f..00000000 --- a/tests/wpt/dom/nodes/Document-Element-getElementsByTagName.js +++ /dev/null @@ -1,208 +0,0 @@ -function test_getElementsByTagName(context, element) { - // TODO: getElementsByTagName("*") - test(function() { - assert_false(context.getElementsByTagName("html") instanceof NodeList, - "Should not return a NodeList") - assert_true(context.getElementsByTagName("html") instanceof HTMLCollection, - "Should return an HTMLCollection") - }, "Interfaces") - - test(function() { - var firstCollection = context.getElementsByTagName("html"), - secondCollection = context.getElementsByTagName("html") - assert_true(firstCollection !== secondCollection || - firstCollection === secondCollection) - }, "Caching is allowed") - - test(function() { - var l = context.getElementsByTagName("nosuchtag") - l[5] = "foopy" - assert_equals(l[5], undefined) - assert_equals(l.item(5), null) - }, "Shouldn't be able to set unsigned properties on a HTMLCollection (non-strict mode)") - - test(function() { - var l = context.getElementsByTagName("nosuchtag") - assert_throws_js(TypeError, function() { - "use strict"; - l[5] = "foopy" - }) - assert_equals(l[5], undefined) - assert_equals(l.item(5), null) - }, "Shouldn't be able to set unsigned properties on a HTMLCollection (strict mode)") - - test(function() { - var l = context.getElementsByTagName("nosuchtag") - var fn = l.item; - assert_equals(fn, HTMLCollection.prototype.item); - l.item = "pass" - assert_equals(l.item, "pass") - assert_equals(HTMLCollection.prototype.item, fn); - }, "Should be able to set expando shadowing a proto prop (item)") - - test(function() { - var l = context.getElementsByTagName("nosuchtag") - var fn = l.namedItem; - assert_equals(fn, HTMLCollection.prototype.namedItem); - l.namedItem = "pass" - assert_equals(l.namedItem, "pass") - assert_equals(HTMLCollection.prototype.namedItem, fn); - }, "Should be able to set expando shadowing a proto prop (namedItem)") - - test(function() { - var t1 = element.appendChild(document.createElement("pre")); - t1.id = "x"; - var t2 = element.appendChild(document.createElement("pre")); - t2.setAttribute("name", "y"); - var t3 = element.appendChild(document.createElementNS("", "pre")); - t3.setAttribute("id", "z"); - var t4 = element.appendChild(document.createElementNS("", "pre")); - t4.setAttribute("name", "w"); - this.add_cleanup(function() { - element.removeChild(t1) - element.removeChild(t2) - element.removeChild(t3) - element.removeChild(t4) - }); - - var list = context.getElementsByTagName('pre'); - var pre = list[0]; - assert_equals(pre.id, "x"); - - var exposedNames = { 'x': 0, 'y': 1, 'z': 2 }; - for (var exposedName in exposedNames) { - assert_equals(list[exposedName], list[exposedNames[exposedName]]); - assert_equals(list[exposedName], list.namedItem(exposedName)); - assert_true(exposedName in list, "'" + exposedName + "' in list"); - assert_true(list.hasOwnProperty(exposedName), - "list.hasOwnProperty('" + exposedName + "')"); - } - - var unexposedNames = ["w"]; - for (var unexposedName of unexposedNames) { - assert_false(unexposedName in list); - assert_false(list.hasOwnProperty(unexposedName)); - assert_equals(list[unexposedName], undefined); - assert_equals(list.namedItem(unexposedName), null); - } - - assert_array_equals(Object.getOwnPropertyNames(list).sort(), - ["0", "1", "2", "3", "x", "y", "z"]); - - var desc = Object.getOwnPropertyDescriptor(list, '0'); - assert_equals(typeof desc, "object", "descriptor should be an object"); - assert_true(desc.enumerable, "desc.enumerable"); - assert_true(desc.configurable, "desc.configurable"); - - desc = Object.getOwnPropertyDescriptor(list, 'x'); - assert_equals(typeof desc, "object", "descriptor should be an object"); - assert_false(desc.enumerable, "desc.enumerable"); - assert_true(desc.configurable, "desc.configurable"); - }, "hasOwnProperty, getOwnPropertyDescriptor, getOwnPropertyNames") - - test(function() { - assert_equals(document.createElementNS("http://www.w3.org/1999/xhtml", "i").localName, "i") // Sanity - var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "I")) - this.add_cleanup(function() {element.removeChild(t)}) - assert_equals(t.localName, "I") - assert_equals(t.tagName, "I") - assert_equals(context.getElementsByTagName("I").length, 0) - assert_equals(context.getElementsByTagName("i").length, 0) - }, "HTML element with uppercase tagName never matches in HTML Documents") - - test(function() { - var t = element.appendChild(document.createElementNS("test", "st")) - this.add_cleanup(function() {element.removeChild(t)}) - assert_array_equals(context.getElementsByTagName("st"), [t]) - assert_array_equals(context.getElementsByTagName("ST"), []) - }, "Element in non-HTML namespace, no prefix, lowercase name") - - test(function() { - var t = element.appendChild(document.createElementNS("test", "ST")) - this.add_cleanup(function() {element.removeChild(t)}) - assert_array_equals(context.getElementsByTagName("ST"), [t]) - assert_array_equals(context.getElementsByTagName("st"), []) - }, "Element in non-HTML namespace, no prefix, uppercase name") - - test(function() { - var t = element.appendChild(document.createElementNS("test", "te:st")) - this.add_cleanup(function() {element.removeChild(t)}) - assert_array_equals(context.getElementsByTagName("st"), []) - assert_array_equals(context.getElementsByTagName("ST"), []) - assert_array_equals(context.getElementsByTagName("te:st"), [t]) - assert_array_equals(context.getElementsByTagName("te:ST"), []) - }, "Element in non-HTML namespace, prefix, lowercase name") - - test(function() { - var t = element.appendChild(document.createElementNS("test", "te:ST")) - this.add_cleanup(function() {element.removeChild(t)}) - assert_array_equals(context.getElementsByTagName("st"), []) - assert_array_equals(context.getElementsByTagName("ST"), []) - assert_array_equals(context.getElementsByTagName("te:st"), []) - assert_array_equals(context.getElementsByTagName("te:ST"), [t]) - }, "Element in non-HTML namespace, prefix, uppercase name") - - test(function() { - var t = element.appendChild(document.createElement("aÇ")) - this.add_cleanup(function() {element.removeChild(t)}) - assert_equals(t.localName, "aÇ") - assert_array_equals(context.getElementsByTagName("AÇ"), [t], "All uppercase input") - assert_array_equals(context.getElementsByTagName("aÇ"), [t], "Ascii lowercase input") - assert_array_equals(context.getElementsByTagName("aç"), [], "All lowercase input") - }, "Element in HTML namespace, no prefix, non-ascii characters in name") - - test(function() { - var t = element.appendChild(document.createElementNS("test", "AÇ")) - this.add_cleanup(function() {element.removeChild(t)}) - assert_array_equals(context.getElementsByTagName("AÇ"), [t]) - assert_array_equals(context.getElementsByTagName("aÇ"), []) - assert_array_equals(context.getElementsByTagName("aç"), []) - }, "Element in non-HTML namespace, non-ascii characters in name") - - test(function() { - var t = element.appendChild(document.createElementNS("http://www.w3.org/1999/xhtml", "test:aÇ")) - this.add_cleanup(function() {element.removeChild(t)}) - assert_array_equals(context.getElementsByTagName("TEST:AÇ"), [t], "All uppercase input") - assert_array_equals(context.getElementsByTagName("test:aÇ"), [t], "Ascii lowercase input") - assert_array_equals(context.getElementsByTagName("test:aç"), [], "All lowercase input") - }, "Element in HTML namespace, prefix, non-ascii characters in name") - - test(function() { - var t = element.appendChild(document.createElementNS("test", "TEST:AÇ")) - this.add_cleanup(function() {element.removeChild(t)}) - assert_array_equals(context.getElementsByTagName("TEST:AÇ"), [t], "All uppercase input") - assert_array_equals(context.getElementsByTagName("test:aÇ"), [], "Ascii lowercase input") - assert_array_equals(context.getElementsByTagName("test:aç"), [], "All lowercase input") - }, "Element in non-HTML namespace, prefix, non-ascii characters in name") - - test(function() { - var actual = context.getElementsByTagName("*"); - var expected = []; - var get_elements = function(node) { - for (var i = 0; i < node.childNodes.length; i++) { - var child = node.childNodes[i]; - if (child.nodeType === child.ELEMENT_NODE) { - expected.push(child); - get_elements(child); - } - } - } - get_elements(context); - assert_array_equals(actual, expected); - }, "getElementsByTagName('*')") - - test(function() { - var t1 = element.appendChild(document.createElement("abc")); - this.add_cleanup(function() {element.removeChild(t1)}); - - var l = context.getElementsByTagName("abc"); - assert_true(l instanceof HTMLCollection); - assert_equals(l.length, 1); - - var t2 = element.appendChild(document.createElement("abc")); - assert_equals(l.length, 2); - - element.removeChild(t2); - assert_equals(l.length, 1); - }, "getElementsByTagName() should be a live collection"); -} diff --git a/tests/wpt/dom/nodes/Document-adoptNode.html b/tests/wpt/dom/nodes/Document-adoptNode.html deleted file mode 100644 index 60a4e677..00000000 --- a/tests/wpt/dom/nodes/Document-adoptNode.html +++ /dev/null @@ -1,50 +0,0 @@ - - -Document.adoptNode - - - -
-x - diff --git a/tests/wpt/dom/nodes/Document-createAttribute.html b/tests/wpt/dom/nodes/Document-createAttribute.html deleted file mode 100644 index b3dc8b60..00000000 --- a/tests/wpt/dom/nodes/Document-createAttribute.html +++ /dev/null @@ -1,55 +0,0 @@ - - -Document.createAttribute - - - - -
- diff --git a/tests/wpt/dom/nodes/Document-createCDATASection-xhtml.xhtml b/tests/wpt/dom/nodes/Document-createCDATASection-xhtml.xhtml deleted file mode 100644 index b0a5a7f2..00000000 --- a/tests/wpt/dom/nodes/Document-createCDATASection-xhtml.xhtml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - document.createCDATASection - - - - - - - - - - diff --git a/tests/wpt/dom/nodes/Document-createCDATASection.html b/tests/wpt/dom/nodes/Document-createCDATASection.html deleted file mode 100644 index 72b3684c..00000000 --- a/tests/wpt/dom/nodes/Document-createCDATASection.html +++ /dev/null @@ -1,16 +0,0 @@ - - -document.createCDATASection must throw in HTML documents - - - - - diff --git a/tests/wpt/dom/nodes/Document-createComment-createTextNode.js b/tests/wpt/dom/nodes/Document-createComment-createTextNode.js deleted file mode 100644 index 62a38d38..00000000 --- a/tests/wpt/dom/nodes/Document-createComment-createTextNode.js +++ /dev/null @@ -1,22 +0,0 @@ -function test_create(method, iface, nodeType, nodeName) { - ["\u000b", "a -- b", "a-", "-b", null, undefined].forEach(function(value) { - test(function() { - var c = document[method](value); - var expected = String(value); - assert_true(c instanceof iface); - assert_true(c instanceof CharacterData); - assert_true(c instanceof Node); - assert_equals(c.ownerDocument, document); - assert_equals(c.data, expected, "data"); - assert_equals(c.nodeValue, expected, "nodeValue"); - assert_equals(c.textContent, expected, "textContent"); - assert_equals(c.length, expected.length); - assert_equals(c.nodeType, nodeType); - assert_equals(c.nodeName, nodeName); - assert_equals(c.hasChildNodes(), false); - assert_equals(c.childNodes.length, 0); - assert_equals(c.firstChild, null); - assert_equals(c.lastChild, null); - }, method + "(" + format_value(value) + ")"); - }); -} diff --git a/tests/wpt/dom/nodes/Document-createComment.html b/tests/wpt/dom/nodes/Document-createComment.html deleted file mode 100644 index a175c3a2..00000000 --- a/tests/wpt/dom/nodes/Document-createComment.html +++ /dev/null @@ -1,21 +0,0 @@ - - -Document.createComment - - - - - - - - - - - - - - -
- diff --git a/tests/wpt/dom/nodes/Document-createElement.html b/tests/wpt/dom/nodes/Document-createElement.html deleted file mode 100644 index 93435ac8..00000000 --- a/tests/wpt/dom/nodes/Document-createElement.html +++ /dev/null @@ -1,158 +0,0 @@ - - -Document.createElement - - - - - - - -
- - - diff --git a/tests/wpt/dom/nodes/Document-createElementNS.html b/tests/wpt/dom/nodes/Document-createElementNS.html deleted file mode 100644 index 5ad81043..00000000 --- a/tests/wpt/dom/nodes/Document-createElementNS.html +++ /dev/null @@ -1,224 +0,0 @@ - - -Document.createElementNS - - - - -
- - - diff --git a/tests/wpt/dom/nodes/Document-createElementNS.js b/tests/wpt/dom/nodes/Document-createElementNS.js deleted file mode 100644 index 2cf29485..00000000 --- a/tests/wpt/dom/nodes/Document-createElementNS.js +++ /dev/null @@ -1,189 +0,0 @@ -var createElementNS_tests = [ - /* Arrays with three elements: - * the namespace argument - * the qualifiedName argument - * the expected exception, or null if none - */ - [null, null, null], - [null, undefined, null], - [null, "foo", null], - [null, "1foo", "INVALID_CHARACTER_ERR"], - [null, "f1oo", null], - [null, "foo1", null], - [null, "\u0BC6foo", null], - [null, "\u037Efoo", "INVALID_CHARACTER_ERR"], - [null, "}foo", "INVALID_CHARACTER_ERR"], - [null, "f}oo", "INVALID_CHARACTER_ERR"], - [null, "foo}", "INVALID_CHARACTER_ERR"], - [null, "\uFFFFfoo", "INVALID_CHARACTER_ERR"], - [null, "f\uFFFFoo", "INVALID_CHARACTER_ERR"], - [null, "foo\uFFFF", "INVALID_CHARACTER_ERR"], - [null, "", "INVALID_CHARACTER_ERR"], - [null, "", "INVALID_CHARACTER_ERR"], - [null, "f", "INVALID_CHARACTER_ERR"], - ["http://example.com/", "fo", "INVALID_CHARACTER_ERR"], - ["http://example.com/", "namespaceURI:,", "INVALID_CHARACTER_ERR"], - ["http://example.com/", "namespaceURI:a ", "INVALID_CHARACTER_ERR"], - ["http://example.com/", "namespaceURI:\"", "INVALID_CHARACTER_ERR"], - ["/", "foo", null], - ["/", "1foo", "INVALID_CHARACTER_ERR"], - ["/", "f1oo", null], - ["/", "foo1", null], - ["/", ":foo", "INVALID_CHARACTER_ERR"], - ["/", "f:oo", null], - ["/", "foo:", "INVALID_CHARACTER_ERR"], - ["/", "xml", null], - ["/", "xmlns", "NAMESPACE_ERR"], - ["/", "xmlfoo", null], - ["/", "xml:foo", "NAMESPACE_ERR"], - ["/", "xmlns:foo", "NAMESPACE_ERR"], - ["/", "xmlfoo:bar", null], - ["http://www.w3.org/XML/1998/namespace", "foo", null], - ["http://www.w3.org/XML/1998/namespace", "1foo", "INVALID_CHARACTER_ERR"], - ["http://www.w3.org/XML/1998/namespace", "f1oo", null], - ["http://www.w3.org/XML/1998/namespace", "foo1", null], - ["http://www.w3.org/XML/1998/namespace", ":foo", "INVALID_CHARACTER_ERR"], - ["http://www.w3.org/XML/1998/namespace", "f:oo", null], - ["http://www.w3.org/XML/1998/namespace", "foo:", "INVALID_CHARACTER_ERR"], - ["http://www.w3.org/XML/1998/namespace", "xml", null], - ["http://www.w3.org/XML/1998/namespace", "xmlns", "NAMESPACE_ERR"], - ["http://www.w3.org/XML/1998/namespace", "xmlfoo", null], - ["http://www.w3.org/XML/1998/namespace", "xml:foo", null], - ["http://www.w3.org/XML/1998/namespace", "xmlns:foo", "NAMESPACE_ERR"], - ["http://www.w3.org/XML/1998/namespace", "xmlfoo:bar", null], - ["http://www.w3.org/XML/1998/namespaces", "xml:foo", "NAMESPACE_ERR"], - ["http://www.w3.org/xml/1998/namespace", "xml:foo", "NAMESPACE_ERR"], - ["http://www.w3.org/2000/xmlns/", "foo", "NAMESPACE_ERR"], - ["http://www.w3.org/2000/xmlns/", "1foo", "INVALID_CHARACTER_ERR"], - ["http://www.w3.org/2000/xmlns/", "f1oo", "NAMESPACE_ERR"], - ["http://www.w3.org/2000/xmlns/", "foo1", "NAMESPACE_ERR"], - ["http://www.w3.org/2000/xmlns/", ":foo", "INVALID_CHARACTER_ERR"], - ["http://www.w3.org/2000/xmlns/", "f:oo", "NAMESPACE_ERR"], - ["http://www.w3.org/2000/xmlns/", "foo:", "INVALID_CHARACTER_ERR"], - ["http://www.w3.org/2000/xmlns/", "xml", "NAMESPACE_ERR"], - ["http://www.w3.org/2000/xmlns/", "xmlns", null], - ["http://www.w3.org/2000/xmlns/", "xmlfoo", "NAMESPACE_ERR"], - ["http://www.w3.org/2000/xmlns/", "xml:foo", "NAMESPACE_ERR"], - ["http://www.w3.org/2000/xmlns/", "xmlns:foo", null], - ["http://www.w3.org/2000/xmlns/", "xmlfoo:bar", "NAMESPACE_ERR"], - ["http://www.w3.org/2000/xmlns/", "foo:xmlns", "NAMESPACE_ERR"], - ["foo:", "foo", null], - ["foo:", "1foo", "INVALID_CHARACTER_ERR"], - ["foo:", "f1oo", null], - ["foo:", "foo1", null], - ["foo:", ":foo", "INVALID_CHARACTER_ERR"], - ["foo:", "f:oo", null], - ["foo:", "foo:", "INVALID_CHARACTER_ERR"], - ["foo:", "xml", null], - ["foo:", "xmlns", "NAMESPACE_ERR"], - ["foo:", "xmlfoo", null], - ["foo:", "xml:foo", "NAMESPACE_ERR"], - ["foo:", "xmlns:foo", "NAMESPACE_ERR"], - ["foo:", "xmlfoo:bar", null], -] diff --git a/tests/wpt/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml b/tests/wpt/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml deleted file mode 100644 index d06f70fd..00000000 --- a/tests/wpt/dom/nodes/Document-createProcessingInstruction-xhtml.xhtml +++ /dev/null @@ -1,15 +0,0 @@ - - -Document.createProcessingInstruction in XML documents - - - - - - - - -
- - -
- diff --git a/tests/wpt/dom/nodes/Document-createProcessingInstruction.js b/tests/wpt/dom/nodes/Document-createProcessingInstruction.js deleted file mode 100644 index d6cc3725..00000000 --- a/tests/wpt/dom/nodes/Document-createProcessingInstruction.js +++ /dev/null @@ -1,39 +0,0 @@ -test(function() { - var invalid = [ - ["A", "?>"], - ["\u00B7A", "x"], - ["\u00D7A", "x"], - ["A\u00D7", "x"], - ["\\A", "x"], - ["\f", "x"], - [0, "x"], - ["0", "x"] - ], - valid = [ - ["xml:fail", "x"], - ["A\u00B7A", "x"], - ["a0", "x"] - ] - - for (var i = 0, il = invalid.length; i < il; i++) { - test(function() { - assert_throws_dom("INVALID_CHARACTER_ERR", function() { - document.createProcessingInstruction(invalid[i][0], invalid[i][1]) - }) - }, "Should throw an INVALID_CHARACTER_ERR for target " + - format_value(invalid[i][0]) + " and data " + - format_value(invalid[i][1]) + ".") - } - for (var i = 0, il = valid.length; i < il; ++i) { - test(function() { - var pi = document.createProcessingInstruction(valid[i][0], valid[i][1]); - assert_equals(pi.target, valid[i][0]); - assert_equals(pi.data, valid[i][1]); - assert_equals(pi.ownerDocument, document); - assert_true(pi instanceof ProcessingInstruction); - assert_true(pi instanceof Node); - }, "Should get a ProcessingInstruction for target " + - format_value(valid[i][0]) + " and data " + - format_value(valid[i][1]) + ".") - } -}) diff --git a/tests/wpt/dom/nodes/Document-createTextNode.html b/tests/wpt/dom/nodes/Document-createTextNode.html deleted file mode 100644 index ccc1b1b7..00000000 --- a/tests/wpt/dom/nodes/Document-createTextNode.html +++ /dev/null @@ -1,21 +0,0 @@ - - -Document.createTextNode - - - - - - - - - - - - - - -
- diff --git a/tests/wpt/dom/nodes/Document-doctype.html b/tests/wpt/dom/nodes/Document-doctype.html deleted file mode 100644 index 75bfd850..00000000 --- a/tests/wpt/dom/nodes/Document-doctype.html +++ /dev/null @@ -1,21 +0,0 @@ - - - -Document.doctype - - - -
- diff --git a/tests/wpt/dom/nodes/Document-getElementsByClassName.html b/tests/wpt/dom/nodes/Document-getElementsByClassName.html deleted file mode 100644 index db8fac21..00000000 --- a/tests/wpt/dom/nodes/Document-getElementsByClassName.html +++ /dev/null @@ -1,26 +0,0 @@ - -Document.getElementsByClassName - - - -
- diff --git a/tests/wpt/dom/nodes/Document-getElementsByTagName.html b/tests/wpt/dom/nodes/Document-getElementsByTagName.html deleted file mode 100644 index 00e3435c..00000000 --- a/tests/wpt/dom/nodes/Document-getElementsByTagName.html +++ /dev/null @@ -1,11 +0,0 @@ - - -Document.getElementsByTagName - - - - -
- diff --git a/tests/wpt/dom/nodes/Document-importNode.html b/tests/wpt/dom/nodes/Document-importNode.html deleted file mode 100644 index d27cce6c..00000000 --- a/tests/wpt/dom/nodes/Document-importNode.html +++ /dev/null @@ -1,67 +0,0 @@ - - -Document.importNode - - - -
- diff --git a/tests/wpt/dom/nodes/DocumentFragment-constructor.html b/tests/wpt/dom/nodes/DocumentFragment-constructor.html deleted file mode 100644 index e97a7c48..00000000 --- a/tests/wpt/dom/nodes/DocumentFragment-constructor.html +++ /dev/null @@ -1,22 +0,0 @@ - - -DocumentFragment constructor - - - - - diff --git a/tests/wpt/dom/nodes/DocumentFragment-getElementById.html b/tests/wpt/dom/nodes/DocumentFragment-getElementById.html deleted file mode 100644 index ce0d302c..00000000 --- a/tests/wpt/dom/nodes/DocumentFragment-getElementById.html +++ /dev/null @@ -1,62 +0,0 @@ - - -DocumentFragment.prototype.getElementById - - - - - - - - - diff --git a/tests/wpt/dom/nodes/DocumentFragment-querySelectorAll-after-modification.html b/tests/wpt/dom/nodes/DocumentFragment-querySelectorAll-after-modification.html deleted file mode 100644 index 80493638..00000000 --- a/tests/wpt/dom/nodes/DocumentFragment-querySelectorAll-after-modification.html +++ /dev/null @@ -1,24 +0,0 @@ - - -querySelectorAll should still work on DocumentFragments after they are modified - - - - - diff --git a/tests/wpt/dom/nodes/DocumentType-literal.html b/tests/wpt/dom/nodes/DocumentType-literal.html deleted file mode 100644 index a755c397..00000000 --- a/tests/wpt/dom/nodes/DocumentType-literal.html +++ /dev/null @@ -1,17 +0,0 @@ - -DocumentType literals - - - - - -
- diff --git a/tests/wpt/dom/nodes/Element-childElement-null-svg.svg b/tests/wpt/dom/nodes/Element-childElement-null-svg.svg deleted file mode 100644 index 38848287..00000000 --- a/tests/wpt/dom/nodes/Element-childElement-null-svg.svg +++ /dev/null @@ -1,20 +0,0 @@ - - -Null test - - - -Test of firstElementChild and lastChildElement returning null -Test - - -test(function() { - var parentEl = document.getElementById("parentEl") - assert_equals(parentEl.firstElementChild, null) - assert_equals(parentEl.lastElementChild, null) -}) - - diff --git a/tests/wpt/dom/nodes/Element-childElement-null-xhtml.xhtml b/tests/wpt/dom/nodes/Element-childElement-null-xhtml.xhtml deleted file mode 100644 index daedab6d..00000000 --- a/tests/wpt/dom/nodes/Element-childElement-null-xhtml.xhtml +++ /dev/null @@ -1,20 +0,0 @@ - - - -Null Test - - - - -

Test of firstElementChild and lastChildElement returning null

-
-

Test.

- - - diff --git a/tests/wpt/dom/nodes/Element-childElement-null.html b/tests/wpt/dom/nodes/Element-childElement-null.html deleted file mode 100644 index 1863a41d..00000000 --- a/tests/wpt/dom/nodes/Element-childElement-null.html +++ /dev/null @@ -1,15 +0,0 @@ - - -Null test - - -

Test of firstElementChild and lastChildElement returning null

-
-

Test.

- diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-svg.svg b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-svg.svg deleted file mode 100644 index d149f1ea..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-svg.svg +++ /dev/null @@ -1,22 +0,0 @@ - - -Dynamic Adding of Elements - - - -Test of Dynamic Adding of Elements -The result of this test is -unknown. - - -test(function() { - var parentEl = document.getElementById("parentEl"); - var newChild = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); - parentEl.appendChild(newChild); - assert_equals(parentEl.childElementCount, 2) -}) - - diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-xhtml.xhtml b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-xhtml.xhtml deleted file mode 100644 index c97ed196..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add-xhtml.xhtml +++ /dev/null @@ -1,22 +0,0 @@ - - - -Dynamic Adding of Elements - - - - -

Test of Dynamic Adding of Elements

-
-

The result of this test is -logged above.

- - - diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add.html b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add.html deleted file mode 100644 index 3e7490b2..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-add.html +++ /dev/null @@ -1,17 +0,0 @@ - - -Dynamic Adding of Elements - - -

Test of Dynamic Adding of Elements

-
-

The result of this test is -logged above.

- diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-svg.svg b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-svg.svg deleted file mode 100644 index bf99de65..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-svg.svg +++ /dev/null @@ -1,22 +0,0 @@ - - -Dynamic Removal of Elements - - - -Test of Dynamic Removal of Elements -The result of this test is -unknown. - - -test(function() { - var parentEl = document.getElementById("parentEl"); - var lec = parentEl.lastElementChild; - parentEl.removeChild(lec); - assert_equals(parentEl.childElementCount, 1) -}) - - diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-xhtml.xhtml b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-xhtml.xhtml deleted file mode 100644 index f0009b0a..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove-xhtml.xhtml +++ /dev/null @@ -1,22 +0,0 @@ - - - -Dynamic Removal of Elements - - - - -

Test of Removal Adding of Elements

-
-

The result of this test is -logged above.

- - - diff --git a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove.html b/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove.html deleted file mode 100644 index 3f7e7c7e..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount-dynamic-remove.html +++ /dev/null @@ -1,17 +0,0 @@ - - -Dynamic Removal of Elements - - -

Test of Dynamic Removal of Elements

-
-

The result of this test is -unknown.

- diff --git a/tests/wpt/dom/nodes/Element-childElementCount-nochild-svg.svg b/tests/wpt/dom/nodes/Element-childElementCount-nochild-svg.svg deleted file mode 100644 index 8ba57436..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount-nochild-svg.svg +++ /dev/null @@ -1,19 +0,0 @@ - - -childElementCount - - - -Test of childElementCount with No Child Element Nodes -Test - - -test(function() { - var parentEl = document.getElementById("parentEl") - assert_equals(parentEl.childElementCount, 0) -}) - - diff --git a/tests/wpt/dom/nodes/Element-childElementCount-nochild-xhtml.xhtml b/tests/wpt/dom/nodes/Element-childElementCount-nochild-xhtml.xhtml deleted file mode 100644 index f567a20c..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount-nochild-xhtml.xhtml +++ /dev/null @@ -1,19 +0,0 @@ - - - -childElementCount without Child Element Nodes - - - - -

Test of childElementCount with No Child Element Nodes

-
-

Test.

- - - diff --git a/tests/wpt/dom/nodes/Element-childElementCount-nochild.html b/tests/wpt/dom/nodes/Element-childElementCount-nochild.html deleted file mode 100644 index fb52fb20..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount-nochild.html +++ /dev/null @@ -1,14 +0,0 @@ - - -childElementCount without Child Element Nodes - - -

Test of childElementCount with No Child Element Nodes

-
-

Test.

- diff --git a/tests/wpt/dom/nodes/Element-childElementCount-svg.svg b/tests/wpt/dom/nodes/Element-childElementCount-svg.svg deleted file mode 100644 index ff93eff6..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount-svg.svg +++ /dev/null @@ -1,25 +0,0 @@ - - -childElementCount - - - -Test of childElementCount -The result of this test is -unknown. - - - - - - -test(function() { - var parentEl = document.getElementById("parentEl") - assert_true("childElementCount" in parentEl) - assert_equals(parentEl.childElementCount, 3) -}) - - diff --git a/tests/wpt/dom/nodes/Element-childElementCount-xhtml.xhtml b/tests/wpt/dom/nodes/Element-childElementCount-xhtml.xhtml deleted file mode 100644 index 6b719ff7..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount-xhtml.xhtml +++ /dev/null @@ -1,25 +0,0 @@ - - - -childElementCount - - - - -

Test of childElementCount

-
-

The result of this test is -unknown. - - - -

- - - diff --git a/tests/wpt/dom/nodes/Element-childElementCount.html b/tests/wpt/dom/nodes/Element-childElementCount.html deleted file mode 100644 index 8cfe567f..00000000 --- a/tests/wpt/dom/nodes/Element-childElementCount.html +++ /dev/null @@ -1,20 +0,0 @@ - - -childElementCount - - -

Test of childElementCount

-
-

The result of this test is -given above. - - - -

- diff --git a/tests/wpt/dom/nodes/Element-children.html b/tests/wpt/dom/nodes/Element-children.html deleted file mode 100644 index c0210f96..00000000 --- a/tests/wpt/dom/nodes/Element-children.html +++ /dev/null @@ -1,58 +0,0 @@ - -HTMLCollection edge cases - - -
-
- diff --git a/tests/wpt/dom/nodes/Element-classlist.html b/tests/wpt/dom/nodes/Element-classlist.html deleted file mode 100644 index 2b5a271b..00000000 --- a/tests/wpt/dom/nodes/Element-classlist.html +++ /dev/null @@ -1,478 +0,0 @@ - - -Test for the classList element attribute - - -
- diff --git a/tests/wpt/dom/nodes/Element-closest.html b/tests/wpt/dom/nodes/Element-closest.html deleted file mode 100644 index 386e3bd2..00000000 --- a/tests/wpt/dom/nodes/Element-closest.html +++ /dev/null @@ -1,73 +0,0 @@ - - -Test for Element.closest - - - - -
- diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-entity-xhtml.xhtml b/tests/wpt/dom/nodes/Element-firstElementChild-entity-xhtml.xhtml deleted file mode 100644 index f28005e9..00000000 --- a/tests/wpt/dom/nodes/Element-firstElementChild-entity-xhtml.xhtml +++ /dev/null @@ -1,27 +0,0 @@ - -unknown."> -]> - - -Entity References - - - - -

Test of Entity References

-
-

The result of this test is &tree;

- - - diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-entity.svg b/tests/wpt/dom/nodes/Element-firstElementChild-entity.svg deleted file mode 100644 index 3a20ea79..00000000 --- a/tests/wpt/dom/nodes/Element-firstElementChild-entity.svg +++ /dev/null @@ -1,26 +0,0 @@ - -unknown."> -]> - -Entity References - - - -Test of Entity References -The result of this test is &tree; - - -test(function() { - var parentEl = document.getElementById("parentEl") - var fec = parentEl.firstElementChild; - assert_true(!!fec) - assert_equals(fec.nodeType, 1) - assert_equals(fec.getAttribute("id"), "first_element_child") -}) - - diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-namespace-svg.svg b/tests/wpt/dom/nodes/Element-firstElementChild-namespace-svg.svg deleted file mode 100644 index d42c0877..00000000 --- a/tests/wpt/dom/nodes/Element-firstElementChild-namespace-svg.svg +++ /dev/null @@ -1,26 +0,0 @@ - - -firstElementChild with namespaces - - - -Test of firstElementChild with namespaces - - - - - -test(function() { - var parentEl = document.getElementById("parentEl"); - var fec = parentEl.firstElementChild; - assert_true(!!fec) - assert_equals(fec.nodeType, 1) - assert_equals(fec.getAttribute("id"), "first_element_child") - assert_equals(fec.localName, "dill") -}) - - diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-namespace-xhtml.xhtml b/tests/wpt/dom/nodes/Element-firstElementChild-namespace-xhtml.xhtml deleted file mode 100644 index 29441d27..00000000 --- a/tests/wpt/dom/nodes/Element-firstElementChild-namespace-xhtml.xhtml +++ /dev/null @@ -1,28 +0,0 @@ - - - -firstElementChild with namespaces - - - - -

Test of firstElementChild with namespaces

-
- -
-
-

The result of this test is -logged above.

- - - diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-namespace.html b/tests/wpt/dom/nodes/Element-firstElementChild-namespace.html deleted file mode 100644 index 629deab3..00000000 --- a/tests/wpt/dom/nodes/Element-firstElementChild-namespace.html +++ /dev/null @@ -1,21 +0,0 @@ - - -firstElementChild with namespaces - - -

Test of firstElementChild with namespaces

-
-

The result of this test is a unknown.

- diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-svg.svg b/tests/wpt/dom/nodes/Element-firstElementChild-svg.svg deleted file mode 100644 index 359c5b82..00000000 --- a/tests/wpt/dom/nodes/Element-firstElementChild-svg.svg +++ /dev/null @@ -1,23 +0,0 @@ - - -firstElementChild - - - -Test of firstElementChild -The result of this test is -unknown. - - -test(function() { - var parentEl = document.getElementById("parentEl"); - var fec = parentEl.firstElementChild; - assert_true(!!fec) - assert_equals(fec.nodeType, 1) - assert_equals(fec.getAttribute("id"), "first_element_child") -}) - - diff --git a/tests/wpt/dom/nodes/Element-firstElementChild-xhtml.xhtml b/tests/wpt/dom/nodes/Element-firstElementChild-xhtml.xhtml deleted file mode 100644 index 302052b0..00000000 --- a/tests/wpt/dom/nodes/Element-firstElementChild-xhtml.xhtml +++ /dev/null @@ -1,23 +0,0 @@ - - - -firstElementChild - - - - -

Test of firstElementChild

-
-

The result of this test is -logged above.

- - - diff --git a/tests/wpt/dom/nodes/Element-firstElementChild.html b/tests/wpt/dom/nodes/Element-firstElementChild.html deleted file mode 100644 index 12a0c594..00000000 --- a/tests/wpt/dom/nodes/Element-firstElementChild.html +++ /dev/null @@ -1,18 +0,0 @@ - - -firstElementChild - - -

Test of firstElementChild

-
-

The result of this test is -logged above.

- diff --git a/tests/wpt/dom/nodes/Element-getElementsByClassName.html b/tests/wpt/dom/nodes/Element-getElementsByClassName.html deleted file mode 100644 index bc87b05d..00000000 --- a/tests/wpt/dom/nodes/Element-getElementsByClassName.html +++ /dev/null @@ -1,43 +0,0 @@ - -Element.getElementsByClassName - - -
- diff --git a/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.xml b/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.xml deleted file mode 100644 index f3f286ea..00000000 --- a/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess-iframe.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html b/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html deleted file mode 100644 index c41ee2e8..00000000 --- a/tests/wpt/dom/nodes/Element-getElementsByTagName-change-document-HTMLNess.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - diff --git a/tests/wpt/dom/nodes/Element-getElementsByTagName.html b/tests/wpt/dom/nodes/Element-getElementsByTagName.html deleted file mode 100644 index 87c4fe93..00000000 --- a/tests/wpt/dom/nodes/Element-getElementsByTagName.html +++ /dev/null @@ -1,30 +0,0 @@ - - -Element.getElementsByTagName - - - - -
- diff --git a/tests/wpt/dom/nodes/Element-getElementsByTagNameNS.html b/tests/wpt/dom/nodes/Element-getElementsByTagNameNS.html deleted file mode 100644 index f826afc3..00000000 --- a/tests/wpt/dom/nodes/Element-getElementsByTagNameNS.html +++ /dev/null @@ -1,37 +0,0 @@ - - -Element.getElementsByTagNameNS - - - - -
- diff --git a/tests/wpt/dom/nodes/Element-hasAttribute.html b/tests/wpt/dom/nodes/Element-hasAttribute.html deleted file mode 100644 index 26528d75..00000000 --- a/tests/wpt/dom/nodes/Element-hasAttribute.html +++ /dev/null @@ -1,32 +0,0 @@ - - -Element.prototype.hasAttribute - - - - - - - diff --git a/tests/wpt/dom/nodes/Element-hasAttributes.html b/tests/wpt/dom/nodes/Element-hasAttributes.html deleted file mode 100644 index fbb9c233..00000000 --- a/tests/wpt/dom/nodes/Element-hasAttributes.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - -
-

- - - diff --git a/tests/wpt/dom/nodes/Element-insertAdjacentElement.html b/tests/wpt/dom/nodes/Element-insertAdjacentElement.html deleted file mode 100644 index 9eafee6a..00000000 --- a/tests/wpt/dom/nodes/Element-insertAdjacentElement.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - -
-
-
- - - - - diff --git a/tests/wpt/dom/nodes/Element-insertAdjacentText.html b/tests/wpt/dom/nodes/Element-insertAdjacentText.html deleted file mode 100644 index be744fd4..00000000 --- a/tests/wpt/dom/nodes/Element-insertAdjacentText.html +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - -
-
-
- - diff --git a/tests/wpt/dom/nodes/Element-lastElementChild-svg.svg b/tests/wpt/dom/nodes/Element-lastElementChild-svg.svg deleted file mode 100644 index 1cec4a13..00000000 --- a/tests/wpt/dom/nodes/Element-lastElementChild-svg.svg +++ /dev/null @@ -1,22 +0,0 @@ - - -lastElementChild - - - -Test of lastElementChild -The result of this test is not known. - - -test(function() { - var parentEl = document.getElementById("parentEl"); - var lec = parentEl.lastElementChild; - assert_true(!!lec) - assert_equals(lec.nodeType, 1) - assert_equals(lec.getAttribute("id"), "last_element_child") -}) - - diff --git a/tests/wpt/dom/nodes/Element-lastElementChild-xhtml.xhtml b/tests/wpt/dom/nodes/Element-lastElementChild-xhtml.xhtml deleted file mode 100644 index 3150b92a..00000000 --- a/tests/wpt/dom/nodes/Element-lastElementChild-xhtml.xhtml +++ /dev/null @@ -1,22 +0,0 @@ - - - -firstElementChild - - - - -

Test of firstElementChild

-
-

The result of this test is logged above.

- - - diff --git a/tests/wpt/dom/nodes/Element-lastElementChild.html b/tests/wpt/dom/nodes/Element-lastElementChild.html deleted file mode 100644 index de7aebdf..00000000 --- a/tests/wpt/dom/nodes/Element-lastElementChild.html +++ /dev/null @@ -1,17 +0,0 @@ - - -lastElementChild - - -

Test of lastElementChild

-
-

The result of this test is logged above.

- diff --git a/tests/wpt/dom/nodes/Element-matches-init.js b/tests/wpt/dom/nodes/Element-matches-init.js deleted file mode 100644 index 254af615..00000000 --- a/tests/wpt/dom/nodes/Element-matches-init.js +++ /dev/null @@ -1,65 +0,0 @@ -function init(e, method) { - /* - * 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 matches() tests are run - * 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 level2-lib.js file contains all the common test functions for running each of the aforementioned tests - */ - - var docType = "html"; // Only run tests suitable for HTML - - // Prepare the nodes for testing - var doc = e.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)); - - // Setup Tests - interfaceCheckMatches(method, "Document", doc); - interfaceCheckMatches(method, "Detached Element", detached); - interfaceCheckMatches(method, "Fragment", fragment); - interfaceCheckMatches(method, "In-document Element", element); - - runSpecialMatchesTests(method, "DIV Element", element); - runSpecialMatchesTests(method, "NULL Element", document.createElement("null")); - runSpecialMatchesTests(method, "UNDEFINED Element", document.createElement("undefined")); - - runInvalidSelectorTestMatches(method, "Document", doc, invalidSelectors); - runInvalidSelectorTestMatches(method, "Detached Element", detached, invalidSelectors); - runInvalidSelectorTestMatches(method, "Fragment", fragment, invalidSelectors); - runInvalidSelectorTestMatches(method, "In-document Element", element, invalidSelectors); - - runMatchesTest(method, "In-document", doc, validSelectors, "html"); - runMatchesTest(method, "Detached", detached, validSelectors, "html"); - runMatchesTest(method, "Fragment", fragment, validSelectors, "html"); - - runMatchesTest(method, "In-document", doc, scopedSelectors, "html"); -} diff --git a/tests/wpt/dom/nodes/Element-matches-namespaced-elements.html b/tests/wpt/dom/nodes/Element-matches-namespaced-elements.html deleted file mode 100644 index e61b11ca..00000000 --- a/tests/wpt/dom/nodes/Element-matches-namespaced-elements.html +++ /dev/null @@ -1,24 +0,0 @@ - - -matches/webkitMatchesSelector must work when an element has a namespace - - - - - diff --git a/tests/wpt/dom/nodes/Element-matches.html b/tests/wpt/dom/nodes/Element-matches.html deleted file mode 100644 index de234b66..00000000 --- a/tests/wpt/dom/nodes/Element-matches.html +++ /dev/null @@ -1,22 +0,0 @@ - - -Selectors-API Level 2 Test Suite: HTML with Selectors Level 3 - - - - - - - - - -
This test requires JavaScript.
- - diff --git a/tests/wpt/dom/nodes/Element-matches.js b/tests/wpt/dom/nodes/Element-matches.js deleted file mode 100644 index a1455c67..00000000 --- a/tests/wpt/dom/nodes/Element-matches.js +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Check that the matches() method exists on the given Node - */ -function interfaceCheckMatches(method, type, obj) { - if (obj.nodeType === obj.ELEMENT_NODE) { - test(function() { - assert_idl_attribute(obj, method, type + " supports " + method); - }, type + " supports " + method) - } else { - test(function() { - assert_false(method in obj, type + " supports " + method); - }, type + " should not support " + method) - } -} - -function runSpecialMatchesTests(method, type, element) { - test(function() { // 1 - if (element.tagName.toLowerCase() === "null") { - assert_true(element[method](null), "An element with the tag name '" + element.tagName.toLowerCase() + "' should match."); - } else { - assert_false(element[method](null), "An element with the tag name '" + element.tagName.toLowerCase() + "' should not match."); - } - }, type + "." + method + "(null)") - - test(function() { // 2 - if (element.tagName.toLowerCase() === "undefined") { - assert_true(element[method](undefined), "An element with the tag name '" + element.tagName.toLowerCase() + "' should match."); - } else { - assert_false(element[method](undefined), "An element with the tag name '" + element.tagName.toLowerCase() + "' should not match."); - } - }, type + "." + method + "(undefined)") - - test(function() { // 3 - assert_throws_js(element.ownerDocument.defaultView.TypeError, function() { - element[method](); - }, "This should throw a TypeError.") - }, type + "." + method + " no parameter") -} - -/* - * Execute queries with the specified invalid selectors for matches() - * Only run these tests when errors are expected. Don't run for valid selector tests. - */ -function runInvalidSelectorTestMatches(method, type, root, selectors) { - if (root.nodeType === root.ELEMENT_NODE) { - 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", - root.ownerDocument.defaultView.DOMException, - function() { - root[method](q) - } - ); - }, type + "." + method + ": " + n + ": " + q); - } - } -} - -function runMatchesTest(method, type, root, selectors, docType) { - var nodeType = getNodeType(root); - - for (var i = 0; i < selectors.length; i++) { - var s = selectors[i]; - var n = s["name"]; - var q = s["selector"]; - var e = s["expect"]; - var u = s["unexpected"]; - - var ctx = s["ctx"]; - var ref = s["ref"]; - - if ((!s["exclude"] || (s["exclude"].indexOf(nodeType) === -1 && s["exclude"].indexOf(docType) === -1)) - && (s["testType"] & TEST_MATCH) ) { - - if (ctx && !ref) { - test(function() { - var j, element, refNode; - for (j = 0; j < e.length; j++) { - element = root.querySelector("#" + e[j]); - refNode = root.querySelector(ctx); - assert_true(element[method](q, refNode), "The element #" + e[j] + " should match the selector.") - } - - if (u) { - for (j = 0; j < u.length; j++) { - element = root.querySelector("#" + u[j]); - refNode = root.querySelector(ctx); - assert_false(element[method](q, refNode), "The element #" + u[j] + " should not match the selector.") - } - } - }, type + " Element." + method + ": " + n + " (with refNode Element): " + q); - } - - if (ref) { - test(function() { - var j, element, refNodes; - for (j = 0; j < e.length; j++) { - element = root.querySelector("#" + e[j]); - refNodes = root.querySelectorAll(ref); - assert_true(element[method](q, refNodes), "The element #" + e[j] + " should match the selector.") - } - - if (u) { - for (j = 0; j < u.length; j++) { - element = root.querySelector("#" + u[j]); - refNodes = root.querySelectorAll(ref); - assert_false(element[method](q, refNodes), "The element #" + u[j] + " should not match the selector.") - } - } - }, type + " Element." + method + ": " + n + " (with refNodes NodeList): " + q); - } - - if (!ctx && !ref) { - test(function() { - for (var j = 0; j < e.length; j++) { - var element = root.querySelector("#" + e[j]); - assert_true(element[method](q), "The element #" + e[j] + " should match the selector.") - } - - if (u) { - for (j = 0; j < u.length; j++) { - element = root.querySelector("#" + u[j]); - assert_false(element[method](q), "The element #" + u[j] + " should not match the selector.") - } - } - }, type + " Element." + method + ": " + n + " (with no refNodes): " + q); - } - } - } -} diff --git a/tests/wpt/dom/nodes/Element-nextElementSibling-svg.svg b/tests/wpt/dom/nodes/Element-nextElementSibling-svg.svg deleted file mode 100644 index 3e17cad2..00000000 --- a/tests/wpt/dom/nodes/Element-nextElementSibling-svg.svg +++ /dev/null @@ -1,23 +0,0 @@ - - -nextElementSibling - - - -Test of nextElementSibling -The result of this test is unknown. - - -test(function() { - var parentEl = document.getElementById("parentEl"); - var fec = document.getElementById("first_element_child"); - var nes = fec.nextElementSibling; - assert_true(!!nes) - assert_equals(nes.nodeType, 1) - assert_equals(nes.getAttribute("id"), "last_element_child") -}) - - diff --git a/tests/wpt/dom/nodes/Element-nextElementSibling-xhtml.xhtml b/tests/wpt/dom/nodes/Element-nextElementSibling-xhtml.xhtml deleted file mode 100644 index 915209bd..00000000 --- a/tests/wpt/dom/nodes/Element-nextElementSibling-xhtml.xhtml +++ /dev/null @@ -1,23 +0,0 @@ - - - -nextElementSibling - - - - -

Test of nextElementSibling

-
-

The result of this test is unknown.

- - - diff --git a/tests/wpt/dom/nodes/Element-nextElementSibling.html b/tests/wpt/dom/nodes/Element-nextElementSibling.html deleted file mode 100644 index 985c602f..00000000 --- a/tests/wpt/dom/nodes/Element-nextElementSibling.html +++ /dev/null @@ -1,18 +0,0 @@ - - -nextElementSibling - - -

Test of nextElementSibling

-
-

The result of this test is unknown.

- diff --git a/tests/wpt/dom/nodes/Element-previousElementSibling-svg.svg b/tests/wpt/dom/nodes/Element-previousElementSibling-svg.svg deleted file mode 100644 index 671d2c87..00000000 --- a/tests/wpt/dom/nodes/Element-previousElementSibling-svg.svg +++ /dev/null @@ -1,28 +0,0 @@ - - -previousElementSibling - - - -Test of previousElementSibling -The result of this test is -unknown. - - - -fnord - - -test(function() { - var parentEl = document.getElementById("parentEl"); - var lec = document.getElementById("last_element_child"); - var pes = lec.previousElementSibling; - assert_true(!!pes) - assert_equals(pes.nodeType, 1) - assert_equals(pes.getAttribute("id"), "middle_element_child") -}) - - diff --git a/tests/wpt/dom/nodes/Element-previousElementSibling-xhtml.xhtml b/tests/wpt/dom/nodes/Element-previousElementSibling-xhtml.xhtml deleted file mode 100644 index 7fbbc6d3..00000000 --- a/tests/wpt/dom/nodes/Element-previousElementSibling-xhtml.xhtml +++ /dev/null @@ -1,28 +0,0 @@ - - - -previousElementSibling - - - - -

Test of previousElementSibling

-
-

The result of this test is -unknown. - - - -

- - - diff --git a/tests/wpt/dom/nodes/Element-previousElementSibling.html b/tests/wpt/dom/nodes/Element-previousElementSibling.html deleted file mode 100644 index 02c7b16d..00000000 --- a/tests/wpt/dom/nodes/Element-previousElementSibling.html +++ /dev/null @@ -1,23 +0,0 @@ - - -previousElementSibling - - -

Test of previousElementSibling

-
-

The result of this test is -unknown. - - - -

- diff --git a/tests/wpt/dom/nodes/Element-remove.html b/tests/wpt/dom/nodes/Element-remove.html deleted file mode 100644 index ab642d66..00000000 --- a/tests/wpt/dom/nodes/Element-remove.html +++ /dev/null @@ -1,16 +0,0 @@ - - -Element.remove - - - - -
- diff --git a/tests/wpt/dom/nodes/Element-removeAttribute.html b/tests/wpt/dom/nodes/Element-removeAttribute.html deleted file mode 100644 index df79e62c..00000000 --- a/tests/wpt/dom/nodes/Element-removeAttribute.html +++ /dev/null @@ -1,58 +0,0 @@ - - -Element.prototype.removeAttribute - - - - - diff --git a/tests/wpt/dom/nodes/Element-removeAttributeNS.html b/tests/wpt/dom/nodes/Element-removeAttributeNS.html deleted file mode 100644 index a2773e6f..00000000 --- a/tests/wpt/dom/nodes/Element-removeAttributeNS.html +++ /dev/null @@ -1,18 +0,0 @@ - -Element.removeAttributeNS - - - -
- diff --git a/tests/wpt/dom/nodes/Element-setAttribute-crbug-1138487.html b/tests/wpt/dom/nodes/Element-setAttribute-crbug-1138487.html deleted file mode 100644 index 9aa9ed81..00000000 --- a/tests/wpt/dom/nodes/Element-setAttribute-crbug-1138487.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - diff --git a/tests/wpt/dom/nodes/Element-setAttribute.html b/tests/wpt/dom/nodes/Element-setAttribute.html deleted file mode 100644 index 76094068..00000000 --- a/tests/wpt/dom/nodes/Element-setAttribute.html +++ /dev/null @@ -1,38 +0,0 @@ - - -Element.prototype.setAttribute - - - - - diff --git a/tests/wpt/dom/nodes/Element-siblingElement-null-svg.svg b/tests/wpt/dom/nodes/Element-siblingElement-null-svg.svg deleted file mode 100644 index 48c981b8..00000000 --- a/tests/wpt/dom/nodes/Element-siblingElement-null-svg.svg +++ /dev/null @@ -1,20 +0,0 @@ - - -Null test - - - -Test of previousElementSibling and nextElementSibling returning null -The result of this test is unknown. - - -test(function() { - var fec = document.getElementById("first_element_child"); - assert_equals(fec.previousElementSibling, null) - assert_equals(fec.nextElementSibling, null) -}) - - diff --git a/tests/wpt/dom/nodes/Element-siblingElement-null-xhtml.xhtml b/tests/wpt/dom/nodes/Element-siblingElement-null-xhtml.xhtml deleted file mode 100644 index fcf4d54f..00000000 --- a/tests/wpt/dom/nodes/Element-siblingElement-null-xhtml.xhtml +++ /dev/null @@ -1,20 +0,0 @@ - - - -Null Test - - - - -

Test of previousElementSibling and nextElementSibling returning null

-
-

The result of this test is unknown.

- - - diff --git a/tests/wpt/dom/nodes/Element-siblingElement-null.html b/tests/wpt/dom/nodes/Element-siblingElement-null.html deleted file mode 100644 index a7920b4f..00000000 --- a/tests/wpt/dom/nodes/Element-siblingElement-null.html +++ /dev/null @@ -1,16 +0,0 @@ - - -Null test - - -

Test of previousElementSibling and nextElementSibling returning null

-
-

The result of this test is unknown.

- - diff --git a/tests/wpt/dom/nodes/Element-tagName.html b/tests/wpt/dom/nodes/Element-tagName.html deleted file mode 100644 index 43e7a2d2..00000000 --- a/tests/wpt/dom/nodes/Element-tagName.html +++ /dev/null @@ -1,57 +0,0 @@ - -Element.tagName - - -
- diff --git a/tests/wpt/dom/nodes/Element-webkitMatchesSelector.html b/tests/wpt/dom/nodes/Element-webkitMatchesSelector.html deleted file mode 100644 index 107f8102..00000000 --- a/tests/wpt/dom/nodes/Element-webkitMatchesSelector.html +++ /dev/null @@ -1,22 +0,0 @@ - - -Selectors-API Level 2 Test Suite: HTML with Selectors Level 3 - - - - - - - - - -
This test requires JavaScript.
- - diff --git a/tests/wpt/dom/nodes/Node-appendChild-cereactions-vs-script.window.js b/tests/wpt/dom/nodes/Node-appendChild-cereactions-vs-script.window.js deleted file mode 100644 index bc0b8ad6..00000000 --- a/tests/wpt/dom/nodes/Node-appendChild-cereactions-vs-script.window.js +++ /dev/null @@ -1,27 +0,0 @@ -const results = []; -test(() => { - class Script1 extends HTMLScriptElement { - constructor() { - super(); - } - connectedCallback() { - results.push("ce connected s1"); - } - } - class Script2 extends HTMLScriptElement { - constructor() { - super(); - } - connectedCallback() { - results.push("ce connected s2"); - } - } - customElements.define("script-1", Script1, { extends: "script" }); - customElements.define("script-2", Script2, { extends: "script" }); - const s1 = new Script1(); - s1.textContent = "results.push('s1')"; - const s2 = new Script2(); - s2.textContent = "results.push('s2')"; - document.body.append(s1, s2); - assert_array_equals(results, ["s1", "s2", "ce connected s1", "ce connected s2"]); -}, "Custom element reactions follow script execution"); diff --git a/tests/wpt/dom/nodes/Node-appendChild.html b/tests/wpt/dom/nodes/Node-appendChild.html deleted file mode 100644 index 8264cb11..00000000 --- a/tests/wpt/dom/nodes/Node-appendChild.html +++ /dev/null @@ -1,59 +0,0 @@ - - -Node.appendChild - - - -
- - diff --git a/tests/wpt/dom/nodes/Node-baseURI.html b/tests/wpt/dom/nodes/Node-baseURI.html deleted file mode 100644 index e9e9d76a..00000000 --- a/tests/wpt/dom/nodes/Node-baseURI.html +++ /dev/null @@ -1,62 +0,0 @@ - -Node.baseURI - - -
- diff --git a/tests/wpt/dom/nodes/Node-childNodes.html b/tests/wpt/dom/nodes/Node-childNodes.html deleted file mode 100644 index 0d38df37..00000000 --- a/tests/wpt/dom/nodes/Node-childNodes.html +++ /dev/null @@ -1,117 +0,0 @@ - - -Node.childNodes - - - - - -
-
-
  • 1
  • 2
  • 3
  • 4
-
- diff --git a/tests/wpt/dom/nodes/Node-cloneNode-XMLDocument.html b/tests/wpt/dom/nodes/Node-cloneNode-XMLDocument.html deleted file mode 100644 index 2c63c775..00000000 --- a/tests/wpt/dom/nodes/Node-cloneNode-XMLDocument.html +++ /dev/null @@ -1,28 +0,0 @@ - - -Cloning of an XMLDocument - - - - - - - - - diff --git a/tests/wpt/dom/nodes/Node-cloneNode-document-with-doctype.html b/tests/wpt/dom/nodes/Node-cloneNode-document-with-doctype.html deleted file mode 100644 index 21963084..00000000 --- a/tests/wpt/dom/nodes/Node-cloneNode-document-with-doctype.html +++ /dev/null @@ -1,51 +0,0 @@ - - -Cloning of a document with a doctype - - - - - - - diff --git a/tests/wpt/dom/nodes/Node-cloneNode-external-stylesheet-no-bc.sub.html b/tests/wpt/dom/nodes/Node-cloneNode-external-stylesheet-no-bc.sub.html deleted file mode 100644 index bce6074a..00000000 --- a/tests/wpt/dom/nodes/Node-cloneNode-external-stylesheet-no-bc.sub.html +++ /dev/null @@ -1,23 +0,0 @@ - - -cloneNode on a stylesheet link in a browsing-context-less document - - - - - diff --git a/tests/wpt/dom/nodes/Node-cloneNode-on-inactive-document-crash.html b/tests/wpt/dom/nodes/Node-cloneNode-on-inactive-document-crash.html deleted file mode 100644 index cbd7a1e6..00000000 --- a/tests/wpt/dom/nodes/Node-cloneNode-on-inactive-document-crash.html +++ /dev/null @@ -1,6 +0,0 @@ - - diff --git a/tests/wpt/dom/nodes/Node-cloneNode-svg.html b/tests/wpt/dom/nodes/Node-cloneNode-svg.html deleted file mode 100644 index 9d4704b0..00000000 --- a/tests/wpt/dom/nodes/Node-cloneNode-svg.html +++ /dev/null @@ -1,63 +0,0 @@ - - -Cloning of SVG elements and attributes - - - - - - - - - - diff --git a/tests/wpt/dom/nodes/Node-cloneNode.html b/tests/wpt/dom/nodes/Node-cloneNode.html deleted file mode 100644 index e97259da..00000000 --- a/tests/wpt/dom/nodes/Node-cloneNode.html +++ /dev/null @@ -1,346 +0,0 @@ - - -Node.cloneNode - - - -
- diff --git a/tests/wpt/dom/nodes/Node-compareDocumentPosition.html b/tests/wpt/dom/nodes/Node-compareDocumentPosition.html deleted file mode 100644 index afae60aa..00000000 --- a/tests/wpt/dom/nodes/Node-compareDocumentPosition.html +++ /dev/null @@ -1,87 +0,0 @@ - -Node.compareDocumentPosition() tests - -
- - - - - diff --git a/tests/wpt/dom/nodes/Node-constants.html b/tests/wpt/dom/nodes/Node-constants.html deleted file mode 100644 index 33e7c10e..00000000 --- a/tests/wpt/dom/nodes/Node-constants.html +++ /dev/null @@ -1,39 +0,0 @@ - -Node constants - - - -
- diff --git a/tests/wpt/dom/nodes/Node-contains-xml.xml b/tests/wpt/dom/nodes/Node-contains-xml.xml deleted file mode 100644 index f9b20d68..00000000 --- a/tests/wpt/dom/nodes/Node-contains-xml.xml +++ /dev/null @@ -1,83 +0,0 @@ - - - -Node.nodeName - - - - - - -
-
- - Link text -
- - - diff --git a/tests/wpt/dom/nodes/Node-contains.html b/tests/wpt/dom/nodes/Node-contains.html deleted file mode 100644 index c44f072b..00000000 --- a/tests/wpt/dom/nodes/Node-contains.html +++ /dev/null @@ -1,36 +0,0 @@ - -Node.contains() tests - -
- - - - - diff --git a/tests/wpt/dom/nodes/Node-insertBefore.html b/tests/wpt/dom/nodes/Node-insertBefore.html deleted file mode 100644 index ecb4d183..00000000 --- a/tests/wpt/dom/nodes/Node-insertBefore.html +++ /dev/null @@ -1,297 +0,0 @@ - -Node.insertBefore - - -
- - - - - diff --git a/tests/wpt/dom/nodes/Node-isConnected-shadow-dom.html b/tests/wpt/dom/nodes/Node-isConnected-shadow-dom.html deleted file mode 100644 index 7d04dc32..00000000 --- a/tests/wpt/dom/nodes/Node-isConnected-shadow-dom.html +++ /dev/null @@ -1,29 +0,0 @@ - - -Test of Node.isConnected in a shadow tree - - - - - - diff --git a/tests/wpt/dom/nodes/Node-isConnected.html b/tests/wpt/dom/nodes/Node-isConnected.html deleted file mode 100644 index da0b460d..00000000 --- a/tests/wpt/dom/nodes/Node-isConnected.html +++ /dev/null @@ -1,95 +0,0 @@ - - - -Node.prototype.isConnected - - - - - - - diff --git a/tests/wpt/dom/nodes/Node-isEqualNode-iframe1.xml b/tests/wpt/dom/nodes/Node-isEqualNode-iframe1.xml deleted file mode 100644 index 8077e73c..00000000 --- a/tests/wpt/dom/nodes/Node-isEqualNode-iframe1.xml +++ /dev/null @@ -1 +0,0 @@ - ]> diff --git a/tests/wpt/dom/nodes/Node-isEqualNode-iframe2.xml b/tests/wpt/dom/nodes/Node-isEqualNode-iframe2.xml deleted file mode 100644 index eacc9d17..00000000 --- a/tests/wpt/dom/nodes/Node-isEqualNode-iframe2.xml +++ /dev/null @@ -1 +0,0 @@ - ]> diff --git a/tests/wpt/dom/nodes/Node-isEqualNode-xhtml.xhtml b/tests/wpt/dom/nodes/Node-isEqualNode-xhtml.xhtml deleted file mode 100644 index 3170643d..00000000 --- a/tests/wpt/dom/nodes/Node-isEqualNode-xhtml.xhtml +++ /dev/null @@ -1,84 +0,0 @@ - - -Node.isEqualNode - - - - -
- - diff --git a/tests/wpt/dom/nodes/Node-properties.html b/tests/wpt/dom/nodes/Node-properties.html deleted file mode 100644 index 10f92e7d..00000000 --- a/tests/wpt/dom/nodes/Node-properties.html +++ /dev/null @@ -1,688 +0,0 @@ - -Node assorted property tests - - -
- - - - diff --git a/tests/wpt/dom/nodes/Node-removeChild.html b/tests/wpt/dom/nodes/Node-removeChild.html deleted file mode 100644 index 61584233..00000000 --- a/tests/wpt/dom/nodes/Node-removeChild.html +++ /dev/null @@ -1,58 +0,0 @@ - -Node.removeChild - - - -
- - diff --git a/tests/wpt/dom/nodes/Node-replaceChild.html b/tests/wpt/dom/nodes/Node-replaceChild.html deleted file mode 100644 index 74aac67d..00000000 --- a/tests/wpt/dom/nodes/Node-replaceChild.html +++ /dev/null @@ -1,349 +0,0 @@ - - -Node.replaceChild - - - -
- - - - diff --git a/tests/wpt/dom/nodes/Node-textContent.html b/tests/wpt/dom/nodes/Node-textContent.html deleted file mode 100644 index cf2e0720..00000000 --- a/tests/wpt/dom/nodes/Node-textContent.html +++ /dev/null @@ -1,265 +0,0 @@ - - -Node.textContent - - -
- diff --git a/tests/wpt/dom/nodes/NodeList-Iterable.html b/tests/wpt/dom/nodes/NodeList-Iterable.html deleted file mode 100644 index fcbee175..00000000 --- a/tests/wpt/dom/nodes/NodeList-Iterable.html +++ /dev/null @@ -1,61 +0,0 @@ - - -NodeList Iterable Test - - -

-

-

-

-

- -
123
- diff --git a/tests/wpt/dom/nodes/NodeList-live-mutations.window.js b/tests/wpt/dom/nodes/NodeList-live-mutations.window.js deleted file mode 100644 index a11fed1e..00000000 --- a/tests/wpt/dom/nodes/NodeList-live-mutations.window.js +++ /dev/null @@ -1,79 +0,0 @@ -function testNodeList(name, hooks) { - test(() => { - const nodes = { - root: document.createElement("div"), - div1: document.createElement("div"), - div2: document.createElement("div"), - p: document.createElement("p") - }; - - const list = nodes.root.childNodes; - - hooks.initial(list, nodes); - - nodes.root.appendChild(nodes.div1); - nodes.root.appendChild(nodes.p); - nodes.root.appendChild(nodes.div2); - - hooks.afterInsertion(list, nodes); - - nodes.root.removeChild(nodes.div1); - - hooks.afterRemoval(list, nodes); - }, `NodeList live mutations: ${name}`); -} - -testNodeList("NodeList.length", { - initial(list) { - assert_equals(list.length, 0); - }, - afterInsertion(list) { - assert_equals(list.length, 3); - }, - afterRemoval(list) { - assert_equals(list.length, 2); - } -}); - -testNodeList("NodeList.item(index)", { - initial(list) { - assert_equals(list.item(0), null); - }, - afterInsertion(list, nodes) { - assert_equals(list.item(0), nodes.div1); - assert_equals(list.item(1), nodes.p); - assert_equals(list.item(2), nodes.div2); - }, - afterRemoval(list, nodes) { - assert_equals(list.item(0), nodes.p); - assert_equals(list.item(1), nodes.div2); - } -}); - -testNodeList("NodeList[index]", { - initial(list) { - assert_equals(list[0], undefined); - }, - afterInsertion(list, nodes) { - assert_equals(list[0], nodes.div1); - assert_equals(list[1], nodes.p); - assert_equals(list[2], nodes.div2); - }, - afterRemoval(list, nodes) { - assert_equals(list[0], nodes.p); - assert_equals(list[1], nodes.div2); - } -}); - -testNodeList("NodeList ownPropertyNames", { - initial(list) { - assert_object_equals(Object.getOwnPropertyNames(list), []); - }, - afterInsertion(list) { - assert_object_equals(Object.getOwnPropertyNames(list), ["0", "1", "2"]); - }, - afterRemoval(list) { - assert_object_equals(Object.getOwnPropertyNames(list), ["0", "1"]); - } -}); - diff --git a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-1.html b/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-1.html deleted file mode 100644 index c5c58f9d..00000000 --- a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-1.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -NodeList (static collection) "length" getter tampered - - - - - - - diff --git a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-2.html b/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-2.html deleted file mode 100644 index bac05112..00000000 --- a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-2.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -NodeList (static collection) "length" getter tampered - - - - - - - diff --git a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-3.html b/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-3.html deleted file mode 100644 index 9690aab3..00000000 --- a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-3.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -NodeList (static collection) "length" getter tampered - - - - - - - diff --git a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html b/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html deleted file mode 100644 index 5ce41467..00000000 --- a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-1.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -NodeList (static collection) "length" getter tampered (Array.prototype.indexOf) - - - - - - - diff --git a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html b/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html deleted file mode 100644 index 57814ed5..00000000 --- a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-2.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -NodeList (static collection) "length" getter tampered (Array.prototype.indexOf) - - - - - - - diff --git a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html b/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html deleted file mode 100644 index 838f376d..00000000 --- a/tests/wpt/dom/nodes/NodeList-static-length-getter-tampered-indexOf-3.html +++ /dev/null @@ -1,22 +0,0 @@ - - - -NodeList (static collection) "length" getter tampered (Array.prototype.indexOf) - - - - - - - diff --git a/tests/wpt/dom/nodes/ParentNode-children.html b/tests/wpt/dom/nodes/ParentNode-children.html deleted file mode 100644 index 6621e7d9..00000000 --- a/tests/wpt/dom/nodes/ParentNode-children.html +++ /dev/null @@ -1,27 +0,0 @@ - - -ParentNode.children - - - -
-
-
  • 1
  • 2
  • 3
  • 4
-
- - diff --git a/tests/wpt/dom/nodes/ParentNode-querySelector-All-content.html b/tests/wpt/dom/nodes/ParentNode-querySelector-All-content.html deleted file mode 100644 index 8dc13545..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelector-All-content.html +++ /dev/null @@ -1,377 +0,0 @@ - - - - - Selectors-API Test Suite: HTML with Selectors Level 2 using TestHarness: Test Document - - - - - - - - -
-
- -
-

Universal selector tests inside element with id="universal".

-
-
Some preformatted text with some embedded code
-

This is a normal link: W3C

-
Some more nested elements code hyperlink
-
- -
-
-
-
-
-

-

-    
-
    - - - - -
    - -
    -
    -
    -
    -
    - -
    - - - - - - - - - -
    - -
    -
    - -
    -
    -
    -
    - -
    -
    - - - - - - - - - -

    -
    - -
    -
    -
    -
    -
    -
    - -
    - - - - -
    -
    -
    -
    -
    - -

    -
    - -
    - - - - -
    -
    -
    -
    - -

    -
    - -
    - - - - -
    -
    -
    -
    -
    -
    - -

    -
    - -
    - - - - -
    - -
      -
    1. -
    2. -
    3. -
    4. -
    5. -
    6. -
    7. -
    8. -
    9. -
    10. -
    11. -
    12. -
    - -

    - span1 - em1 - - em2 - span2 - strong1 - em3 - span3 - span4 - strong2 - em4 -

    -
    - -
    -
    -
    -
    - -

    -

    -

    -
    - -
    -

    -

    -

    - -
    -
    -
    -
    - -
    -

    - -

    -

    - - -

    -

    - - - -

    -
    > - -
    -

    -

    -

    -

    Text node

    -

    -
    - - - -
    -
    -
    -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    -
    -
    - -

    -

    -

    -
    - -
    All pseudo-element tests
    - -
    -

    -

    -

    - - -
    -
    -

    -
    -

    -
    -
    -
    -
    - - - - - - -
    - -
    -
    -
    - -
      -
    • -
    • -
    • -
    • -
    - - - - - - -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -

    -
    -
    -
    -

    -

    -
    - -
    -
    -
    -
    -
    -
    -

    -
    -
    -
    -

    -

    -
    - -
    - - -
    -
    - - diff --git a/tests/wpt/dom/nodes/ParentNode-querySelector-All-content.xht b/tests/wpt/dom/nodes/ParentNode-querySelector-All-content.xht deleted file mode 100644 index 0e9b925f..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelector-All-content.xht +++ /dev/null @@ -1,372 +0,0 @@ - - - - Selectors-API Test Suite: HTML with Selectors Level 2 using TestHarness: Test Document - - - - - - - -
    -
    - -
    -

    Universal selector tests inside element with id="universal".

    -
    -
    Some preformatted text with some embedded code
    -

    This is a normal link: W3C

    -
    Some more nested elements code hyperlink
    -
    - -
    -
    -
    -
    -
    -

    -
    
    -    
    -
      - - - - -
      - -
      -
      -
      -
      -
      - -
      - - - - - - - - - -
      - -
      -
      - -
      -
      -
      -
      - -
      -
      - - - - - - - - - -

      -
      - -
      -
      -
      -
      -
      -
      - -
      - - - - -
      -
      -
      -
      -
      - -

      -
      - -
      - - - - -
      -
      -
      -
      - -

      -
      - -
      - - - - -
      -
      -
      -
      -
      -
      - -

      -
      - -
      - - - - -
      - -
        -
      1. -
      2. -
      3. -
      4. -
      5. -
      6. -
      7. -
      8. -
      9. -
      10. -
      11. -
      12. -
      - -

      - span1 - em1 - - em2 - span2 - strong1 - em3 - span3 - span4 - strong2 - em4 -

      -
      - -
      -
      -
      -
      - -

      -

      -

      -
      - -
      -

      -

      -

      - -
      -
      -
      -
      - -
      -

      - -

      -

      - - -

      -

      - - - -

      -
      > - -
      -

      -

      -

      -

      Text node

      -

      -
      - - - -
      -
      -
      -
      -
      -
      - -
      - - - - - - - - - - - - - - - - - - - - - - - -
      - -
      -
      -
      -
      - -

      -

      -

      -
      - -
      All pseudo-element tests
      - -
      -

      -

      -

      - - -
      -
      -

      -
      -

      -
      -
      -
      -
      - - - - - - -
      - -
      -
      -
      - -
        -
      • -
      • -
      • -
      • -
      - - - - - - -
      - -
      -
      -
      -
      -
      -
      -
      -
      -
      - -
      -
      -
      -
      -
      -
      -
      -
      -
      - -
      -
      -
      -
      -
      -
      -

      -
      -
      -
      -

      -

      -
      - -
      -
      -
      -
      -
      -
      -

      -
      -
      -
      -

      -

      -
      - -
      - - -
      -
      - - diff --git a/tests/wpt/dom/nodes/ParentNode-querySelector-All-xht.xht b/tests/wpt/dom/nodes/ParentNode-querySelector-All-xht.xht deleted file mode 100644 index f2d94da1..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelector-All-xht.xht +++ /dev/null @@ -1,124 +0,0 @@ - - - - -Selectors-API Test Suite: XHTML - - - - - - - -
      This test requires JavaScript.
      - - - - diff --git a/tests/wpt/dom/nodes/ParentNode-querySelector-All.html b/tests/wpt/dom/nodes/ParentNode-querySelector-All.html deleted file mode 100644 index 7d68e7f2..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelector-All.html +++ /dev/null @@ -1,120 +0,0 @@ - - - -Selectors-API Test Suite: HTML - - - - - - -
      This test requires JavaScript.
      - - diff --git a/tests/wpt/dom/nodes/ParentNode-querySelector-All.js b/tests/wpt/dom/nodes/ParentNode-querySelector-All.js deleted file mode 100644 index 3c6c5031..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelector-All.js +++ /dev/null @@ -1,261 +0,0 @@ -// 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. - } -} diff --git a/tests/wpt/dom/nodes/ParentNode-querySelector-case-insensitive.html b/tests/wpt/dom/nodes/ParentNode-querySelector-case-insensitive.html deleted file mode 100644 index e461ee50..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelector-case-insensitive.html +++ /dev/null @@ -1,21 +0,0 @@ - - -querySelector(All) must work with the i and *= selectors - - - - - - - diff --git a/tests/wpt/dom/nodes/ParentNode-querySelector-escapes.html b/tests/wpt/dom/nodes/ParentNode-querySelector-escapes.html deleted file mode 100644 index 65a75e5c..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelector-escapes.html +++ /dev/null @@ -1,123 +0,0 @@ - - -querySelector() with CSS escapes - - - - - - - - diff --git a/tests/wpt/dom/nodes/ParentNode-querySelector-scope.html b/tests/wpt/dom/nodes/ParentNode-querySelector-scope.html deleted file mode 100644 index d984956d..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelector-scope.html +++ /dev/null @@ -1,33 +0,0 @@ - - -querySelector(All) scoped to a root element - - - -

      hello

      - - diff --git a/tests/wpt/dom/nodes/ParentNode-querySelectorAll-removed-elements.html b/tests/wpt/dom/nodes/ParentNode-querySelectorAll-removed-elements.html deleted file mode 100644 index 3cefc809..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelectorAll-removed-elements.html +++ /dev/null @@ -1,30 +0,0 @@ - - -querySelectorAll must not return removed elements - - - - -
      - - diff --git a/tests/wpt/dom/nodes/ParentNode-querySelectors-exclusive.html b/tests/wpt/dom/nodes/ParentNode-querySelectors-exclusive.html deleted file mode 100644 index 5cff9367..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelectors-exclusive.html +++ /dev/null @@ -1,39 +0,0 @@ - - -querySelector/querySelectorAll should not include their thisArg - - - - - diff --git a/tests/wpt/dom/nodes/ParentNode-querySelectors-namespaces.html b/tests/wpt/dom/nodes/ParentNode-querySelectors-namespaces.html deleted file mode 100644 index 714999b3..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelectors-namespaces.html +++ /dev/null @@ -1,21 +0,0 @@ - - -querySelectorAll must work with namespace attribute selectors on SVG - - - - - - - diff --git a/tests/wpt/dom/nodes/ParentNode-querySelectors-space-and-dash-attribute-value.html b/tests/wpt/dom/nodes/ParentNode-querySelectors-space-and-dash-attribute-value.html deleted file mode 100644 index e08c6e6d..00000000 --- a/tests/wpt/dom/nodes/ParentNode-querySelectors-space-and-dash-attribute-value.html +++ /dev/null @@ -1,21 +0,0 @@ - - -querySelector(All) must work for attribute values that contain spaces and dashes - - - - -Test One - - diff --git a/tests/wpt/dom/nodes/append-on-Document.html b/tests/wpt/dom/nodes/append-on-Document.html deleted file mode 100644 index 78f278b3..00000000 --- a/tests/wpt/dom/nodes/append-on-Document.html +++ /dev/null @@ -1,53 +0,0 @@ - - -DocumentType.append - - - - - diff --git a/tests/wpt/dom/nodes/attributes.html b/tests/wpt/dom/nodes/attributes.html deleted file mode 100644 index c6db7eb8..00000000 --- a/tests/wpt/dom/nodes/attributes.html +++ /dev/null @@ -1,858 +0,0 @@ - - -Attributes tests - - - - - - - -
      - - - - - - - - diff --git a/tests/wpt/dom/nodes/attributes.js b/tests/wpt/dom/nodes/attributes.js deleted file mode 100644 index ef32bf6a..00000000 --- a/tests/wpt/dom/nodes/attributes.js +++ /dev/null @@ -1,18 +0,0 @@ -function attr_is(attr, v, ln, ns, p, n) { - assert_equals(attr.value, v) - assert_equals(attr.nodeValue, v) - assert_equals(attr.textContent, v) - assert_equals(attr.localName, ln) - assert_equals(attr.namespaceURI, ns) - assert_equals(attr.prefix, p) - assert_equals(attr.name, n) - assert_equals(attr.nodeName, n); - assert_equals(attr.specified, true) -} - -function attributes_are(el, l) { - for (var i = 0, il = l.length; i < il; i++) { - attr_is(el.attributes[i], l[i][1], l[i][0], (l[i].length < 3) ? null : l[i][2], null, l[i][0]) - assert_equals(el.attributes[i].ownerElement, el) - } -} diff --git a/tests/wpt/dom/nodes/creators.js b/tests/wpt/dom/nodes/creators.js deleted file mode 100644 index 8b7415d1..00000000 --- a/tests/wpt/dom/nodes/creators.js +++ /dev/null @@ -1,5 +0,0 @@ -var creators = { - "element": "createElement", - "text": "createTextNode", - "comment": "createComment" -}; diff --git a/tests/wpt/dom/nodes/pre-insertion-validation-hierarchy.js b/tests/wpt/dom/nodes/pre-insertion-validation-hierarchy.js deleted file mode 100644 index 6ef2576d..00000000 --- a/tests/wpt/dom/nodes/pre-insertion-validation-hierarchy.js +++ /dev/null @@ -1,86 +0,0 @@ -/** - * Validations where `child` argument is irrelevant. - * @param {Function} methodName - */ -function preInsertionValidateHierarchy(methodName) { - function insert(parent, node) { - if (parent[methodName].length > 1) { - // This is for insertBefore(). We can't blindly pass `null` for all methods - // as doing so will move nodes before validation. - parent[methodName](node, null); - } else { - parent[methodName](node); - } - } - - // Step 2 - test(() => { - const doc = document.implementation.createHTMLDocument("title"); - assert_throws_dom("HierarchyRequestError", () => insert(doc.body, doc.body)); - assert_throws_dom("HierarchyRequestError", () => insert(doc.body, doc.documentElement)); - }, "If node is a host-including inclusive ancestor of parent, then throw a HierarchyRequestError DOMException."); - - // Step 4 - test(() => { - const doc = document.implementation.createHTMLDocument("title"); - const doc2 = document.implementation.createHTMLDocument("title2"); - assert_throws_dom("HierarchyRequestError", () => insert(doc, doc2)); - }, "If node is not a DocumentFragment, DocumentType, Element, Text, ProcessingInstruction, or Comment node, then throw a HierarchyRequestError DOMException."); - - // Step 5, in case of inserting a text node into a document - test(() => { - const doc = document.implementation.createHTMLDocument("title"); - assert_throws_dom("HierarchyRequestError", () => insert(doc, doc.createTextNode("text"))); - }, "If node is a Text node and parent is a document, then throw a HierarchyRequestError DOMException."); - - // Step 5, in case of inserting a doctype into a non-document - test(() => { - const doc = document.implementation.createHTMLDocument("title"); - const doctype = doc.childNodes[0]; - assert_throws_dom("HierarchyRequestError", () => insert(doc.createElement("a"), doctype)); - }, "If node is a doctype and parent is not a document, then throw a HierarchyRequestError DOMException.") - - // Step 6, in case of DocumentFragment including multiple elements - test(() => { - const doc = document.implementation.createHTMLDocument("title"); - doc.documentElement.remove(); - const df = doc.createDocumentFragment(); - df.appendChild(doc.createElement("a")); - df.appendChild(doc.createElement("b")); - assert_throws_dom("HierarchyRequestError", () => insert(doc, df)); - }, "If node is a DocumentFragment with multiple elements and parent is a document, then throw a HierarchyRequestError DOMException."); - - // Step 6, in case of DocumentFragment has multiple elements when document already has an element - test(() => { - const doc = document.implementation.createHTMLDocument("title"); - const df = doc.createDocumentFragment(); - df.appendChild(doc.createElement("a")); - assert_throws_dom("HierarchyRequestError", () => insert(doc, df)); - }, "If node is a DocumentFragment with an element and parent is a document with another element, then throw a HierarchyRequestError DOMException."); - - // Step 6, in case of an element - test(() => { - const doc = document.implementation.createHTMLDocument("title"); - const el = doc.createElement("a"); - assert_throws_dom("HierarchyRequestError", () => insert(doc, el)); - }, "If node is an Element and parent is a document with another element, then throw a HierarchyRequestError DOMException."); - - // Step 6, in case of a doctype when document already has another doctype - test(() => { - const doc = document.implementation.createHTMLDocument("title"); - const doctype = doc.childNodes[0].cloneNode(); - doc.documentElement.remove(); - assert_throws_dom("HierarchyRequestError", () => insert(doc, doctype)); - }, "If node is a doctype and parent is a document with another doctype, then throw a HierarchyRequestError DOMException."); - - // Step 6, in case of a doctype when document has an element - if (methodName !== "prepend") { - // Skip `.prepend` as this doesn't throw if `child` is an element - test(() => { - const doc = document.implementation.createHTMLDocument("title"); - const doctype = doc.childNodes[0].cloneNode(); - doc.childNodes[0].remove(); - assert_throws_dom("HierarchyRequestError", () => insert(doc, doctype)); - }, "If node is a doctype and parent is a document with an element, then throw a HierarchyRequestError DOMException."); - } -} diff --git a/tests/wpt/dom/nodes/pre-insertion-validation-notfound.js b/tests/wpt/dom/nodes/pre-insertion-validation-notfound.js deleted file mode 100644 index 705283fa..00000000 --- a/tests/wpt/dom/nodes/pre-insertion-validation-notfound.js +++ /dev/null @@ -1,108 +0,0 @@ -function getNonParentNodes() { - return [ - document.implementation.createDocumentType("html", "", ""), - document.createTextNode("text"), - document.implementation.createDocument(null, "foo", null).createProcessingInstruction("foo", "bar"), - document.createComment("comment"), - document.implementation.createDocument(null, "foo", null).createCDATASection("data"), - ]; -} - -function getNonInsertableNodes() { - return [ - document.implementation.createHTMLDocument("title") - ]; -} - -function getNonDocumentParentNodes() { - return [ - document.createElement("div"), - document.createDocumentFragment(), - ]; -} - -// Test that the steps happen in the right order, to the extent that it's -// observable. The variable names "parent", "child", and "node" match the -// corresponding variables in the replaceChild algorithm in these tests. - -// Step 1 happens before step 3. -test(function() { - var illegalParents = getNonParentNodes(); - var child = document.createElement("div"); - var node = document.createElement("div"); - illegalParents.forEach(function (parent) { - assert_throws_dom("HierarchyRequestError", function() { - insertFunc.call(parent, node, child); - }); - }); -}, "Should check the 'parent' type before checking whether 'child' is a child of 'parent'"); - -// Step 2 happens before step 3. -test(function() { - var parent = document.createElement("div"); - var child = document.createElement("div"); - var node = document.createElement("div"); - - node.appendChild(parent); - assert_throws_dom("HierarchyRequestError", function() { - insertFunc.call(parent, node, child); - }); -}, "Should check that 'node' is not an ancestor of 'parent' before checking whether 'child' is a child of 'parent'"); - -// Step 3 happens before step 4. -test(function() { - var parent = document.createElement("div"); - var child = document.createElement("div"); - - var illegalChildren = getNonInsertableNodes(); - illegalChildren.forEach(function (node) { - assert_throws_dom("NotFoundError", function() { - insertFunc.call(parent, node, child); - }); - }); -}, "Should check whether 'child' is a child of 'parent' before checking whether 'node' is of a type that can have a parent."); - - -// Step 3 happens before step 5. -test(function() { - var child = document.createElement("div"); - - var node = document.createTextNode(""); - var parent = document.implementation.createDocument(null, "foo", null); - assert_throws_dom("NotFoundError", function() { - insertFunc.call(parent, node, child); - }); - - node = document.implementation.createDocumentType("html", "", ""); - getNonDocumentParentNodes().forEach(function (parent) { - assert_throws_dom("NotFoundError", function() { - insertFunc.call(parent, node, child); - }); - }); -}, "Should check whether 'child' is a child of 'parent' before checking whether 'node' is of a type that can have a parent of the type that 'parent' is."); - -// Step 3 happens before step 6. -test(function() { - var child = document.createElement("div"); - var parent = document.implementation.createDocument(null, null, null); - - var node = document.createDocumentFragment(); - node.appendChild(document.createElement("div")); - node.appendChild(document.createElement("div")); - assert_throws_dom("NotFoundError", function() { - insertFunc.call(parent, node, child); - }); - - node = document.createElement("div"); - parent.appendChild(document.createElement("div")); - assert_throws_dom("NotFoundError", function() { - insertFunc.call(parent, node, child); - }); - - parent.firstChild.remove(); - parent.appendChild(document.implementation.createDocumentType("html", "", "")); - node = document.implementation.createDocumentType("html", "", "") - assert_throws_dom("NotFoundError", function() { - insertFunc.call(parent, node, child); - }); -}, "Should check whether 'child' is a child of 'parent' before checking whether 'node' can be inserted into the document given the kids the document has right now."); diff --git a/tests/wpt/dom/nodes/productions.js b/tests/wpt/dom/nodes/productions.js deleted file mode 100644 index 218797fc..00000000 --- a/tests/wpt/dom/nodes/productions.js +++ /dev/null @@ -1,3 +0,0 @@ -var invalid_names = ["", "invalid^Name", "\\", "'", '"', "0", "0:a"] // XXX -var valid_names = ["x", "X", ":", "a:0"] -var invalid_qnames = [":a", "b:", "x:y:z"] // XXX diff --git a/tests/wpt/dom/nodes/selectors.js b/tests/wpt/dom/nodes/selectors.js deleted file mode 100644 index 5e05547c..00000000 --- a/tests/wpt/dom/nodes/selectors.js +++ /dev/null @@ -1,755 +0,0 @@ -// 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}, -]; diff --git a/tests/wpt/dom/nodes/support/NodeList-static-length-tampered.js b/tests/wpt/dom/nodes/support/NodeList-static-length-tampered.js deleted file mode 100644 index 51167e2d..00000000 --- a/tests/wpt/dom/nodes/support/NodeList-static-length-tampered.js +++ /dev/null @@ -1,46 +0,0 @@ -"use strict"; - -function makeStaticNodeList(length) { - const fooRoot = document.createElement("div"); - - for (var i = 0; i < length; i++) { - const el = document.createElement("span"); - el.className = "foo"; - fooRoot.append(el); - } - - document.body.append(fooRoot); - return fooRoot.querySelectorAll(".foo"); -} - -const indexOfNodeList = new Function("nodeList", ` - const __cacheBust = ${Math.random()}; - - const el = nodeList[50]; - - let index = -1; - - for (var i = 0; i < 1e5 / 2; i++) { - for (var j = 0; j < nodeList.length; j++) { - if (nodeList[j] === el) { - index = j; - break; - } - } - } - - return index; -`); - -const arrayIndexOfNodeList = new Function("nodeList", ` - const __cacheBust = ${Math.random()}; - - const el = nodeList[50]; - const {indexOf} = Array.prototype; - - for (var i = 0; i < 1e5; i++) { - var index = indexOf.call(nodeList, el); - } - - return index; -`); diff --git a/tests/wpt/failure.html.skip b/tests/wpt/failure.html.skip deleted file mode 100644 index 76e6e1c6..00000000 --- a/tests/wpt/failure.html.skip +++ /dev/null @@ -1,11 +0,0 @@ - -Failure - - -
      - - diff --git a/tests/wpt/resources/testharness.js b/tests/wpt/resources/testharness.js deleted file mode 100644 index cdc93b46..00000000 --- a/tests/wpt/resources/testharness.js +++ /dev/null @@ -1,4941 +0,0 @@ -/*global self*/ -/*jshint latedef: nofunc*/ - -/* Documentation: https://web-platform-tests.org/writing-tests/testharness-api.html - * (../docs/_writing-tests/testharness-api.md) */ - -(function (global_scope) -{ - // default timeout is 10 seconds, test can override if needed - var settings = { - output:true, - harness_timeout:{ - "normal":10000, - "long":60000 - }, - test_timeout:null, - message_events: ["start", "test_state", "result", "completion"], - debug: false, - }; - - var xhtml_ns = "http://www.w3.org/1999/xhtml"; - - /* - * TestEnvironment is an abstraction for the environment in which the test - * harness is used. Each implementation of a test environment has to provide - * the following interface: - * - * interface TestEnvironment { - * // Invoked after the global 'tests' object has been created and it's - * // safe to call add_*_callback() to register event handlers. - * void on_tests_ready(); - * - * // Invoked after setup() has been called to notify the test environment - * // of changes to the test harness properties. - * void on_new_harness_properties(object properties); - * - * // Should return a new unique default test name. - * DOMString next_default_test_name(); - * - * // Should return the test harness timeout duration in milliseconds. - * float test_timeout(); - * }; - */ - - /* - * A test environment with a DOM. The global object is 'window'. By default - * test results are displayed in a table. Any parent windows receive - * callbacks or messages via postMessage() when test events occur. See - * apisample11.html and apisample12.html. - */ - function WindowTestEnvironment() { - this.name_counter = 0; - this.window_cache = null; - this.output_handler = null; - this.all_loaded = false; - var this_obj = this; - this.message_events = []; - this.dispatched_messages = []; - - this.message_functions = { - start: [add_start_callback, remove_start_callback, - function (properties) { - this_obj._dispatch("start_callback", [properties], - {type: "start", properties: properties}); - }], - - test_state: [add_test_state_callback, remove_test_state_callback, - function(test) { - this_obj._dispatch("test_state_callback", [test], - {type: "test_state", - test: test.structured_clone()}); - }], - result: [add_result_callback, remove_result_callback, - function (test) { - this_obj.output_handler.show_status(); - this_obj._dispatch("result_callback", [test], - {type: "result", - test: test.structured_clone()}); - }], - completion: [add_completion_callback, remove_completion_callback, - function (tests, harness_status, asserts) { - var cloned_tests = map(tests, function(test) { - return test.structured_clone(); - }); - this_obj._dispatch("completion_callback", [tests, harness_status], - {type: "complete", - tests: cloned_tests, - status: harness_status.structured_clone(), - asserts: asserts.map(assert => assert.structured_clone())}); - }] - } - - on_event(window, 'load', function() { - this_obj.all_loaded = true; - }); - - on_event(window, 'message', function(event) { - if (event.data && event.data.type === "getmessages" && event.source) { - // A window can post "getmessages" to receive a duplicate of every - // message posted by this environment so far. This allows subscribers - // from fetch_tests_from_window to 'catch up' to the current state of - // this environment. - for (var i = 0; i < this_obj.dispatched_messages.length; ++i) - { - event.source.postMessage(this_obj.dispatched_messages[i], "*"); - } - } - }); - } - - WindowTestEnvironment.prototype._dispatch = function(selector, callback_args, message_arg) { - this.dispatched_messages.push(message_arg); - this._forEach_windows( - function(w, same_origin) { - if (same_origin) { - try { - var has_selector = selector in w; - } catch(e) { - // If document.domain was set at some point same_origin can be - // wrong and the above will fail. - has_selector = false; - } - if (has_selector) { - try { - w[selector].apply(undefined, callback_args); - } catch (e) {} - } - } - if (w !== self) { - w.postMessage(message_arg, "*"); - } - }); - }; - - WindowTestEnvironment.prototype._forEach_windows = function(callback) { - // Iterate over the windows [self ... top, opener]. The callback is passed - // two objects, the first one is the window object itself, the second one - // is a boolean indicating whether or not it's on the same origin as the - // current window. - var cache = this.window_cache; - if (!cache) { - cache = [[self, true]]; - var w = self; - var i = 0; - var so; - while (w != w.parent) { - w = w.parent; - so = is_same_origin(w); - cache.push([w, so]); - i++; - } - w = window.opener; - if (w) { - cache.push([w, is_same_origin(w)]); - } - this.window_cache = cache; - } - - forEach(cache, - function(a) { - callback.apply(null, a); - }); - }; - - WindowTestEnvironment.prototype.on_tests_ready = function() { - var output = new Output(); - this.output_handler = output; - - var this_obj = this; - - add_start_callback(function (properties) { - this_obj.output_handler.init(properties); - }); - - add_test_state_callback(function(test) { - this_obj.output_handler.show_status(); - }); - - add_result_callback(function (test) { - this_obj.output_handler.show_status(); - }); - - // add_completion_callback(function (tests, harness_status, asserts_run) { - // this_obj.output_handler.show_results(tests, harness_status, asserts_run); - // }); - this.setup_messages(settings.message_events); - }; - - WindowTestEnvironment.prototype.setup_messages = function(new_events) { - var this_obj = this; - forEach(settings.message_events, function(x) { - var current_dispatch = this_obj.message_events.indexOf(x) !== -1; - var new_dispatch = new_events.indexOf(x) !== -1; - if (!current_dispatch && new_dispatch) { - this_obj.message_functions[x][0](this_obj.message_functions[x][2]); - } else if (current_dispatch && !new_dispatch) { - this_obj.message_functions[x][1](this_obj.message_functions[x][2]); - } - }); - this.message_events = new_events; - } - - WindowTestEnvironment.prototype.next_default_test_name = function() { - var suffix = this.name_counter > 0 ? " " + this.name_counter : ""; - this.name_counter++; - return get_title() + suffix; - }; - - WindowTestEnvironment.prototype.on_new_harness_properties = function(properties) { - this.output_handler.setup(properties); - if (properties.hasOwnProperty("message_events")) { - this.setup_messages(properties.message_events); - } - }; - - WindowTestEnvironment.prototype.add_on_loaded_callback = function(callback) { - on_event(window, 'load', callback); - }; - - WindowTestEnvironment.prototype.test_timeout = function() { - // var metas = document.getElementsByTagName("meta"); - // for (var i = 0; i < metas.length; i++) { - // if (metas[i].name == "timeout") { - // if (metas[i].content == "long") { - // return settings.harness_timeout.long; - // } - // break; - // } - // } - return settings.harness_timeout.normal; - }; - - /* - * Base TestEnvironment implementation for a generic web worker. - * - * Workers accumulate test results. One or more clients can connect and - * retrieve results from a worker at any time. - * - * WorkerTestEnvironment supports communicating with a client via a - * MessagePort. The mechanism for determining the appropriate MessagePort - * for communicating with a client depends on the type of worker and is - * implemented by the various specializations of WorkerTestEnvironment - * below. - * - * A client document using testharness can use fetch_tests_from_worker() to - * retrieve results from a worker. See apisample16.html. - */ - function WorkerTestEnvironment() { - this.name_counter = 0; - this.all_loaded = true; - this.message_list = []; - this.message_ports = []; - } - - WorkerTestEnvironment.prototype._dispatch = function(message) { - this.message_list.push(message); - for (var i = 0; i < this.message_ports.length; ++i) - { - this.message_ports[i].postMessage(message); - } - }; - - // The only requirement is that port has a postMessage() method. It doesn't - // have to be an instance of a MessagePort, and often isn't. - WorkerTestEnvironment.prototype._add_message_port = function(port) { - this.message_ports.push(port); - for (var i = 0; i < this.message_list.length; ++i) - { - port.postMessage(this.message_list[i]); - } - }; - - WorkerTestEnvironment.prototype.next_default_test_name = function() { - var suffix = this.name_counter > 0 ? " " + this.name_counter : ""; - this.name_counter++; - return get_title() + suffix; - }; - - WorkerTestEnvironment.prototype.on_new_harness_properties = function() {}; - - WorkerTestEnvironment.prototype.on_tests_ready = function() { - var this_obj = this; - add_start_callback( - function(properties) { - this_obj._dispatch({ - type: "start", - properties: properties, - }); - }); - add_test_state_callback( - function(test) { - this_obj._dispatch({ - type: "test_state", - test: test.structured_clone() - }); - }); - add_result_callback( - function(test) { - this_obj._dispatch({ - type: "result", - test: test.structured_clone() - }); - }); - add_completion_callback( - function(tests, harness_status, asserts) { - this_obj._dispatch({ - type: "complete", - tests: map(tests, - function(test) { - return test.structured_clone(); - }), - status: harness_status.structured_clone(), - asserts: asserts.map(assert => assert.structured_clone()), - }); - }); - }; - - WorkerTestEnvironment.prototype.add_on_loaded_callback = function() {}; - - WorkerTestEnvironment.prototype.test_timeout = function() { - // Tests running in a worker don't have a default timeout. I.e. all - // worker tests behave as if settings.explicit_timeout is true. - return null; - }; - - /* - * Dedicated web workers. - * https://html.spec.whatwg.org/multipage/workers.html#dedicatedworkerglobalscope - * - * This class is used as the test_environment when testharness is running - * inside a dedicated worker. - */ - function DedicatedWorkerTestEnvironment() { - WorkerTestEnvironment.call(this); - // self is an instance of DedicatedWorkerGlobalScope which exposes - // a postMessage() method for communicating via the message channel - // established when the worker is created. - this._add_message_port(self); - } - DedicatedWorkerTestEnvironment.prototype = Object.create(WorkerTestEnvironment.prototype); - - DedicatedWorkerTestEnvironment.prototype.on_tests_ready = function() { - WorkerTestEnvironment.prototype.on_tests_ready.call(this); - // In the absence of an onload notification, we a require dedicated - // workers to explicitly signal when the tests are done. - tests.wait_for_finish = true; - }; - - /* - * Shared web workers. - * https://html.spec.whatwg.org/multipage/workers.html#sharedworkerglobalscope - * - * This class is used as the test_environment when testharness is running - * inside a shared web worker. - */ - function SharedWorkerTestEnvironment() { - WorkerTestEnvironment.call(this); - var this_obj = this; - // Shared workers receive message ports via the 'onconnect' event for - // each connection. - self.addEventListener("connect", - function(message_event) { - this_obj._add_message_port(message_event.source); - }, false); - } - SharedWorkerTestEnvironment.prototype = Object.create(WorkerTestEnvironment.prototype); - - SharedWorkerTestEnvironment.prototype.on_tests_ready = function() { - WorkerTestEnvironment.prototype.on_tests_ready.call(this); - // In the absence of an onload notification, we a require shared - // workers to explicitly signal when the tests are done. - tests.wait_for_finish = true; - }; - - /* - * Service workers. - * http://www.w3.org/TR/service-workers/ - * - * This class is used as the test_environment when testharness is running - * inside a service worker. - */ - function ServiceWorkerTestEnvironment() { - WorkerTestEnvironment.call(this); - this.all_loaded = false; - this.on_loaded_callback = null; - var this_obj = this; - self.addEventListener("message", - function(event) { - if (event.data && event.data.type && event.data.type === "connect") { - this_obj._add_message_port(event.source); - } - }, false); - - // The oninstall event is received after the service worker script and - // all imported scripts have been fetched and executed. It's the - // equivalent of an onload event for a document. All tests should have - // been added by the time this event is received, thus it's not - // necessary to wait until the onactivate event. However, tests for - // installed service workers need another event which is equivalent to - // the onload event because oninstall is fired only on installation. The - // onmessage event is used for that purpose since tests using - // testharness.js should ask the result to its service worker by - // PostMessage. If the onmessage event is triggered on the service - // worker's context, that means the worker's script has been evaluated. - on_event(self, "install", on_all_loaded); - on_event(self, "message", on_all_loaded); - function on_all_loaded() { - if (this_obj.all_loaded) - return; - this_obj.all_loaded = true; - if (this_obj.on_loaded_callback) { - this_obj.on_loaded_callback(); - } - } - } - - ServiceWorkerTestEnvironment.prototype = Object.create(WorkerTestEnvironment.prototype); - - ServiceWorkerTestEnvironment.prototype.add_on_loaded_callback = function(callback) { - if (this.all_loaded) { - callback(); - } else { - this.on_loaded_callback = callback; - } - }; - - /* - * Shadow realms. - * https://github.com/tc39/proposal-shadowrealm - * - * This class is used as the test_environment when testharness is running - * inside a shadow realm. - */ - function ShadowRealmTestEnvironment() { - WorkerTestEnvironment.call(this); - this.all_loaded = false; - this.on_loaded_callback = null; - } - - ShadowRealmTestEnvironment.prototype = Object.create(WorkerTestEnvironment.prototype); - - /** - * Signal to the test environment that the tests are ready and the on-loaded - * callback should be run. - * - * Shadow realms are not *really* a DOM context: they have no `onload` or similar - * event for us to use to set up the test environment; so, instead, this method - * is manually triggered from the incubating realm - * - * @param {Function} message_destination - a function that receives JSON-serializable - * data to send to the incubating realm, in the same format as used by RemoteContext - */ - ShadowRealmTestEnvironment.prototype.begin = function(message_destination) { - if (this.all_loaded) { - throw new Error("Tried to start a shadow realm test environment after it has already started"); - } - var fakeMessagePort = {}; - fakeMessagePort.postMessage = message_destination; - this._add_message_port(fakeMessagePort); - this.all_loaded = true; - if (this.on_loaded_callback) { - this.on_loaded_callback(); - } - }; - - ShadowRealmTestEnvironment.prototype.add_on_loaded_callback = function(callback) { - if (this.all_loaded) { - callback(); - } else { - this.on_loaded_callback = callback; - } - }; - - /* - * JavaScript shells. - * - * This class is used as the test_environment when testharness is running - * inside a JavaScript shell. - */ - function ShellTestEnvironment() { - this.name_counter = 0; - this.all_loaded = false; - this.on_loaded_callback = null; - Promise.resolve().then(function() { - this.all_loaded = true - if (this.on_loaded_callback) { - this.on_loaded_callback(); - } - }.bind(this)); - this.message_list = []; - this.message_ports = []; - } - - ShellTestEnvironment.prototype.next_default_test_name = function() { - var suffix = this.name_counter > 0 ? " " + this.name_counter : ""; - this.name_counter++; - return get_title() + suffix; - }; - - ShellTestEnvironment.prototype.on_new_harness_properties = function() {}; - - ShellTestEnvironment.prototype.on_tests_ready = function() {}; - - ShellTestEnvironment.prototype.add_on_loaded_callback = function(callback) { - if (this.all_loaded) { - callback(); - } else { - this.on_loaded_callback = callback; - } - }; - - ShellTestEnvironment.prototype.test_timeout = function() { - // Tests running in a shell don't have a default timeout, so behave as - // if settings.explicit_timeout is true. - return null; - }; - - function create_test_environment() { - if ('document' in global_scope) { - return new WindowTestEnvironment(); - } - if ('DedicatedWorkerGlobalScope' in global_scope && - global_scope instanceof DedicatedWorkerGlobalScope) { - return new DedicatedWorkerTestEnvironment(); - } - if ('SharedWorkerGlobalScope' in global_scope && - global_scope instanceof SharedWorkerGlobalScope) { - return new SharedWorkerTestEnvironment(); - } - if ('ServiceWorkerGlobalScope' in global_scope && - global_scope instanceof ServiceWorkerGlobalScope) { - return new ServiceWorkerTestEnvironment(); - } - if ('WorkerGlobalScope' in global_scope && - global_scope instanceof WorkerGlobalScope) { - return new DedicatedWorkerTestEnvironment(); - } - /* Shadow realm global objects are _ordinary_ objects (i.e. their prototype is - * Object) so we don't have a nice `instanceof` test to use; instead, we - * check if the there is a GLOBAL.isShadowRealm() property - * on the global object. that was set by the test harness when it - * created the ShadowRealm. - */ - if (global_scope.GLOBAL && global_scope.GLOBAL.isShadowRealm()) { - return new ShadowRealmTestEnvironment(); - } - - return new ShellTestEnvironment(); - } - - var test_environment = create_test_environment(); - - function is_shared_worker(worker) { - return 'SharedWorker' in global_scope && worker instanceof SharedWorker; - } - - function is_service_worker(worker) { - // The worker object may be from another execution context, - // so do not use instanceof here. - return 'ServiceWorker' in global_scope && - Object.prototype.toString.call(worker) == '[object ServiceWorker]'; - } - - var seen_func_name = Object.create(null); - - function get_test_name(func, name) - { - if (name) { - return name; - } - - if (func) { - var func_code = func.toString(); - - // Try and match with brackets, but fallback to matching without - var arrow = func_code.match(/^\(\)\s*=>\s*(?:{(.*)}\s*|(.*))$/); - - // Check for JS line separators - if (arrow !== null && !/[\u000A\u000D\u2028\u2029]/.test(func_code)) { - var trimmed = (arrow[1] !== undefined ? arrow[1] : arrow[2]).trim(); - // drop trailing ; if there's no earlier ones - trimmed = trimmed.replace(/^([^;]*)(;\s*)+$/, "$1"); - - if (trimmed) { - let name = trimmed; - if (seen_func_name[trimmed]) { - // This subtest name already exists, so add a suffix. - name += " " + seen_func_name[trimmed]; - } else { - seen_func_name[trimmed] = 0; - } - seen_func_name[trimmed] += 1; - return name; - } - } - } - - return test_environment.next_default_test_name(); - } - - /** - * @callback TestFunction - * @param {Test} test - The test currnetly being run. - * @param {Any[]} args - Additional args to pass to function. - * - */ - - /** - * Create a synchronous test - * - * @param {TestFunction} func - Test function. This is executed - * immediately. If it returns without error, the test status is - * set to ``PASS``. If it throws an :js:class:`AssertionError`, or - * any other exception, the test status is set to ``FAIL`` - * (typically from an `assert` function). - * @param {String} name - Test name. This must be unique in a - * given file and must be invariant between runs. - */ - function test(func, name, properties) - { - if (tests.promise_setup_called) { - tests.status.status = tests.status.ERROR; - tests.status.message = '`test` invoked after `promise_setup`'; - tests.complete(); - } - var test_name = get_test_name(func, name); - var test_obj = new Test(test_name, properties); - var value = test_obj.step(func, test_obj, test_obj); - - if (value !== undefined) { - var msg = 'Test named "' + test_name + - '" passed a function to `test` that returned a value.'; - - try { - if (value && typeof value.then === 'function') { - msg += ' Consider using `promise_test` instead when ' + - 'using Promises or async/await.'; - } - } catch (err) {} - - tests.status.status = tests.status.ERROR; - tests.status.message = msg; - } - - if (test_obj.phase === test_obj.phases.STARTED) { - test_obj.done(); - } - } - - /** - * Create an asynchronous test - * - * @param {TestFunction|string} funcOrName - Initial step function - * to call immediately with the test name as an argument (if any), - * or name of the test. - * @param {String} name - Test name (if a test function was - * provided). This must be unique in a given file and must be - * invariant between runs. - * @returns {Test} An object representing the ongoing test. - */ - function async_test(func, name, properties) - { - if (tests.promise_setup_called) { - tests.status.status = tests.status.ERROR; - tests.status.message = '`async_test` invoked after `promise_setup`'; - tests.complete(); - } - if (typeof func !== "function") { - properties = name; - name = func; - func = null; - } - var test_name = get_test_name(func, name); - var test_obj = new Test(test_name, properties); - if (func) { - var value = test_obj.step(func, test_obj, test_obj); - - // Test authors sometimes return values to async_test, expecting us - // to handle the value somehow. Make doing so a harness error to be - // clear this is invalid, and point authors to promise_test if it - // may be appropriate. - // - // Note that we only perform this check on the initial function - // passed to async_test, not on any later steps - we haven't seen a - // consistent problem with those (and it's harder to check). - if (value !== undefined) { - var msg = 'Test named "' + test_name + - '" passed a function to `async_test` that returned a value.'; - - try { - if (value && typeof value.then === 'function') { - msg += ' Consider using `promise_test` instead when ' + - 'using Promises or async/await.'; - } - } catch (err) {} - - tests.set_status(tests.status.ERROR, msg); - tests.complete(); - } - } - return test_obj; - } - - /** - * Create a promise test. - * - * Promise tests are tests which are represented by a promise - * object. If the promise is fulfilled the test passes, if it's - * rejected the test fails, otherwise the test passes. - * - * @param {TestFunction} func - Test function. This must return a - * promise. The test is automatically marked as complete once the - * promise settles. - * @param {String} name - Test name. This must be unique in a - * given file and must be invariant between runs. - */ - function promise_test(func, name, properties) { - if (typeof func !== "function") { - properties = name; - name = func; - func = null; - } - var test_name = get_test_name(func, name); - var test = new Test(test_name, properties); - test._is_promise_test = true; - - // If there is no promise tests queue make one. - if (!tests.promise_tests) { - tests.promise_tests = Promise.resolve(); - } - tests.promise_tests = tests.promise_tests.then(function() { - return new Promise(function(resolve) { - var promise = test.step(func, test, test); - - test.step(function() { - assert(!!promise, "promise_test", null, - "test body must return a 'thenable' object (received ${value})", - {value:promise}); - assert(typeof promise.then === "function", "promise_test", null, - "test body must return a 'thenable' object (received an object with no `then` method)", - null); - }); - - // Test authors may use the `step` method within a - // `promise_test` even though this reflects a mixture of - // asynchronous control flow paradigms. The "done" callback - // should be registered prior to the resolution of the - // user-provided Promise to avoid timeouts in cases where the - // Promise does not settle but a `step` function has thrown an - // error. - add_test_done_callback(test, resolve); - - Promise.resolve(promise) - .catch(test.step_func( - function(value) { - if (value instanceof AssertionError) { - throw value; - } - assert(false, "promise_test", null, - "Unhandled rejection with value: ${value}", {value:value}); - })) - .then(function() { - test.done(); - }); - }); - }); - } - - /** - * Make a copy of a Promise in the current realm. - * - * @param {Promise} promise the given promise that may be from a different - * realm - * @returns {Promise} - * - * An arbitrary promise provided by the caller may have originated - * in another frame that have since navigated away, rendering the - * frame's document inactive. Such a promise cannot be used with - * `await` or Promise.resolve(), as microtasks associated with it - * may be prevented from being run. See `issue - * 5319`_ for a - * particular case. - * - * In functions we define here, there is an expectation from the caller - * that the promise is from the current realm, that can always be used with - * `await`, etc. We therefore create a new promise in this realm that - * inherit the value and status from the given promise. - */ - - function bring_promise_to_current_realm(promise) { - return new Promise(promise.then.bind(promise)); - } - - /** - * Assert that a Promise is rejected with the right ECMAScript exception. - * - * @param {Test} test - the `Test` to use for the assertion. - * @param {Function} constructor - The expected exception constructor. - * @param {Promise} promise - The promise that's expected to - * reject with the given exception. - * @param {string} [description] Error message to add to assert in case of - * failure. - */ - function promise_rejects_js(test, constructor, promise, description) { - return bring_promise_to_current_realm(promise) - .then(test.unreached_func("Should have rejected: " + description)) - .catch(function(e) { - assert_throws_js_impl(constructor, function() { throw e }, - description, "promise_rejects_js"); - }); - } - - /** - * Assert that a Promise is rejected with the right DOMException. - * - * For the remaining arguments, there are two ways of calling - * promise_rejects_dom: - * - * 1) If the DOMException is expected to come from the current global, the - * third argument should be the promise expected to reject, and a fourth, - * optional, argument is the assertion description. - * - * 2) If the DOMException is expected to come from some other global, the - * third argument should be the DOMException constructor from that global, - * the fourth argument the promise expected to reject, and the fifth, - * optional, argument the assertion description. - * - * @param {Test} test - the `Test` to use for the assertion. - * @param {number|string} type - See documentation for - * `assert_throws_dom <#assert_throws_dom>`_. - * @param {Function} promiseOrConstructor - Either the constructor - * for the expected exception (if the exception comes from another - * global), or the promise that's expected to reject (if the - * exception comes from the current global). - * @param {Function|string} descriptionOrPromise - Either the - * promise that's expected to reject (if the exception comes from - * another global), or the optional description of the condition - * being tested (if the exception comes from the current global). - * @param {string} [description] - Description of the condition - * being tested (if the exception comes from another global). - * - */ - function promise_rejects_dom(test, type, promiseOrConstructor, descriptionOrPromise, maybeDescription) { - let constructor, promise, description; - if (typeof promiseOrConstructor === "function" && - promiseOrConstructor.name === "DOMException") { - constructor = promiseOrConstructor; - promise = descriptionOrPromise; - description = maybeDescription; - } else { - constructor = self.DOMException; - promise = promiseOrConstructor; - description = descriptionOrPromise; - assert(maybeDescription === undefined, - "Too many args pased to no-constructor version of promise_rejects_dom"); - } - return bring_promise_to_current_realm(promise) - .then(test.unreached_func("Should have rejected: " + description)) - .catch(function(e) { - assert_throws_dom_impl(type, function() { throw e }, description, - "promise_rejects_dom", constructor); - }); - } - - /** - * Assert that a Promise is rejected with the provided value. - * - * @param {Test} test - the `Test` to use for the assertion. - * @param {Any} exception - The expected value of the rejected promise. - * @param {Promise} promise - The promise that's expected to - * reject. - * @param {string} [description] Error message to add to assert in case of - * failure. - */ - function promise_rejects_exactly(test, exception, promise, description) { - return bring_promise_to_current_realm(promise) - .then(test.unreached_func("Should have rejected: " + description)) - .catch(function(e) { - assert_throws_exactly_impl(exception, function() { throw e }, - description, "promise_rejects_exactly"); - }); - } - - /** - * Allow DOM events to be handled using Promises. - * - * This can make it a lot easier to test a very specific series of events, - * including ensuring that unexpected events are not fired at any point. - * - * `EventWatcher` will assert if an event occurs while there is no `wait_for` - * created Promise waiting to be fulfilled, or if the event is of a different type - * to the type currently expected. This ensures that only the events that are - * expected occur, in the correct order, and with the correct timing. - * - * @constructor - * @param {Test} test - The `Test` to use for the assertion. - * @param {EventTarget} watchedNode - The target expected to receive the events. - * @param {string[]} eventTypes - List of events to watch for. - * @param {Promise} timeoutPromise - Promise that will cause the - * test to be set to `TIMEOUT` once fulfilled. - * - */ - function EventWatcher(test, watchedNode, eventTypes, timeoutPromise) - { - if (typeof eventTypes == 'string') { - eventTypes = [eventTypes]; - } - - var waitingFor = null; - - // This is null unless we are recording all events, in which case it - // will be an Array object. - var recordedEvents = null; - - var eventHandler = test.step_func(function(evt) { - assert_true(!!waitingFor, - 'Not expecting event, but got ' + evt.type + ' event'); - assert_equals(evt.type, waitingFor.types[0], - 'Expected ' + waitingFor.types[0] + ' event, but got ' + - evt.type + ' event instead'); - - if (Array.isArray(recordedEvents)) { - recordedEvents.push(evt); - } - - if (waitingFor.types.length > 1) { - // Pop first event from array - waitingFor.types.shift(); - return; - } - // We need to null out waitingFor before calling the resolve function - // since the Promise's resolve handlers may call wait_for() which will - // need to set waitingFor. - var resolveFunc = waitingFor.resolve; - waitingFor = null; - // Likewise, we should reset the state of recordedEvents. - var result = recordedEvents || evt; - recordedEvents = null; - resolveFunc(result); - }); - - for (var i = 0; i < eventTypes.length; i++) { - watchedNode.addEventListener(eventTypes[i], eventHandler, false); - } - - /** - * Returns a Promise that will resolve after the specified event or - * series of events has occurred. - * - * @param {Object} options An optional options object. If the 'record' property - * on this object has the value 'all', when the Promise - * returned by this function is resolved, *all* Event - * objects that were waited for will be returned as an - * array. - * - * @example - * const watcher = new EventWatcher(t, div, [ 'animationstart', - * 'animationiteration', - * 'animationend' ]); - * return watcher.wait_for([ 'animationstart', 'animationend' ], - * { record: 'all' }).then(evts => { - * assert_equals(evts[0].elapsedTime, 0.0); - * assert_equals(evts[1].elapsedTime, 2.0); - * }); - */ - this.wait_for = function(types, options) { - if (waitingFor) { - return Promise.reject('Already waiting for an event or events'); - } - if (typeof types == 'string') { - types = [types]; - } - if (options && options.record && options.record === 'all') { - recordedEvents = []; - } - return new Promise(function(resolve, reject) { - var timeout = test.step_func(function() { - // If the timeout fires after the events have been received - // or during a subsequent call to wait_for, ignore it. - if (!waitingFor || waitingFor.resolve !== resolve) - return; - - // This should always fail, otherwise we should have - // resolved the promise. - assert_true(waitingFor.types.length == 0, - 'Timed out waiting for ' + waitingFor.types.join(', ')); - var result = recordedEvents; - recordedEvents = null; - var resolveFunc = waitingFor.resolve; - waitingFor = null; - resolveFunc(result); - }); - - if (timeoutPromise) { - timeoutPromise().then(timeout); - } - - waitingFor = { - types: types, - resolve: resolve, - reject: reject - }; - }); - }; - - /** - * Stop listening for events - */ - function stop_watching() { - for (var i = 0; i < eventTypes.length; i++) { - watchedNode.removeEventListener(eventTypes[i], eventHandler, false); - } - }; - - test._add_cleanup(stop_watching); - - return this; - } - expose(EventWatcher, 'EventWatcher'); - - /** - * @typedef {Object} SettingsObject - * @property {bool} single_test - Use the single-page-test - * mode. In this mode the Document represents a single - * `async_test`. Asserts may be used directly without requiring - * `Test.step` or similar wrappers, and any exceptions set the - * status of the test rather than the status of the harness. - * @property {bool} allow_uncaught_exception - don't treat an - * uncaught exception as an error; needed when e.g. testing the - * `window.onerror` handler. - * @property {boolean} explicit_done - Wait for a call to `done()` - * before declaring all tests complete (this is always true for - * single-page tests). - * @property hide_test_state - hide the test state output while - * the test is running; This is helpful when the output of the test state - * may interfere the test results. - * @property {bool} explicit_timeout - disable file timeout; only - * stop waiting for results when the `timeout()` function is - * called This should typically only be set for manual tests, or - * by a test runner that providees its own timeout mechanism. - * @property {number} timeout_multiplier - Multiplier to apply to - * per-test timeouts. This should only be set by a test runner. - * @property {Document} output_document - The document to which - * results should be logged. By default this is the current - * document but could be an ancestor document in some cases e.g. a - * SVG test loaded in an HTML wrapper - * - */ - - /** - * Configure the harness - * - * @param {Function|SettingsObject} funcOrProperties - Either a - * setup function to run, or a set of properties. If this is a - * function that function is run synchronously. Any exception in - * the function will set the overall harness status to `ERROR`. - * @param {SettingsObject} maybeProperties - An object containing - * the settings to use, if the first argument is a function. - * - */ - function setup(func_or_properties, maybe_properties) - { - var func = null; - var properties = {}; - if (arguments.length === 2) { - func = func_or_properties; - properties = maybe_properties; - } else if (func_or_properties instanceof Function) { - func = func_or_properties; - } else { - properties = func_or_properties; - } - tests.setup(func, properties); - test_environment.on_new_harness_properties(properties); - } - - /** - * Configure the harness, waiting for a promise to resolve - * before running any `promise_test` tests. - * - * @param {Function} func - Function returning a promise that's - * run synchronously. Promise tests are not run until after this - * function has resolved. - * @param {SettingsObject} [properties] - An object containing - * the harness settings to use. - * - */ - function promise_setup(func, properties={}) - { - if (typeof func !== "function") { - tests.set_status(tests.status.ERROR, - "promise_test invoked without a function"); - tests.complete(); - return; - } - tests.promise_setup_called = true; - - if (!tests.promise_tests) { - tests.promise_tests = Promise.resolve(); - } - - tests.promise_tests = tests.promise_tests - .then(function() - { - var result; - - tests.setup(null, properties); - result = func(); - test_environment.on_new_harness_properties(properties); - - if (!result || typeof result.then !== "function") { - throw "Non-thenable returned by function passed to `promise_setup`"; - } - return result; - }) - .catch(function(e) - { - tests.set_status(tests.status.ERROR, - String(e), - e && e.stack); - tests.complete(); - }); - } - - /** - * Mark test loading as complete. - * - * Typically this function is called implicitly on page load; it's - * only necessary for users to call this when either the - * ``explicit_done`` or ``single_page`` properties have been set - * via the :js:func:`setup` function. - * - * For single page tests this marks the test as complete and sets its status. - * For other tests, this marks test loading as complete, but doesn't affect ongoing tests. - */ - function done() { - if (tests.tests.length === 0) { - // `done` is invoked after handling uncaught exceptions, so if the - // harness status is already set, the corresponding message is more - // descriptive than the generic message defined here. - if (tests.status.status === null) { - tests.status.status = tests.status.ERROR; - tests.status.message = "done() was called without first defining any tests"; - } - - tests.complete(); - return; - } - if (tests.file_is_test) { - // file is test files never have asynchronous cleanup logic, - // meaning the fully-synchronous `done` function can be used here. - tests.tests[0].done(); - } - tests.end_wait(); - } - - /** - * @deprecated generate a list of tests from a function and list of arguments - * - * This is deprecated because it runs all the tests outside of the test functions - * and as a result any test throwing an exception will result in no tests being - * run. In almost all cases, you should simply call test within the loop you would - * use to generate the parameter list array. - * - * @param {Function} func - The function that will be called for each generated tests. - * @param {Any[][]} args - An array of arrays. Each nested array - * has the structure `[testName, ...testArgs]`. For each of these nested arrays - * array, a test is generated with name `testName` and test function equivalent to - * `func(..testArgs)`. - */ - function generate_tests(func, args, properties) { - forEach(args, function(x, i) - { - var name = x[0]; - test(function() - { - func.apply(this, x.slice(1)); - }, - name, - Array.isArray(properties) ? properties[i] : properties); - }); - } - - /** - * @deprecated - * - * Register a function as a DOM event listener to the - * given object for the event bubbling phase. - * - * @param {EventTarget} object - Event target - * @param {string} event - Event name - * @param {Function} callback - Event handler. - */ - function on_event(object, event, callback) - { - object.addEventListener(event, callback, false); - } - - /** - * Global version of :js:func:`Test.step_timeout` for use in single page tests. - * - * @param {Function} func - Function to run after the timeout - * @param {number} timeout - Time in ms to wait before running the - * test step. The actual wait time is ``timeout`` x - * ``timeout_multiplier``. - */ - function step_timeout(func, timeout) { - var outer_this = this; - var args = Array.prototype.slice.call(arguments, 2); - return setTimeout(function() { - func.apply(outer_this, args); - }, timeout * tests.timeout_multiplier); - } - - expose(test, 'test'); - expose(async_test, 'async_test'); - expose(promise_test, 'promise_test'); - expose(promise_rejects_js, 'promise_rejects_js'); - expose(promise_rejects_dom, 'promise_rejects_dom'); - expose(promise_rejects_exactly, 'promise_rejects_exactly'); - expose(generate_tests, 'generate_tests'); - expose(setup, 'setup'); - expose(promise_setup, 'promise_setup'); - expose(done, 'done'); - expose(on_event, 'on_event'); - expose(step_timeout, 'step_timeout'); - - /* - * Return a string truncated to the given length, with ... added at the end - * if it was longer. - */ - function truncate(s, len) - { - if (s.length > len) { - return s.substring(0, len - 3) + "..."; - } - return s; - } - - /* - * Return true if object is probably a Node object. - */ - function is_node(object) - { - // I use duck-typing instead of instanceof, because - // instanceof doesn't work if the node is from another window (like an - // iframe's contentWindow): - // http://www.w3.org/Bugs/Public/show_bug.cgi?id=12295 - try { - var has_node_properties = ("nodeType" in object && - "nodeName" in object && - "nodeValue" in object && - "childNodes" in object); - } catch (e) { - // We're probably cross-origin, which means we aren't a node - return false; - } - - if (has_node_properties) { - try { - object.nodeType; - } catch (e) { - // The object is probably Node.prototype or another prototype - // object that inherits from it, and not a Node instance. - return false; - } - return true; - } - return false; - } - - var replacements = { - "0": "0", - "1": "x01", - "2": "x02", - "3": "x03", - "4": "x04", - "5": "x05", - "6": "x06", - "7": "x07", - "8": "b", - "9": "t", - "10": "n", - "11": "v", - "12": "f", - "13": "r", - "14": "x0e", - "15": "x0f", - "16": "x10", - "17": "x11", - "18": "x12", - "19": "x13", - "20": "x14", - "21": "x15", - "22": "x16", - "23": "x17", - "24": "x18", - "25": "x19", - "26": "x1a", - "27": "x1b", - "28": "x1c", - "29": "x1d", - "30": "x1e", - "31": "x1f", - "0xfffd": "ufffd", - "0xfffe": "ufffe", - "0xffff": "uffff", - }; - - /** - * Convert a value to a nice, human-readable string - * - * When many JavaScript Object values are coerced to a String, the - * resulting value will be ``"[object Object]"``. This obscures - * helpful information, making the coerced value unsuitable for - * use in assertion messages, test names, and debugging - * statements. `format_value` produces more distinctive string - * representations of many kinds of objects, including arrays and - * the more important DOM Node types. It also translates String - * values containing control characters to include human-readable - * representations. - * - * @example - * // "Document node with 2 children" - * format_value(document); - * @example - * // "\"foo\\uffffbar\"" - * format_value("foo\uffffbar"); - * @example - * // "[-0, Infinity]" - * format_value([-0, Infinity]); - * @param {Any} val - The value to convert to a string. - * @returns {string} - A string representation of ``val``, optimised for human readability. - */ - function format_value(val, seen) - { - if (!seen) { - seen = []; - } - if (typeof val === "object" && val !== null) { - if (seen.indexOf(val) >= 0) { - return "[...]"; - } - seen.push(val); - } - if (Array.isArray(val)) { - let output = "["; - if (val.beginEllipsis !== undefined) { - output += "…, "; - } - output += val.map(function(x) {return format_value(x, seen);}).join(", "); - if (val.endEllipsis !== undefined) { - output += ", …"; - } - return output + "]"; - } - - switch (typeof val) { - case "string": - val = val.replace(/\\/g, "\\\\"); - for (var p in replacements) { - var replace = "\\" + replacements[p]; - val = val.replace(RegExp(String.fromCharCode(p), "g"), replace); - } - return '"' + val.replace(/"/g, '\\"') + '"'; - case "boolean": - case "undefined": - return String(val); - case "number": - // In JavaScript, -0 === 0 and String(-0) == "0", so we have to - // special-case. - if (val === -0 && 1/val === -Infinity) { - return "-0"; - } - return String(val); - case "object": - if (val === null) { - return "null"; - } - - // Special-case Node objects, since those come up a lot in my tests. I - // ignore namespaces. - if (is_node(val)) { - switch (val.nodeType) { - case Node.ELEMENT_NODE: - var ret = "<" + val.localName; - for (var i = 0; i < val.attributes.length; i++) { - ret += " " + val.attributes[i].name + '="' + val.attributes[i].value + '"'; - } - ret += ">" + val.innerHTML + ""; - return "Element node " + truncate(ret, 60); - case Node.TEXT_NODE: - return 'Text node "' + truncate(val.data, 60) + '"'; - case Node.PROCESSING_INSTRUCTION_NODE: - return "ProcessingInstruction node with target " + format_value(truncate(val.target, 60)) + " and data " + format_value(truncate(val.data, 60)); - case Node.COMMENT_NODE: - return "Comment node "; - case Node.DOCUMENT_NODE: - return "Document node with " + val.childNodes.length + (val.childNodes.length == 1 ? " child" : " children"); - case Node.DOCUMENT_TYPE_NODE: - return "DocumentType node"; - case Node.DOCUMENT_FRAGMENT_NODE: - return "DocumentFragment node with " + val.childNodes.length + (val.childNodes.length == 1 ? " child" : " children"); - default: - return "Node object of unknown type"; - } - } - - /* falls through */ - default: - try { - return typeof val + ' "' + truncate(String(val), 1000) + '"'; - } catch(e) { - return ("[stringifying object threw " + String(e) + - " with type " + String(typeof e) + "]"); - } - } - } - expose(format_value, "format_value"); - - /* - * Assertions - */ - - function expose_assert(f, name) { - function assert_wrapper(...args) { - let status = Test.statuses.TIMEOUT; - let stack = null; - let new_assert_index = null; - try { - if (settings.debug) { - console.debug("ASSERT", name, tests.current_test && tests.current_test.name, args); - } - if (tests.output) { - tests.set_assert(name, args); - // Remember the newly pushed assert's index, because `apply` - // below might push new asserts. - new_assert_index = tests.asserts_run.length - 1; - } - const rv = f.apply(undefined, args); - status = Test.statuses.PASS; - return rv; - } catch(e) { - status = Test.statuses.FAIL; - stack = e.stack ? e.stack : null; - throw e; - } finally { - if (tests.output && !stack) { - stack = get_stack(); - } - if (tests.output) { - tests.set_assert_status(new_assert_index, status, stack); - } - } - } - expose(assert_wrapper, name); - } - - /** - * Assert that ``actual`` is strictly true - * - * @param {Any} actual - Value that is asserted to be true - * @param {string} [description] - Description of the condition being tested - */ - function assert_true(actual, description) - { - assert(actual === true, "assert_true", description, - "expected true got ${actual}", {actual:actual}); - } - expose_assert(assert_true, "assert_true"); - - /** - * Assert that ``actual`` is strictly false - * - * @param {Any} actual - Value that is asserted to be false - * @param {string} [description] - Description of the condition being tested - */ - function assert_false(actual, description) - { - assert(actual === false, "assert_false", description, - "expected false got ${actual}", {actual:actual}); - } - expose_assert(assert_false, "assert_false"); - - function same_value(x, y) { - if (y !== y) { - //NaN case - return x !== x; - } - if (x === 0 && y === 0) { - //Distinguish +0 and -0 - return 1/x === 1/y; - } - return x === y; - } - - /** - * Assert that ``actual`` is the same value as ``expected``. - * - * For objects this compares by object identity; for primitives - * this distinguishes between 0 and -0, and has correct handling - * of NaN. - * - * @param {Any} actual - Test value. - * @param {Any} expected - Expected value. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_equals(actual, expected, description) - { - /* - * Test if two primitives are equal or two objects - * are the same object - */ - if (typeof actual != typeof expected) { - assert(false, "assert_equals", description, - "expected (" + typeof expected + ") ${expected} but got (" + typeof actual + ") ${actual}", - {expected:expected, actual:actual}); - return; - } - assert(same_value(actual, expected), "assert_equals", description, - "expected ${expected} but got ${actual}", - {expected:expected, actual:actual}); - } - expose_assert(assert_equals, "assert_equals"); - - /** - * Assert that ``actual`` is not the same value as ``expected``. - * - * Comparison is as for :js:func:`assert_equals`. - * - * @param {Any} actual - Test value. - * @param {Any} expected - The value ``actual`` is expected to be different to. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_not_equals(actual, expected, description) - { - assert(!same_value(actual, expected), "assert_not_equals", description, - "got disallowed value ${actual}", - {actual:actual}); - } - expose_assert(assert_not_equals, "assert_not_equals"); - - /** - * Assert that ``expected`` is an array and ``actual`` is one of the members. - * This is implemented using ``indexOf``, so doesn't handle NaN or ±0 correctly. - * - * @param {Any} actual - Test value. - * @param {Array} expected - An array that ``actual`` is expected to - * be a member of. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_in_array(actual, expected, description) - { - assert(expected.indexOf(actual) != -1, "assert_in_array", description, - "value ${actual} not in array ${expected}", - {actual:actual, expected:expected}); - } - expose_assert(assert_in_array, "assert_in_array"); - - // This function was deprecated in July of 2015. - // See https://github.com/web-platform-tests/wpt/issues/2033 - /** - * @deprecated - * Recursively compare two objects for equality. - * - * See `Issue 2033 - * `_ for - * more information. - * - * @param {Object} actual - Test value. - * @param {Object} expected - Expected value. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_object_equals(actual, expected, description) - { - assert(typeof actual === "object" && actual !== null, "assert_object_equals", description, - "value is ${actual}, expected object", - {actual: actual}); - //This needs to be improved a great deal - function check_equal(actual, expected, stack) - { - stack.push(actual); - - var p; - for (p in actual) { - assert(expected.hasOwnProperty(p), "assert_object_equals", description, - "unexpected property ${p}", {p:p}); - - if (typeof actual[p] === "object" && actual[p] !== null) { - if (stack.indexOf(actual[p]) === -1) { - check_equal(actual[p], expected[p], stack); - } - } else { - assert(same_value(actual[p], expected[p]), "assert_object_equals", description, - "property ${p} expected ${expected} got ${actual}", - {p:p, expected:expected[p], actual:actual[p]}); - } - } - for (p in expected) { - assert(actual.hasOwnProperty(p), - "assert_object_equals", description, - "expected property ${p} missing", {p:p}); - } - stack.pop(); - } - check_equal(actual, expected, []); - } - expose_assert(assert_object_equals, "assert_object_equals"); - - /** - * Assert that ``actual`` and ``expected`` are both arrays, and that the array properties of - * ``actual`` and ``expected`` are all the same value (as for :js:func:`assert_equals`). - * - * @param {Array} actual - Test array. - * @param {Array} expected - Array that is expected to contain the same values as ``actual``. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_array_equals(actual, expected, description) - { - const max_array_length = 20; - function shorten_array(arr, offset = 0) { - // Make ", …" only show up when it would likely reduce the length, not accounting for - // fonts. - if (arr.length < max_array_length + 2) { - return arr; - } - // By default we want half the elements after the offset and half before - // But if that takes us past the end of the array, we have more before, and - // if it takes us before the start we have more after. - const length_after_offset = Math.floor(max_array_length / 2); - let upper_bound = Math.min(length_after_offset + offset, arr.length); - const lower_bound = Math.max(upper_bound - max_array_length, 0); - - if (lower_bound === 0) { - upper_bound = max_array_length; - } - - const output = arr.slice(lower_bound, upper_bound); - if (lower_bound > 0) { - output.beginEllipsis = true; - } - if (upper_bound < arr.length) { - output.endEllipsis = true; - } - return output; - } - - assert(typeof actual === "object" && actual !== null && "length" in actual, - "assert_array_equals", description, - "value is ${actual}, expected array", - {actual:actual}); - assert(actual.length === expected.length, - "assert_array_equals", description, - "lengths differ, expected array ${expected} length ${expectedLength}, got ${actual} length ${actualLength}", - {expected:shorten_array(expected, expected.length - 1), expectedLength:expected.length, - actual:shorten_array(actual, actual.length - 1), actualLength:actual.length - }); - - for (var i = 0; i < actual.length; i++) { - assert(actual.hasOwnProperty(i) === expected.hasOwnProperty(i), - "assert_array_equals", description, - "expected property ${i} to be ${expected} but was ${actual} (expected array ${arrayExpected} got ${arrayActual})", - {i:i, expected:expected.hasOwnProperty(i) ? "present" : "missing", - actual:actual.hasOwnProperty(i) ? "present" : "missing", - arrayExpected:shorten_array(expected, i), arrayActual:shorten_array(actual, i)}); - assert(same_value(expected[i], actual[i]), - "assert_array_equals", description, - "expected property ${i} to be ${expected} but got ${actual} (expected array ${arrayExpected} got ${arrayActual})", - {i:i, expected:expected[i], actual:actual[i], - arrayExpected:shorten_array(expected, i), arrayActual:shorten_array(actual, i)}); - } - } - expose_assert(assert_array_equals, "assert_array_equals"); - - /** - * Assert that each array property in ``actual`` is a number within - * ± `epsilon` of the corresponding property in `expected`. - * - * @param {Array} actual - Array of test values. - * @param {Array} expected - Array of values expected to be close to the values in ``actual``. - * @param {number} epsilon - Magnitude of allowed difference - * between each value in ``actual`` and ``expected``. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_array_approx_equals(actual, expected, epsilon, description) - { - /* - * Test if two primitive arrays are equal within +/- epsilon - */ - assert(actual.length === expected.length, - "assert_array_approx_equals", description, - "lengths differ, expected ${expected} got ${actual}", - {expected:expected.length, actual:actual.length}); - - for (var i = 0; i < actual.length; i++) { - assert(actual.hasOwnProperty(i) === expected.hasOwnProperty(i), - "assert_array_approx_equals", description, - "property ${i}, property expected to be ${expected} but was ${actual}", - {i:i, expected:expected.hasOwnProperty(i) ? "present" : "missing", - actual:actual.hasOwnProperty(i) ? "present" : "missing"}); - assert(typeof actual[i] === "number", - "assert_array_approx_equals", description, - "property ${i}, expected a number but got a ${type_actual}", - {i:i, type_actual:typeof actual[i]}); - assert(Math.abs(actual[i] - expected[i]) <= epsilon, - "assert_array_approx_equals", description, - "property ${i}, expected ${expected} +/- ${epsilon}, expected ${expected} but got ${actual}", - {i:i, expected:expected[i], actual:actual[i], epsilon:epsilon}); - } - } - expose_assert(assert_array_approx_equals, "assert_array_approx_equals"); - - /** - * Assert that ``actual`` is within ± ``epsilon`` of ``expected``. - * - * @param {number} actual - Test value. - * @param {number} expected - Value number is expected to be close to. - * @param {number} epsilon - Magnitude of allowed difference between ``actual`` and ``expected``. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_approx_equals(actual, expected, epsilon, description) - { - /* - * Test if two primitive numbers are equal within +/- epsilon - */ - assert(typeof actual === "number", - "assert_approx_equals", description, - "expected a number but got a ${type_actual}", - {type_actual:typeof actual}); - - // The epsilon math below does not place nice with NaN and Infinity - // But in this case Infinity = Infinity and NaN = NaN - if (isFinite(actual) || isFinite(expected)) { - assert(Math.abs(actual - expected) <= epsilon, - "assert_approx_equals", description, - "expected ${expected} +/- ${epsilon} but got ${actual}", - {expected:expected, actual:actual, epsilon:epsilon}); - } else { - assert_equals(actual, expected); - } - } - expose_assert(assert_approx_equals, "assert_approx_equals"); - - /** - * Assert that ``actual`` is a number less than ``expected``. - * - * @param {number} actual - Test value. - * @param {number} expected - Number that ``actual`` must be less than. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_less_than(actual, expected, description) - { - /* - * Test if a primitive number is less than another - */ - assert(typeof actual === "number", - "assert_less_than", description, - "expected a number but got a ${type_actual}", - {type_actual:typeof actual}); - - assert(actual < expected, - "assert_less_than", description, - "expected a number less than ${expected} but got ${actual}", - {expected:expected, actual:actual}); - } - expose_assert(assert_less_than, "assert_less_than"); - - /** - * Assert that ``actual`` is a number greater than ``expected``. - * - * @param {number} actual - Test value. - * @param {number} expected - Number that ``actual`` must be greater than. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_greater_than(actual, expected, description) - { - /* - * Test if a primitive number is greater than another - */ - assert(typeof actual === "number", - "assert_greater_than", description, - "expected a number but got a ${type_actual}", - {type_actual:typeof actual}); - - assert(actual > expected, - "assert_greater_than", description, - "expected a number greater than ${expected} but got ${actual}", - {expected:expected, actual:actual}); - } - expose_assert(assert_greater_than, "assert_greater_than"); - - /** - * Assert that ``actual`` is a number greater than ``lower`` and less - * than ``upper`` but not equal to either. - * - * @param {number} actual - Test value. - * @param {number} lower - Number that ``actual`` must be greater than. - * @param {number} upper - Number that ``actual`` must be less than. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_between_exclusive(actual, lower, upper, description) - { - /* - * Test if a primitive number is between two others - */ - assert(typeof actual === "number", - "assert_between_exclusive", description, - "expected a number but got a ${type_actual}", - {type_actual:typeof actual}); - - assert(actual > lower && actual < upper, - "assert_between_exclusive", description, - "expected a number greater than ${lower} " + - "and less than ${upper} but got ${actual}", - {lower:lower, upper:upper, actual:actual}); - } - expose_assert(assert_between_exclusive, "assert_between_exclusive"); - - /** - * Assert that ``actual`` is a number less than or equal to ``expected``. - * - * @param {number} actual - Test value. - * @param {number} expected - Number that ``actual`` must be less - * than or equal to. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_less_than_equal(actual, expected, description) - { - /* - * Test if a primitive number is less than or equal to another - */ - assert(typeof actual === "number", - "assert_less_than_equal", description, - "expected a number but got a ${type_actual}", - {type_actual:typeof actual}); - - assert(actual <= expected, - "assert_less_than_equal", description, - "expected a number less than or equal to ${expected} but got ${actual}", - {expected:expected, actual:actual}); - } - expose_assert(assert_less_than_equal, "assert_less_than_equal"); - - /** - * Assert that ``actual`` is a number greater than or equal to ``expected``. - * - * @param {number} actual - Test value. - * @param {number} expected - Number that ``actual`` must be greater - * than or equal to. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_greater_than_equal(actual, expected, description) - { - /* - * Test if a primitive number is greater than or equal to another - */ - assert(typeof actual === "number", - "assert_greater_than_equal", description, - "expected a number but got a ${type_actual}", - {type_actual:typeof actual}); - - assert(actual >= expected, - "assert_greater_than_equal", description, - "expected a number greater than or equal to ${expected} but got ${actual}", - {expected:expected, actual:actual}); - } - expose_assert(assert_greater_than_equal, "assert_greater_than_equal"); - - /** - * Assert that ``actual`` is a number greater than or equal to ``lower`` and less - * than or equal to ``upper``. - * - * @param {number} actual - Test value. - * @param {number} lower - Number that ``actual`` must be greater than or equal to. - * @param {number} upper - Number that ``actual`` must be less than or equal to. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_between_inclusive(actual, lower, upper, description) - { - /* - * Test if a primitive number is between to two others or equal to either of them - */ - assert(typeof actual === "number", - "assert_between_inclusive", description, - "expected a number but got a ${type_actual}", - {type_actual:typeof actual}); - - assert(actual >= lower && actual <= upper, - "assert_between_inclusive", description, - "expected a number greater than or equal to ${lower} " + - "and less than or equal to ${upper} but got ${actual}", - {lower:lower, upper:upper, actual:actual}); - } - expose_assert(assert_between_inclusive, "assert_between_inclusive"); - - /** - * Assert that ``actual`` matches the RegExp ``expected``. - * - * @param {String} actual - Test string. - * @param {RegExp} expected - RegExp ``actual`` must match. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_regexp_match(actual, expected, description) { - /* - * Test if a string (actual) matches a regexp (expected) - */ - assert(expected.test(actual), - "assert_regexp_match", description, - "expected ${expected} but got ${actual}", - {expected:expected, actual:actual}); - } - expose_assert(assert_regexp_match, "assert_regexp_match"); - - /** - * Assert that the class string of ``object`` as returned in - * ``Object.prototype.toString`` is equal to ``class_name``. - * - * @param {Object} object - Object to stringify. - * @param {string} class_string - Expected class string for ``object``. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_class_string(object, class_string, description) { - var actual = {}.toString.call(object); - var expected = "[object " + class_string + "]"; - assert(same_value(actual, expected), "assert_class_string", description, - "expected ${expected} but got ${actual}", - {expected:expected, actual:actual}); - } - expose_assert(assert_class_string, "assert_class_string"); - - /** - * Assert that ``object`` has an own property with name ``property_name``. - * - * @param {Object} object - Object that should have the given property. - * @param {string} property_name - Expected property name. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_own_property(object, property_name, description) { - assert(object.hasOwnProperty(property_name), - "assert_own_property", description, - "expected property ${p} missing", {p:property_name}); - } - expose_assert(assert_own_property, "assert_own_property"); - - /** - * Assert that ``object`` does not have an own property with name ``property_name``. - * - * @param {Object} object - Object that should not have the given property. - * @param {string} property_name - Property name to test. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_not_own_property(object, property_name, description) { - assert(!object.hasOwnProperty(property_name), - "assert_not_own_property", description, - "unexpected property ${p} is found on object", {p:property_name}); - } - expose_assert(assert_not_own_property, "assert_not_own_property"); - - function _assert_inherits(name) { - return function (object, property_name, description) - { - assert((typeof object === "object" && object !== null) || - typeof object === "function" || - // Or has [[IsHTMLDDA]] slot - String(object) === "[object HTMLAllCollection]", - name, description, - "provided value is not an object"); - - assert("hasOwnProperty" in object, - name, description, - "provided value is an object but has no hasOwnProperty method"); - - assert(!object.hasOwnProperty(property_name), - name, description, - "property ${p} found on object expected in prototype chain", - {p:property_name}); - - assert(property_name in object, - name, description, - "property ${p} not found in prototype chain", - {p:property_name}); - }; - } - - /** - * Assert that ``object`` does not have an own property with name - * ``property_name``, but inherits one through the prototype chain. - * - * @param {Object} object - Object that should have the given property in its prototype chain. - * @param {string} property_name - Expected property name. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_inherits(object, property_name, description) { - return _assert_inherits("assert_inherits")(object, property_name, description); - } - expose_assert(assert_inherits, "assert_inherits"); - - /** - * Alias for :js:func:`insert_inherits`. - * - * @param {Object} object - Object that should have the given property in its prototype chain. - * @param {string} property_name - Expected property name. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_idl_attribute(object, property_name, description) { - return _assert_inherits("assert_idl_attribute")(object, property_name, description); - } - expose_assert(assert_idl_attribute, "assert_idl_attribute"); - - - /** - * Assert that ``object`` has a property named ``property_name`` and that the property is readonly. - * - * Note: The implementation tries to update the named property, so - * any side effects of updating will be triggered. Users are - * encouraged to instead inspect the property descriptor of ``property_name`` on ``object``. - * - * @param {Object} object - Object that should have the given property in its prototype chain. - * @param {string} property_name - Expected property name. - * @param {string} [description] - Description of the condition being tested. - */ - function assert_readonly(object, property_name, description) - { - var initial_value = object[property_name]; - try { - //Note that this can have side effects in the case where - //the property has PutForwards - object[property_name] = initial_value + "a"; //XXX use some other value here? - assert(same_value(object[property_name], initial_value), - "assert_readonly", description, - "changing property ${p} succeeded", - {p:property_name}); - } finally { - object[property_name] = initial_value; - } - } - expose_assert(assert_readonly, "assert_readonly"); - - /** - * Assert a JS Error with the expected constructor is thrown. - * - * @param {object} constructor The expected exception constructor. - * @param {Function} func Function which should throw. - * @param {string} [description] Error description for the case that the error is not thrown. - */ - function assert_throws_js(constructor, func, description) - { - assert_throws_js_impl(constructor, func, description, - "assert_throws_js"); - } - expose_assert(assert_throws_js, "assert_throws_js"); - - /** - * Like assert_throws_js but allows specifying the assertion type - * (assert_throws_js or promise_rejects_js, in practice). - */ - function assert_throws_js_impl(constructor, func, description, - assertion_type) - { - try { - func.call(this); - assert(false, assertion_type, description, - "${func} did not throw", {func:func}); - } catch (e) { - if (e instanceof AssertionError) { - throw e; - } - - // Basic sanity-checks on the thrown exception. - assert(typeof e === "object", - assertion_type, description, - "${func} threw ${e} with type ${type}, not an object", - {func:func, e:e, type:typeof e}); - - assert(e !== null, - assertion_type, description, - "${func} threw null, not an object", - {func:func}); - - // Basic sanity-check on the passed-in constructor - assert(typeof constructor == "function", - assertion_type, description, - "${constructor} is not a constructor", - {constructor:constructor}); - var obj = constructor; - while (obj) { - if (typeof obj === "function" && - obj.name === "Error") { - break; - } - obj = Object.getPrototypeOf(obj); - } - assert(obj != null, - assertion_type, description, - "${constructor} is not an Error subtype", - {constructor:constructor}); - - // And checking that our exception is reasonable - assert(e.constructor === constructor && - e.name === constructor.name, - assertion_type, description, - "${func} threw ${actual} (${actual_name}) expected instance of ${expected} (${expected_name})", - {func:func, actual:e, actual_name:e.name, - expected:constructor, - expected_name:constructor.name}); - } - } - - // TODO: Figure out how to document the overloads better. - // sphinx-js doesn't seem to handle @variation correctly, - // and only expects a single JSDoc entry per function. - /** - * Assert a DOMException with the expected type is thrown. - * - * There are two ways of calling assert_throws_dom: - * - * 1) If the DOMException is expected to come from the current global, the - * second argument should be the function expected to throw and a third, - * optional, argument is the assertion description. - * - * 2) If the DOMException is expected to come from some other global, the - * second argument should be the DOMException constructor from that global, - * the third argument the function expected to throw, and the fourth, optional, - * argument the assertion description. - * - * @param {number|string} type - The expected exception name or - * code. See the `table of names and codes - * `_. If a - * number is passed it should be one of the numeric code values in - * that table (e.g. 3, 4, etc). If a string is passed it can - * either be an exception name (e.g. "HierarchyRequestError", - * "WrongDocumentError") or the name of the corresponding error - * code (e.g. "``HIERARCHY_REQUEST_ERR``", "``WRONG_DOCUMENT_ERR``"). - * @param {Function} descriptionOrFunc - The function expected to - * throw (if the exception comes from another global), or the - * optional description of the condition being tested (if the - * exception comes from the current global). - * @param {string} [description] - Description of the condition - * being tested (if the exception comes from another global). - * - */ - function assert_throws_dom(type, funcOrConstructor, descriptionOrFunc, maybeDescription) - { - let constructor, func, description; - if (funcOrConstructor.name === "DOMException") { - constructor = funcOrConstructor; - func = descriptionOrFunc; - description = maybeDescription; - } else { - constructor = self.DOMException; - func = funcOrConstructor; - description = descriptionOrFunc; - assert(maybeDescription === undefined, - "Too many args pased to no-constructor version of assert_throws_dom"); - } - assert_throws_dom_impl(type, func, description, "assert_throws_dom", constructor) - } - expose_assert(assert_throws_dom, "assert_throws_dom"); - - /** - * Similar to assert_throws_dom but allows specifying the assertion type - * (assert_throws_dom or promise_rejects_dom, in practice). The - * "constructor" argument must be the DOMException constructor from the - * global we expect the exception to come from. - */ - function assert_throws_dom_impl(type, func, description, assertion_type, constructor) - { - try { - func.call(this); - assert(false, assertion_type, description, - "${func} did not throw", {func:func}); - } catch (e) { - if (e instanceof AssertionError) { - throw e; - } - - // Basic sanity-checks on the thrown exception. - assert(typeof e === "object", - assertion_type, description, - "${func} threw ${e} with type ${type}, not an object", - {func:func, e:e, type:typeof e}); - - assert(e !== null, - assertion_type, description, - "${func} threw null, not an object", - {func:func}); - - // Sanity-check our type - assert(typeof type == "number" || - typeof type == "string", - assertion_type, description, - "${type} is not a number or string", - {type:type}); - - var codename_name_map = { - INDEX_SIZE_ERR: 'IndexSizeError', - HIERARCHY_REQUEST_ERR: 'HierarchyRequestError', - WRONG_DOCUMENT_ERR: 'WrongDocumentError', - INVALID_CHARACTER_ERR: 'InvalidCharacterError', - NO_MODIFICATION_ALLOWED_ERR: 'NoModificationAllowedError', - NOT_FOUND_ERR: 'NotFoundError', - NOT_SUPPORTED_ERR: 'NotSupportedError', - INUSE_ATTRIBUTE_ERR: 'InUseAttributeError', - INVALID_STATE_ERR: 'InvalidStateError', - SYNTAX_ERR: 'SyntaxError', - INVALID_MODIFICATION_ERR: 'InvalidModificationError', - NAMESPACE_ERR: 'NamespaceError', - INVALID_ACCESS_ERR: 'InvalidAccessError', - TYPE_MISMATCH_ERR: 'TypeMismatchError', - SECURITY_ERR: 'SecurityError', - NETWORK_ERR: 'NetworkError', - ABORT_ERR: 'AbortError', - URL_MISMATCH_ERR: 'URLMismatchError', - QUOTA_EXCEEDED_ERR: 'QuotaExceededError', - TIMEOUT_ERR: 'TimeoutError', - INVALID_NODE_TYPE_ERR: 'InvalidNodeTypeError', - DATA_CLONE_ERR: 'DataCloneError' - }; - - var name_code_map = { - IndexSizeError: 1, - HierarchyRequestError: 3, - WrongDocumentError: 4, - InvalidCharacterError: 5, - NoModificationAllowedError: 7, - NotFoundError: 8, - NotSupportedError: 9, - InUseAttributeError: 10, - InvalidStateError: 11, - SyntaxError: 12, - InvalidModificationError: 13, - NamespaceError: 14, - InvalidAccessError: 15, - TypeMismatchError: 17, - SecurityError: 18, - NetworkError: 19, - AbortError: 20, - URLMismatchError: 21, - QuotaExceededError: 22, - TimeoutError: 23, - InvalidNodeTypeError: 24, - DataCloneError: 25, - - EncodingError: 0, - NotReadableError: 0, - UnknownError: 0, - ConstraintError: 0, - DataError: 0, - TransactionInactiveError: 0, - ReadOnlyError: 0, - VersionError: 0, - OperationError: 0, - NotAllowedError: 0, - OptOutError: 0 - }; - - var code_name_map = {}; - for (var key in name_code_map) { - if (name_code_map[key] > 0) { - code_name_map[name_code_map[key]] = key; - } - } - - var required_props = {}; - var name; - - if (typeof type === "number") { - if (type === 0) { - throw new AssertionError('Test bug: ambiguous DOMException code 0 passed to assert_throws_dom()'); - } else if (!(type in code_name_map)) { - throw new AssertionError('Test bug: unrecognized DOMException code "' + type + '" passed to assert_throws_dom()'); - } - name = code_name_map[type]; - required_props.code = type; - } else if (typeof type === "string") { - name = type in codename_name_map ? codename_name_map[type] : type; - if (!(name in name_code_map)) { - throw new AssertionError('Test bug: unrecognized DOMException code name or name "' + type + '" passed to assert_throws_dom()'); - } - - required_props.code = name_code_map[name]; - } - - if (required_props.code === 0 || - ("name" in e && - e.name !== e.name.toUpperCase() && - e.name !== "DOMException")) { - // New style exception: also test the name property. - required_props.name = name; - } - - for (var prop in required_props) { - assert(prop in e && e[prop] == required_props[prop], - assertion_type, description, - "${func} threw ${e} that is not a DOMException " + type + ": property ${prop} is equal to ${actual}, expected ${expected}", - {func:func, e:e, prop:prop, actual:e[prop], expected:required_props[prop]}); - } - - // Check that the exception is from the right global. This check is last - // so more specific, and more informative, checks on the properties can - // happen in case a totally incorrect exception is thrown. - assert(e.constructor === constructor, - assertion_type, description, - "${func} threw an exception from the wrong global", - {func}); - - } - } - - /** - * Assert the provided value is thrown. - * - * @param {value} exception The expected exception. - * @param {Function} func Function which should throw. - * @param {string} [description] Error description for the case that the error is not thrown. - */ - function assert_throws_exactly(exception, func, description) - { - assert_throws_exactly_impl(exception, func, description, - "assert_throws_exactly"); - } - expose_assert(assert_throws_exactly, "assert_throws_exactly"); - - /** - * Like assert_throws_exactly but allows specifying the assertion type - * (assert_throws_exactly or promise_rejects_exactly, in practice). - */ - function assert_throws_exactly_impl(exception, func, description, - assertion_type) - { - try { - func.call(this); - assert(false, assertion_type, description, - "${func} did not throw", {func:func}); - } catch (e) { - if (e instanceof AssertionError) { - throw e; - } - - assert(same_value(e, exception), assertion_type, description, - "${func} threw ${e} but we expected it to throw ${exception}", - {func:func, e:e, exception:exception}); - } - } - - /** - * Asserts if called. Used to ensure that a specific codepath is - * not taken e.g. that an error event isn't fired. - * - * @param {string} [description] - Description of the condition being tested. - */ - function assert_unreached(description) { - assert(false, "assert_unreached", description, - "Reached unreachable code"); - } - expose_assert(assert_unreached, "assert_unreached"); - - /** - * @callback AssertFunc - * @param {Any} actual - * @param {Any} expected - * @param {Any[]} args - */ - - /** - * Asserts that ``actual`` matches at least one value of ``expected`` - * according to a comparison defined by ``assert_func``. - * - * Note that tests with multiple allowed pass conditions are bad - * practice unless the spec specifically allows multiple - * behaviours. Test authors should not use this method simply to - * hide UA bugs. - * - * @param {AssertFunc} assert_func - Function to compare actual - * and expected. It must throw when the comparison fails and - * return when the comparison passes. - * @param {Any} actual - Test value. - * @param {Array} expected_array - Array of possible expected values. - * @param {Any[]} args - Additional arguments to pass to ``assert_func``. - */ - function assert_any(assert_func, actual, expected_array, ...args) - { - var errors = []; - var passed = false; - forEach(expected_array, - function(expected) - { - try { - assert_func.apply(this, [actual, expected].concat(args)); - passed = true; - } catch (e) { - errors.push(e.message); - } - }); - if (!passed) { - throw new AssertionError(errors.join("\n\n")); - } - } - // FIXME: assert_any cannot use expose_assert, because assert_wrapper does - // not support nested assert calls (e.g. to assert_func). We need to - // support bypassing assert_wrapper for the inner asserts here. - expose(assert_any, "assert_any"); - - /** - * Assert that a feature is implemented, based on a 'truthy' condition. - * - * This function should be used to early-exit from tests in which there is - * no point continuing without support for a non-optional spec or spec - * feature. For example: - * - * assert_implements(window.Foo, 'Foo is not supported'); - * - * @param {object} condition The truthy value to test - * @param {string} [description] Error description for the case that the condition is not truthy. - */ - function assert_implements(condition, description) { - assert(!!condition, "assert_implements", description); - } - expose_assert(assert_implements, "assert_implements") - - /** - * Assert that an optional feature is implemented, based on a 'truthy' condition. - * - * This function should be used to early-exit from tests in which there is - * no point continuing without support for an explicitly optional spec or - * spec feature. For example: - * - * assert_implements_optional(video.canPlayType("video/webm"), - * "webm video playback not supported"); - * - * @param {object} condition The truthy value to test - * @param {string} [description] Error description for the case that the condition is not truthy. - */ - function assert_implements_optional(condition, description) { - if (!condition) { - throw new OptionalFeatureUnsupportedError(description); - } - } - expose_assert(assert_implements_optional, "assert_implements_optional"); - - /** - * @class - * - * A single subtest. A Test is not constructed directly but via the - * :js:func:`test`, :js:func:`async_test` or :js:func:`promise_test` functions. - * - * @param {string} name - This must be unique in a given file and must be - * invariant between runs. - * - */ - function Test(name, properties) - { - if (tests.file_is_test && tests.tests.length) { - throw new Error("Tried to create a test with file_is_test"); - } - /** The test name. */ - this.name = name; - - this.phase = (tests.is_aborted || tests.phase === tests.phases.COMPLETE) ? - this.phases.COMPLETE : this.phases.INITIAL; - - /** The test status code.*/ - this.status = this.NOTRUN; - this.timeout_id = null; - this.index = null; - - this.properties = properties || {}; - this.timeout_length = settings.test_timeout; - if (this.timeout_length !== null) { - this.timeout_length *= tests.timeout_multiplier; - } - - /** A message indicating the reason for test failure. */ - this.message = null; - /** Stack trace in case of failure. */ - this.stack = null; - - this.steps = []; - this._is_promise_test = false; - - this.cleanup_callbacks = []; - this._user_defined_cleanup_count = 0; - this._done_callbacks = []; - - if (typeof AbortController === "function") { - this._abortController = new AbortController(); - } - - // Tests declared following harness completion are likely an indication - // of a programming error, but they cannot be reported - // deterministically. - if (tests.phase === tests.phases.COMPLETE) { - return; - } - - tests.push(this); - } - - /** - * Enum of possible test statuses. - * - * :values: - * - ``PASS`` - * - ``FAIL`` - * - ``TIMEOUT`` - * - ``NOTRUN`` - * - ``PRECONDITION_FAILED`` - */ - Test.statuses = { - PASS:0, - FAIL:1, - TIMEOUT:2, - NOTRUN:3, - PRECONDITION_FAILED:4 - }; - - Test.prototype = merge({}, Test.statuses); - - Test.prototype.phases = { - INITIAL:0, - STARTED:1, - HAS_RESULT:2, - CLEANING:3, - COMPLETE:4 - }; - - Test.prototype.status_formats = { - 0: "Pass", - 1: "Fail", - 2: "Timeout", - 3: "Not Run", - 4: "Optional Feature Unsupported", - } - - Test.prototype.format_status = function() { - return this.status_formats[this.status]; - } - - Test.prototype.structured_clone = function() - { - if (!this._structured_clone) { - var msg = this.message; - msg = msg ? String(msg) : msg; - this._structured_clone = merge({ - name:String(this.name), - properties:merge({}, this.properties), - phases:merge({}, this.phases) - }, Test.statuses); - } - this._structured_clone.status = this.status; - this._structured_clone.message = this.message; - this._structured_clone.stack = this.stack; - this._structured_clone.index = this.index; - this._structured_clone.phase = this.phase; - return this._structured_clone; - }; - - /** - * Run a single step of an ongoing test. - * - * @param {string} func - Callback function to run as a step. If - * this throws an :js:func:`AssertionError`, or any other - * exception, the :js:class:`Test` status is set to ``FAIL``. - * @param {Object} [this_obj] - The object to use as the this - * value when calling ``func``. Defaults to the :js:class:`Test` object. - */ - Test.prototype.step = function(func, this_obj) - { - if (this.phase > this.phases.STARTED) { - return; - } - - if (settings.debug && this.phase !== this.phases.STARTED) { - console.log("TEST START", this.name); - } - this.phase = this.phases.STARTED; - //If we don't get a result before the harness times out that will be a test timeout - this.set_status(this.TIMEOUT, "Test timed out"); - - tests.started = true; - tests.current_test = this; - tests.notify_test_state(this); - - if (this.timeout_id === null) { - this.set_timeout(); - } - - this.steps.push(func); - - if (arguments.length === 1) { - this_obj = this; - } - - if (settings.debug) { - console.debug("TEST STEP", this.name); - } - - try { - return func.apply(this_obj, Array.prototype.slice.call(arguments, 2)); - } catch (e) { - if (this.phase >= this.phases.HAS_RESULT) { - return; - } - var status = e instanceof OptionalFeatureUnsupportedError ? this.PRECONDITION_FAILED : this.FAIL; - var message = String((typeof e === "object" && e !== null) ? e.message : e); - var stack = e.stack ? e.stack : null; - - this.set_status(status, message, stack); - this.phase = this.phases.HAS_RESULT; - this.done(); - } finally { - this.current_test = null; - } - }; - - /** - * Wrap a function so that it runs as a step of the current test. - * - * This allows creating a callback function that will run as a - * test step. - * - * @example - * let t = async_test("Example"); - * onload = t.step_func(e => { - * assert_equals(e.name, "load"); - * // Mark the test as complete. - * t.done(); - * }) - * - * @param {string} func - Function to run as a step. If this - * throws an :js:func:`AssertionError`, or any other exception, - * the :js:class:`Test` status is set to ``FAIL``. - * @param {Object} [this_obj] - The object to use as the this - * value when calling ``func``. Defaults to the :js:class:`Test` object. - */ - Test.prototype.step_func = function(func, this_obj) - { - var test_this = this; - - if (arguments.length === 1) { - this_obj = test_this; - } - - return function() - { - return test_this.step.apply(test_this, [func, this_obj].concat( - Array.prototype.slice.call(arguments))); - }; - }; - - /** - * Wrap a function so that it runs as a step of the current test, - * and automatically marks the test as complete if the function - * returns without error. - * - * @param {string} func - Function to run as a step. If this - * throws an :js:func:`AssertionError`, or any other exception, - * the :js:class:`Test` status is set to ``FAIL``. If it returns - * without error the status is set to ``PASS``. - * @param {Object} [this_obj] - The object to use as the this - * value when calling `func`. Defaults to the :js:class:`Test` object. - */ - Test.prototype.step_func_done = function(func, this_obj) - { - var test_this = this; - - if (arguments.length === 1) { - this_obj = test_this; - } - - return function() - { - if (func) { - test_this.step.apply(test_this, [func, this_obj].concat( - Array.prototype.slice.call(arguments))); - } - test_this.done(); - }; - }; - - /** - * Return a function that automatically sets the current test to - * ``FAIL`` if it's called. - * - * @param {string} [description] - Error message to add to assert - * in case of failure. - * - */ - Test.prototype.unreached_func = function(description) - { - return this.step_func(function() { - assert_unreached(description); - }); - }; - - /** - * Run a function as a step of the test after a given timeout. - * - * This multiplies the timeout by the global timeout multiplier to - * account for the expected execution speed of the current test - * environment. For example ``test.step_timeout(f, 2000)`` with a - * timeout multiplier of 2 will wait for 4000ms before calling ``f``. - * - * In general it's encouraged to use :js:func:`Test.step_wait` or - * :js:func:`step_wait_func` in preference to this function where possible, - * as they provide better test performance. - * - * @param {Function} func - Function to run as a test - * step. - * @param {number} timeout - Time in ms to wait before running the - * test step. The actual wait time is ``timeout`` x - * ``timeout_multiplier``. - * - */ - Test.prototype.step_timeout = function(func, timeout) { - var test_this = this; - var args = Array.prototype.slice.call(arguments, 2); - return setTimeout(this.step_func(function() { - return func.apply(test_this, args); - }), timeout * tests.timeout_multiplier); - }; - - /** - * Poll for a function to return true, and call a callback - * function once it does, or assert if a timeout is - * reached. This is preferred over a simple step_timeout - * whenever possible since it allows the timeout to be longer - * to reduce intermittents without compromising test execution - * speed when the condition is quickly met. - * - * @param {Function} cond A function taking no arguments and - * returning a boolean or a Promise. The callback is - * called when this function returns true, or the - * returned Promise is resolved with true. - * @param {Function} func A function taking no arguments to call once - * the condition is met. - * @param {string} [description] Error message to add to assert in case of - * failure. - * @param {number} timeout Timeout in ms. This is multiplied by the global - * timeout_multiplier - * @param {number} interval Polling interval in ms - * - */ - Test.prototype.step_wait_func = function(cond, func, description, - timeout=3000, interval=100) { - var timeout_full = timeout * tests.timeout_multiplier; - var remaining = Math.ceil(timeout_full / interval); - var test_this = this; - - const step = test_this.step_func((result) => { - if (result) { - func(); - } else { - if (remaining === 0) { - assert(false, "step_wait_func", description, - "Timed out waiting on condition"); - } - remaining--; - setTimeout(wait_for_inner, interval); - } - }); - - var wait_for_inner = test_this.step_func(() => { - Promise.resolve(cond()).then( - step, - test_this.unreached_func("step_wait_func")); - }); - - wait_for_inner(); - }; - - /** - * Poll for a function to return true, and invoke a callback - * followed by this.done() once it does, or assert if a timeout - * is reached. This is preferred over a simple step_timeout - * whenever possible since it allows the timeout to be longer - * to reduce intermittents without compromising test execution speed - * when the condition is quickly met. - * - * @example - * async_test(t => { - * const popup = window.open("resources/coop-coep.py?coop=same-origin&coep=&navigate=about:blank"); - * t.add_cleanup(() => popup.close()); - * assert_equals(window, popup.opener); - * - * popup.onload = t.step_func(() => { - * assert_true(popup.location.href.endsWith("&navigate=about:blank")); - * // Use step_wait_func_done as about:blank cannot message back. - * t.step_wait_func_done(() => popup.location.href === "about:blank"); - * }); - * }, "Navigating a popup to about:blank"); - * - * @param {Function} cond A function taking no arguments and - * returning a boolean or a Promise. The callback is - * called when this function returns true, or the - * returned Promise is resolved with true. - * @param {Function} func A function taking no arguments to call once - * the condition is met. - * @param {string} [description] Error message to add to assert in case of - * failure. - * @param {number} timeout Timeout in ms. This is multiplied by the global - * timeout_multiplier - * @param {number} interval Polling interval in ms - * - */ - Test.prototype.step_wait_func_done = function(cond, func, description, - timeout=3000, interval=100) { - this.step_wait_func(cond, () => { - if (func) { - func(); - } - this.done(); - }, description, timeout, interval); - }; - - /** - * Poll for a function to return true, and resolve a promise - * once it does, or assert if a timeout is reached. This is - * preferred over a simple step_timeout whenever possible - * since it allows the timeout to be longer to reduce - * intermittents without compromising test execution speed - * when the condition is quickly met. - * - * @example - * promise_test(async t => { - * // … - * await t.step_wait(() => frame.contentDocument === null, "Frame navigated to a cross-origin document"); - * // … - * }, ""); - * - * @param {Function} cond A function taking no arguments and - * returning a boolean or a Promise. - * @param {string} [description] Error message to add to assert in case of - * failure. - * @param {number} timeout Timeout in ms. This is multiplied by the global - * timeout_multiplier - * @param {number} interval Polling interval in ms - * @returns {Promise} Promise resolved once cond is met. - * - */ - Test.prototype.step_wait = function(cond, description, timeout=3000, interval=100) { - return new Promise(resolve => { - this.step_wait_func(cond, resolve, description, timeout, interval); - }); - } - - /* - * Private method for registering cleanup functions. `testharness.js` - * internals should use this method instead of the public `add_cleanup` - * method in order to hide implementation details from the harness status - * message in the case errors. - */ - Test.prototype._add_cleanup = function(callback) { - this.cleanup_callbacks.push(callback); - }; - - /** - * Schedule a function to be run after the test result is known, regardless - * of passing or failing state. - * - * The behavior of this function will not - * influence the result of the test, but if an exception is thrown, the - * test harness will report an error. - * - * @param {Function} callback - The cleanup function to run. This - * is called with no arguments. - */ - Test.prototype.add_cleanup = function(callback) { - this._user_defined_cleanup_count += 1; - this._add_cleanup(callback); - }; - - Test.prototype.set_timeout = function() - { - if (this.timeout_length !== null) { - var this_obj = this; - this.timeout_id = setTimeout(function() - { - this_obj.timeout(); - }, this.timeout_length); - } - }; - - Test.prototype.set_status = function(status, message, stack) - { - this.status = status; - this.message = message; - this.stack = stack ? stack : null; - }; - - /** - * Manually set the test status to ``TIMEOUT``. - */ - Test.prototype.timeout = function() - { - this.timeout_id = null; - this.set_status(this.TIMEOUT, "Test timed out"); - this.phase = this.phases.HAS_RESULT; - this.done(); - }; - - /** - * Manually set the test status to ``TIMEOUT``. - * - * Alias for `Test.timeout <#Test.timeout>`_. - */ - Test.prototype.force_timeout = function() { - return this.timeout(); - }; - - /** - * Mark the test as complete. - * - * This sets the test status to ``PASS`` if no other status was - * already recorded. Any subsequent attempts to run additional - * test steps will be ignored. - * - * After setting the test status any test cleanup functions will - * be run. - */ - Test.prototype.done = function() - { - if (this.phase >= this.phases.CLEANING) { - return; - } - - if (this.phase <= this.phases.STARTED) { - this.set_status(this.PASS, null); - } - - if (global_scope.clearTimeout) { - clearTimeout(this.timeout_id); - } - - if (settings.debug) { - console.log("TEST DONE", - this.status, - this.name); - } - - this.cleanup(); - }; - - function add_test_done_callback(test, callback) - { - if (test.phase === test.phases.COMPLETE) { - callback(); - return; - } - - test._done_callbacks.push(callback); - } - - /* - * Invoke all specified cleanup functions. If one or more produce an error, - * the context is in an unpredictable state, so all further testing should - * be cancelled. - */ - Test.prototype.cleanup = function() { - var errors = []; - var bad_value_count = 0; - function on_error(e) { - errors.push(e); - // Abort tests immediately so that tests declared within subsequent - // cleanup functions are not run. - tests.abort(); - } - var this_obj = this; - var results = []; - - this.phase = this.phases.CLEANING; - - if (this._abortController) { - this._abortController.abort("Test cleanup"); - } - - forEach(this.cleanup_callbacks, - function(cleanup_callback) { - var result; - - try { - result = cleanup_callback(); - } catch (e) { - on_error(e); - return; - } - - if (!is_valid_cleanup_result(this_obj, result)) { - bad_value_count += 1; - // Abort tests immediately so that tests declared - // within subsequent cleanup functions are not run. - tests.abort(); - } - - results.push(result); - }); - - if (!this._is_promise_test) { - cleanup_done(this_obj, errors, bad_value_count); - } else { - all_async(results, - function(result, done) { - if (result && typeof result.then === "function") { - result - .then(null, on_error) - .then(done); - } else { - done(); - } - }, - function() { - cleanup_done(this_obj, errors, bad_value_count); - }); - } - }; - - /* - * Determine if the return value of a cleanup function is valid for a given - * test. Any test may return the value `undefined`. Tests created with - * `promise_test` may alternatively return "thenable" object values. - */ - function is_valid_cleanup_result(test, result) { - if (result === undefined) { - return true; - } - - if (test._is_promise_test) { - return result && typeof result.then === "function"; - } - - return false; - } - - function cleanup_done(test, errors, bad_value_count) { - if (errors.length || bad_value_count) { - var total = test._user_defined_cleanup_count; - - tests.status.status = tests.status.ERROR; - tests.status.stack = null; - tests.status.message = "Test named '" + test.name + - "' specified " + total + - " 'cleanup' function" + (total > 1 ? "s" : ""); - - if (errors.length) { - tests.status.message += ", and " + errors.length + " failed"; - tests.status.stack = ((typeof errors[0] === "object" && - errors[0].hasOwnProperty("stack")) ? - errors[0].stack : null); - } - - if (bad_value_count) { - var type = test._is_promise_test ? - "non-thenable" : "non-undefined"; - tests.status.message += ", and " + bad_value_count + - " returned a " + type + " value"; - } - - tests.status.message += "."; - } - - test.phase = test.phases.COMPLETE; - tests.result(test); - forEach(test._done_callbacks, - function(callback) { - callback(); - }); - test._done_callbacks.length = 0; - } - - /** - * Gives an AbortSignal that will be aborted when the test finishes. - */ - Test.prototype.get_signal = function() { - if (!this._abortController) { - throw new Error("AbortController is not supported in this browser"); - } - return this._abortController.signal; - } - - /** - * A RemoteTest object mirrors a Test object on a remote worker. The - * associated RemoteWorker updates the RemoteTest object in response to - * received events. In turn, the RemoteTest object replicates these events - * on the local document. This allows listeners (test result reporting - * etc..) to transparently handle local and remote events. - */ - function RemoteTest(clone) { - var this_obj = this; - Object.keys(clone).forEach( - function(key) { - this_obj[key] = clone[key]; - }); - this.index = null; - this.phase = this.phases.INITIAL; - this.update_state_from(clone); - this._done_callbacks = []; - tests.push(this); - } - - RemoteTest.prototype.structured_clone = function() { - var clone = {}; - Object.keys(this).forEach( - (function(key) { - var value = this[key]; - // `RemoteTest` instances are responsible for managing - // their own "done" callback functions, so those functions - // are not relevant in other execution contexts. Because of - // this (and because Function values cannot be serialized - // for cross-realm transmittance), the property should not - // be considered when cloning instances. - if (key === '_done_callbacks' ) { - return; - } - - if (typeof value === "object" && value !== null) { - clone[key] = merge({}, value); - } else { - clone[key] = value; - } - }).bind(this)); - clone.phases = merge({}, this.phases); - return clone; - }; - - /** - * `RemoteTest` instances are objects which represent tests running in - * another realm. They do not define "cleanup" functions (if necessary, - * such functions are defined on the associated `Test` instance within the - * external realm). However, `RemoteTests` may have "done" callbacks (e.g. - * as attached by the `Tests` instance responsible for tracking the overall - * test status in the parent realm). The `cleanup` method delegates to - * `done` in order to ensure that such callbacks are invoked following the - * completion of the `RemoteTest`. - */ - RemoteTest.prototype.cleanup = function() { - this.done(); - }; - RemoteTest.prototype.phases = Test.prototype.phases; - RemoteTest.prototype.update_state_from = function(clone) { - this.status = clone.status; - this.message = clone.message; - this.stack = clone.stack; - if (this.phase === this.phases.INITIAL) { - this.phase = this.phases.STARTED; - } - }; - RemoteTest.prototype.done = function() { - this.phase = this.phases.COMPLETE; - - forEach(this._done_callbacks, - function(callback) { - callback(); - }); - } - - RemoteTest.prototype.format_status = function() { - return Test.prototype.status_formats[this.status]; - } - - /* - * A RemoteContext listens for test events from a remote test context, such - * as another window or a worker. These events are then used to construct - * and maintain RemoteTest objects that mirror the tests running in the - * remote context. - * - * An optional third parameter can be used as a predicate to filter incoming - * MessageEvents. - */ - function RemoteContext(remote, message_target, message_filter) { - this.running = true; - this.started = false; - this.tests = new Array(); - this.early_exception = null; - - var this_obj = this; - // If remote context is cross origin assigning to onerror is not - // possible, so silently catch those errors. - try { - remote.onerror = function(error) { this_obj.remote_error(error); }; - } catch (e) { - // Ignore. - } - - // Keeping a reference to the remote object and the message handler until - // remote_done() is seen prevents the remote object and its message channel - // from going away before all the messages are dispatched. - this.remote = remote; - this.message_target = message_target; - this.message_handler = function(message) { - var passesFilter = !message_filter || message_filter(message); - // The reference to the `running` property in the following - // condition is unnecessary because that value is only set to - // `false` after the `message_handler` function has been - // unsubscribed. - // TODO: Simplify the condition by removing the reference. - if (this_obj.running && message.data && passesFilter && - (message.data.type in this_obj.message_handlers)) { - this_obj.message_handlers[message.data.type].call(this_obj, message.data); - } - }; - - if (self.Promise) { - this.done = new Promise(function(resolve) { - this_obj.doneResolve = resolve; - }); - } - - this.message_target.addEventListener("message", this.message_handler); - } - - RemoteContext.prototype.remote_error = function(error) { - if (error.preventDefault) { - error.preventDefault(); - } - - // Defer interpretation of errors until the testing protocol has - // started and the remote test's `allow_uncaught_exception` property - // is available. - if (!this.started) { - this.early_exception = error; - } else if (!this.allow_uncaught_exception) { - this.report_uncaught(error); - } - }; - - RemoteContext.prototype.report_uncaught = function(error) { - var message = error.message || String(error); - var filename = (error.filename ? " " + error.filename: ""); - // FIXME: Display remote error states separately from main document - // error state. - tests.set_status(tests.status.ERROR, - "Error in remote" + filename + ": " + message, - error.stack); - }; - - RemoteContext.prototype.start = function(data) { - this.started = true; - this.allow_uncaught_exception = data.properties.allow_uncaught_exception; - - if (this.early_exception && !this.allow_uncaught_exception) { - this.report_uncaught(this.early_exception); - } - }; - - RemoteContext.prototype.test_state = function(data) { - var remote_test = this.tests[data.test.index]; - if (!remote_test) { - remote_test = new RemoteTest(data.test); - this.tests[data.test.index] = remote_test; - } - remote_test.update_state_from(data.test); - tests.notify_test_state(remote_test); - }; - - RemoteContext.prototype.test_done = function(data) { - var remote_test = this.tests[data.test.index]; - remote_test.update_state_from(data.test); - remote_test.done(); - tests.result(remote_test); - }; - - RemoteContext.prototype.remote_done = function(data) { - if (tests.status.status === null && - data.status.status !== data.status.OK) { - tests.set_status(data.status.status, data.status.message, data.status.stack); - } - - for (let assert of data.asserts) { - var record = new AssertRecord(); - record.assert_name = assert.assert_name; - record.args = assert.args; - record.test = assert.test != null ? this.tests[assert.test.index] : null; - record.status = assert.status; - record.stack = assert.stack; - tests.asserts_run.push(record); - } - - this.message_target.removeEventListener("message", this.message_handler); - this.running = false; - - // If remote context is cross origin assigning to onerror is not - // possible, so silently catch those errors. - try { - this.remote.onerror = null; - } catch (e) { - // Ignore. - } - - this.remote = null; - this.message_target = null; - if (this.doneResolve) { - this.doneResolve(); - } - - if (tests.all_done()) { - tests.complete(); - } - }; - - RemoteContext.prototype.message_handlers = { - start: RemoteContext.prototype.start, - test_state: RemoteContext.prototype.test_state, - result: RemoteContext.prototype.test_done, - complete: RemoteContext.prototype.remote_done - }; - - /** - * @class - * Status of the overall harness - */ - function TestsStatus() - { - /** The status code */ - this.status = null; - /** Message in case of failure */ - this.message = null; - /** Stack trace in case of an exception. */ - this.stack = null; - } - - /** - * Enum of possible harness statuses. - * - * :values: - * - ``OK`` - * - ``ERROR`` - * - ``TIMEOUT`` - * - ``PRECONDITION_FAILED`` - */ - TestsStatus.statuses = { - OK:0, - ERROR:1, - TIMEOUT:2, - PRECONDITION_FAILED:3 - }; - - TestsStatus.prototype = merge({}, TestsStatus.statuses); - - TestsStatus.prototype.formats = { - 0: "OK", - 1: "Error", - 2: "Timeout", - 3: "Optional Feature Unsupported" - }; - - TestsStatus.prototype.structured_clone = function() - { - if (!this._structured_clone) { - var msg = this.message; - msg = msg ? String(msg) : msg; - this._structured_clone = merge({ - status:this.status, - message:msg, - stack:this.stack - }, TestsStatus.statuses); - } - return this._structured_clone; - }; - - TestsStatus.prototype.format_status = function() { - return this.formats[this.status]; - }; - - /** - * @class - * Record of an assert that ran. - * - * @param {Test} test - The test which ran the assert. - * @param {string} assert_name - The function name of the assert. - * @param {Any} args - The arguments passed to the assert function. - */ - function AssertRecord(test, assert_name, args = []) { - /** Name of the assert that ran */ - this.assert_name = assert_name; - /** Test that ran the assert */ - this.test = test; - // Avoid keeping complex objects alive - /** Stringification of the arguments that were passed to the assert function */ - this.args = args.map(x => format_value(x).replace(/\n/g, " ")); - /** Status of the assert */ - this.status = null; - } - - AssertRecord.prototype.structured_clone = function() { - return { - assert_name: this.assert_name, - test: this.test ? this.test.structured_clone() : null, - args: this.args, - status: this.status, - }; - }; - - function Tests() - { - this.tests = []; - this.num_pending = 0; - - this.phases = { - INITIAL:0, - SETUP:1, - HAVE_TESTS:2, - HAVE_RESULTS:3, - COMPLETE:4 - }; - this.phase = this.phases.INITIAL; - - this.properties = {}; - - this.wait_for_finish = false; - this.processing_callbacks = false; - - this.allow_uncaught_exception = false; - - this.file_is_test = false; - // This value is lazily initialized in order to avoid introducing a - // dependency on ECMAScript 2015 Promises to all tests. - this.promise_tests = null; - this.promise_setup_called = false; - - this.timeout_multiplier = 1; - this.timeout_length = test_environment.test_timeout(); - this.timeout_id = null; - - this.start_callbacks = []; - this.test_state_callbacks = []; - this.test_done_callbacks = []; - this.all_done_callbacks = []; - - this.hide_test_state = false; - this.pending_remotes = []; - - this.current_test = null; - this.asserts_run = []; - - // Track whether output is enabled, and thus whether or not we should - // track asserts. - // - // On workers we don't get properties set from testharnessreport.js, so - // we don't know whether or not to track asserts. To avoid the - // resulting performance hit, we assume we are not meant to. This means - // that assert tracking does not function on workers. - this.output = settings.output && 'document' in global_scope; - - this.status = new TestsStatus(); - - var this_obj = this; - - test_environment.add_on_loaded_callback(function() { - if (this_obj.all_done()) { - this_obj.complete(); - } - }); - - this.set_timeout(); - } - - Tests.prototype.setup = function(func, properties) - { - if (this.phase >= this.phases.HAVE_RESULTS) { - return; - } - - if (this.phase < this.phases.SETUP) { - this.phase = this.phases.SETUP; - } - - this.properties = properties; - - for (var p in properties) { - if (properties.hasOwnProperty(p)) { - var value = properties[p]; - if (p == "allow_uncaught_exception") { - this.allow_uncaught_exception = value; - } else if (p == "explicit_done" && value) { - this.wait_for_finish = true; - } else if (p == "explicit_timeout" && value) { - this.timeout_length = null; - if (this.timeout_id) - { - clearTimeout(this.timeout_id); - } - } else if (p == "single_test" && value) { - this.set_file_is_test(); - } else if (p == "timeout_multiplier") { - this.timeout_multiplier = value; - if (this.timeout_length) { - this.timeout_length *= this.timeout_multiplier; - } - } else if (p == "hide_test_state") { - this.hide_test_state = value; - } else if (p == "output") { - this.output = value; - } else if (p === "debug") { - settings.debug = value; - } - } - } - - if (func) { - try { - func(); - } catch (e) { - this.status.status = e instanceof OptionalFeatureUnsupportedError ? this.status.PRECONDITION_FAILED : this.status.ERROR; - this.status.message = String(e); - this.status.stack = e.stack ? e.stack : null; - this.complete(); - } - } - this.set_timeout(); - }; - - Tests.prototype.set_file_is_test = function() { - if (this.tests.length > 0) { - throw new Error("Tried to set file as test after creating a test"); - } - this.wait_for_finish = true; - this.file_is_test = true; - // Create the test, which will add it to the list of tests - tests.current_test = async_test(); - }; - - Tests.prototype.set_status = function(status, message, stack) - { - this.status.status = status; - this.status.message = message; - this.status.stack = stack ? stack : null; - }; - - Tests.prototype.set_timeout = function() { - if (global_scope.clearTimeout) { - var this_obj = this; - clearTimeout(this.timeout_id); - if (this.timeout_length !== null) { - this.timeout_id = setTimeout(function() { - this_obj.timeout(); - }, this.timeout_length); - } - } - }; - - Tests.prototype.timeout = function() { - var test_in_cleanup = null; - - if (this.status.status === null) { - forEach(this.tests, - function(test) { - // No more than one test is expected to be in the - // "CLEANUP" phase at any time - if (test.phase === test.phases.CLEANING) { - test_in_cleanup = test; - } - - test.phase = test.phases.COMPLETE; - }); - - // Timeouts that occur while a test is in the "cleanup" phase - // indicate that some global state was not properly reverted. This - // invalidates the overall test execution, so the timeout should be - // reported as an error and cancel the execution of any remaining - // tests. - if (test_in_cleanup) { - this.status.status = this.status.ERROR; - this.status.message = "Timeout while running cleanup for " + - "test named \"" + test_in_cleanup.name + "\"."; - tests.status.stack = null; - } else { - this.status.status = this.status.TIMEOUT; - } - } - - this.complete(); - }; - - Tests.prototype.end_wait = function() - { - this.wait_for_finish = false; - if (this.all_done()) { - this.complete(); - } - }; - - Tests.prototype.push = function(test) - { - if (this.phase < this.phases.HAVE_TESTS) { - this.start(); - } - this.num_pending++; - test.index = this.tests.push(test); - this.notify_test_state(test); - }; - - Tests.prototype.notify_test_state = function(test) { - var this_obj = this; - forEach(this.test_state_callbacks, - function(callback) { - callback(test, this_obj); - }); - }; - - Tests.prototype.all_done = function() { - return (this.tests.length > 0 || this.pending_remotes.length > 0) && - test_environment.all_loaded && - (this.num_pending === 0 || this.is_aborted) && !this.wait_for_finish && - !this.processing_callbacks && - !this.pending_remotes.some(function(w) { return w.running; }); - }; - - Tests.prototype.start = function() { - this.phase = this.phases.HAVE_TESTS; - this.notify_start(); - }; - - Tests.prototype.notify_start = function() { - var this_obj = this; - forEach (this.start_callbacks, - function(callback) - { - callback(this_obj.properties); - }); - }; - - Tests.prototype.result = function(test) - { - // If the harness has already transitioned beyond the `HAVE_RESULTS` - // phase, subsequent tests should not cause it to revert. - if (this.phase <= this.phases.HAVE_RESULTS) { - this.phase = this.phases.HAVE_RESULTS; - } - this.num_pending--; - this.notify_result(test); - }; - - Tests.prototype.notify_result = function(test) { - var this_obj = this; - this.processing_callbacks = true; - forEach(this.test_done_callbacks, - function(callback) - { - callback(test, this_obj); - }); - this.processing_callbacks = false; - if (this_obj.all_done()) { - this_obj.complete(); - } - }; - - Tests.prototype.complete = function() { - if (this.phase === this.phases.COMPLETE) { - return; - } - var this_obj = this; - var all_complete = function() { - this_obj.phase = this_obj.phases.COMPLETE; - this_obj.notify_complete(); - }; - var incomplete = filter(this.tests, - function(test) { - return test.phase < test.phases.COMPLETE; - }); - - /** - * To preserve legacy behavior, overall test completion must be - * signaled synchronously. - */ - if (incomplete.length === 0) { - all_complete(); - return; - } - - all_async(incomplete, - function(test, testDone) - { - if (test.phase === test.phases.INITIAL) { - test.phase = test.phases.COMPLETE; - testDone(); - } else { - add_test_done_callback(test, testDone); - test.cleanup(); - } - }, - all_complete); - }; - - Tests.prototype.set_assert = function(assert_name, args) { - this.asserts_run.push(new AssertRecord(this.current_test, assert_name, args)) - } - - Tests.prototype.set_assert_status = function(index, status, stack) { - let assert_record = this.asserts_run[index]; - assert_record.status = status; - assert_record.stack = stack; - } - - /** - * Update the harness status to reflect an unrecoverable harness error that - * should cancel all further testing. Update all previously-defined tests - * which have not yet started to indicate that they will not be executed. - */ - Tests.prototype.abort = function() { - this.status.status = this.status.ERROR; - this.is_aborted = true; - - forEach(this.tests, - function(test) { - if (test.phase === test.phases.INITIAL) { - test.phase = test.phases.COMPLETE; - } - }); - }; - - /* - * Determine if any tests share the same `name` property. Return an array - * containing the names of any such duplicates. - */ - Tests.prototype.find_duplicates = function() { - var names = Object.create(null); - var duplicates = []; - - forEach (this.tests, - function(test) - { - if (test.name in names && duplicates.indexOf(test.name) === -1) { - duplicates.push(test.name); - } - names[test.name] = true; - }); - - return duplicates; - }; - - function code_unit_str(char) { - return 'U+' + char.charCodeAt(0).toString(16); - } - - function sanitize_unpaired_surrogates(str) { - return str.replace( - /([\ud800-\udbff]+)(?![\udc00-\udfff])|(^|[^\ud800-\udbff])([\udc00-\udfff]+)/g, - function(_, low, prefix, high) { - var output = prefix || ""; // prefix may be undefined - var string = low || high; // only one of these alternates can match - for (var i = 0; i < string.length; i++) { - output += code_unit_str(string[i]); - } - return output; - }); - } - - function sanitize_all_unpaired_surrogates(tests) { - forEach (tests, - function (test) - { - var sanitized = sanitize_unpaired_surrogates(test.name); - - if (test.name !== sanitized) { - test.name = sanitized; - delete test._structured_clone; - } - }); - } - - Tests.prototype.notify_complete = function() { - var this_obj = this; - var duplicates; - - if (this.status.status === null) { - duplicates = this.find_duplicates(); - - // Some transports adhere to UTF-8's restriction on unpaired - // surrogates. Sanitize the titles so that the results can be - // consistently sent via all transports. - sanitize_all_unpaired_surrogates(this.tests); - - // Test names are presumed to be unique within test files--this - // allows consumers to use them for identification purposes. - // Duplicated names violate this expectation and should therefore - // be reported as an error. - if (duplicates.length) { - this.status.status = this.status.ERROR; - this.status.message = - duplicates.length + ' duplicate test name' + - (duplicates.length > 1 ? 's' : '') + ': "' + - duplicates.join('", "') + '"'; - } else { - this.status.status = this.status.OK; - } - } - - forEach (this.all_done_callbacks, - function(callback) - { - callback(this_obj.tests, this_obj.status, this_obj.asserts_run); - }); - }; - - /* - * Constructs a RemoteContext that tracks tests from a specific worker. - */ - Tests.prototype.create_remote_worker = function(worker) { - var message_port; - - if (is_service_worker(worker)) { - message_port = navigator.serviceWorker; - worker.postMessage({type: "connect"}); - } else if (is_shared_worker(worker)) { - message_port = worker.port; - message_port.start(); - } else { - message_port = worker; - } - - return new RemoteContext(worker, message_port); - }; - - /* - * Constructs a RemoteContext that tracks tests from a specific window. - */ - Tests.prototype.create_remote_window = function(remote) { - remote.postMessage({type: "getmessages"}, "*"); - return new RemoteContext( - remote, - window, - function(msg) { - return msg.source === remote; - } - ); - }; - - Tests.prototype.fetch_tests_from_worker = function(worker) { - if (this.phase >= this.phases.COMPLETE) { - return; - } - - var remoteContext = this.create_remote_worker(worker); - this.pending_remotes.push(remoteContext); - return remoteContext.done; - }; - - /** - * Get test results from a worker and include them in the current test. - * - * @param {Worker|SharedWorker|ServiceWorker|MessagePort} port - - * Either a worker object or a port connected to a worker which is - * running tests.. - * @returns {Promise} - A promise that's resolved once all the remote tests are complete. - */ - function fetch_tests_from_worker(port) { - return tests.fetch_tests_from_worker(port); - } - expose(fetch_tests_from_worker, 'fetch_tests_from_worker'); - - Tests.prototype.fetch_tests_from_window = function(remote) { - if (this.phase >= this.phases.COMPLETE) { - return; - } - - var remoteContext = this.create_remote_window(remote); - this.pending_remotes.push(remoteContext); - return remoteContext.done; - }; - - /** - * Aggregate tests from separate windows or iframes - * into the current document as if they were all part of the same test file. - * - * The document of the second window (or iframe) should include - * ``testharness.js``, but not ``testharnessreport.js``, and use - * :js:func:`test`, :js:func:`async_test`, and :js:func:`promise_test` in - * the usual manner. - * - * @param {Window} window - The window to fetch tests from. - */ - function fetch_tests_from_window(window) { - return tests.fetch_tests_from_window(window); - } - expose(fetch_tests_from_window, 'fetch_tests_from_window'); - - /** - * Get test results from a shadow realm and include them in the current test. - * - * @param {ShadowRealm} realm - A shadow realm also running the test harness - * @returns {Promise} - A promise that's resolved once all the remote tests are complete. - */ - function fetch_tests_from_shadow_realm(realm) { - var chan = new MessageChannel(); - function receiveMessage(msg_json) { - chan.port1.postMessage(JSON.parse(msg_json)); - } - var done = tests.fetch_tests_from_worker(chan.port2); - realm.evaluate("begin_shadow_realm_tests")(receiveMessage); - chan.port2.start(); - return done; - } - expose(fetch_tests_from_shadow_realm, 'fetch_tests_from_shadow_realm'); - - /** - * Begin running tests in this shadow realm test harness. - * - * To be called after all tests have been loaded; it is an error to call - * this more than once or in a non-Shadow Realm environment - * - * @param {Function} postMessage - A function to send test updates to the - * incubating realm-- accepts JSON-encoded messages in the format used by - * RemoteContext - */ - function begin_shadow_realm_tests(postMessage) { - if (!(test_environment instanceof ShadowRealmTestEnvironment)) { - throw new Error("begin_shadow_realm_tests called in non-Shadow Realm environment"); - } - - test_environment.begin(function (msg) { - postMessage(JSON.stringify(msg)); - }); - } - expose(begin_shadow_realm_tests, 'begin_shadow_realm_tests'); - - /** - * Timeout the tests. - * - * This only has an effect when ``explicit_timeout`` has been set - * in :js:func:`setup`. In other cases any call is a no-op. - * - */ - function timeout() { - if (tests.timeout_length === null) { - tests.timeout(); - } - } - expose(timeout, 'timeout'); - - /** - * Add a callback that's triggered when the first :js:class:`Test` is created. - * - * @param {Function} callback - Callback function. This is called - * without arguments. - */ - function add_start_callback(callback) { - tests.start_callbacks.push(callback); - } - - /** - * Add a callback that's triggered when a test state changes. - * - * @param {Function} callback - Callback function, called with the - * :js:class:`Test` as the only argument. - */ - function add_test_state_callback(callback) { - tests.test_state_callbacks.push(callback); - } - - /** - * Add a callback that's triggered when a test result is received. - * - * @param {Function} callback - Callback function, called with the - * :js:class:`Test` as the only argument. - */ - function add_result_callback(callback) { - tests.test_done_callbacks.push(callback); - } - - /** - * Add a callback that's triggered when all tests are complete. - * - * @param {Function} callback - Callback function, called with an - * array of :js:class:`Test` objects, a :js:class:`TestsStatus` - * object and an array of :js:class:`AssertRecord` objects. If the - * debug setting is ``false`` the final argument will be an empty - * array. - * - * For performance reasons asserts are only tracked when the debug - * setting is ``true``. In other cases the array of asserts will be - * empty. - */ - function add_completion_callback(callback) { - tests.all_done_callbacks.push(callback); - } - - expose(add_start_callback, 'add_start_callback'); - expose(add_test_state_callback, 'add_test_state_callback'); - expose(add_result_callback, 'add_result_callback'); - expose(add_completion_callback, 'add_completion_callback'); - - function remove(array, item) { - var index = array.indexOf(item); - if (index > -1) { - array.splice(index, 1); - } - } - - function remove_start_callback(callback) { - remove(tests.start_callbacks, callback); - } - - function remove_test_state_callback(callback) { - remove(tests.test_state_callbacks, callback); - } - - function remove_result_callback(callback) { - remove(tests.test_done_callbacks, callback); - } - - function remove_completion_callback(callback) { - remove(tests.all_done_callbacks, callback); - } - - /* - * Output listener - */ - - function Output() { - this.output_document = document; - this.output_node = null; - this.enabled = settings.output; - this.phase = this.INITIAL; - } - - Output.prototype.INITIAL = 0; - Output.prototype.STARTED = 1; - Output.prototype.HAVE_RESULTS = 2; - Output.prototype.COMPLETE = 3; - - Output.prototype.setup = function(properties) { - if (this.phase > this.INITIAL) { - return; - } - - //If output is disabled in testharnessreport.js the test shouldn't be - //able to override that - this.enabled = this.enabled && (properties.hasOwnProperty("output") ? - properties.output : settings.output); - }; - - Output.prototype.init = function(properties) { - if (this.phase >= this.STARTED) { - return; - } - if (properties.output_document) { - this.output_document = properties.output_document; - } else { - this.output_document = document; - } - this.phase = this.STARTED; - }; - - Output.prototype.resolve_log = function() { - var output_document; - if (this.output_node) { - return; - } - if (typeof this.output_document === "function") { - output_document = this.output_document.apply(undefined); - } else { - output_document = this.output_document; - } - if (!output_document) { - return; - } - var node = output_document.getElementById("log"); - if (!node) { - if (output_document.readyState === "loading") { - return; - } - node = output_document.createElementNS("http://www.w3.org/1999/xhtml", "div"); - node.id = "log"; - if (output_document.body) { - output_document.body.appendChild(node); - } else { - var root = output_document.documentElement; - var is_html = (root && - root.namespaceURI == "http://www.w3.org/1999/xhtml" && - root.localName == "html"); - var is_svg = (output_document.defaultView && - "SVGSVGElement" in output_document.defaultView && - root instanceof output_document.defaultView.SVGSVGElement); - if (is_svg) { - var foreignObject = output_document.createElementNS("http://www.w3.org/2000/svg", "foreignObject"); - foreignObject.setAttribute("width", "100%"); - foreignObject.setAttribute("height", "100%"); - root.appendChild(foreignObject); - foreignObject.appendChild(node); - } else if (is_html) { - root.appendChild(output_document.createElementNS("http://www.w3.org/1999/xhtml", "body")) - .appendChild(node); - } else { - root.appendChild(node); - } - } - } - this.output_document = output_document; - this.output_node = node; - }; - - Output.prototype.show_status = function() { - if (this.phase < this.STARTED) { - this.init({}); - } - if (!this.enabled || this.phase === this.COMPLETE) { - return; - } - //this.resolve_log(); - if (this.phase < this.HAVE_RESULTS) { - this.phase = this.HAVE_RESULTS; - } - var done_count = tests.tests.length - tests.num_pending; - if (this.output_node && !tests.hide_test_state) { - if (done_count < 100 || - (done_count < 1000 && done_count % 100 === 0) || - done_count % 1000 === 0) { - this.output_node.textContent = "Running, " + - done_count + " complete, " + - tests.num_pending + " remain"; - } - } - }; - - Output.prototype.show_results = function (tests, harness_status, asserts_run) { - if (this.phase >= this.COMPLETE) { - return; - } - if (!this.enabled) { - return; - } - if (!this.output_node) { - //this.resolve_log(); - } - this.phase = this.COMPLETE; - - var log = this.output_node; - if (!log) { - return; - } - var output_document = this.output_document; - - while (log.lastChild) { - log.removeChild(log.lastChild); - } - - var stylesheet = output_document.createElementNS(xhtml_ns, "style"); - stylesheet.textContent = stylesheetContent; - // var heads = output_document.getElementsByTagName("head"); - // if (heads.length) { - // heads[0].appendChild(stylesheet); - // } - - var status_number = {}; - forEach(tests, - function(test) { - var status = test.format_status(); - if (status_number.hasOwnProperty(status)) { - status_number[status] += 1; - } else { - status_number[status] = 1; - } - }); - - function status_class(status) - { - return status.replace(/\s/g, '').toLowerCase(); - } - - var summary_template = ["section", {"id":"summary"}, - ["h2", {}, "Summary"], - function() - { - var status = harness_status.format_status(); - var rv = [["section", {}, - ["p", {}, - "Harness status: ", - ["span", {"class":status_class(status)}, - status - ], - ], - ["button", - {"onclick": "let evt = new Event('__test_restart'); " + - "let canceled = !window.dispatchEvent(evt);" + - "if (!canceled) { location.reload() }"}, - "Rerun"] - ]]; - - if (harness_status.status === harness_status.ERROR) { - rv[0].push(["pre", {}, harness_status.message]); - if (harness_status.stack) { - rv[0].push(["pre", {}, harness_status.stack]); - } - } - return rv; - }, - ["p", {}, "Found ${num_tests} tests"], - function() { - var rv = [["div", {}]]; - var i = 0; - while (Test.prototype.status_formats.hasOwnProperty(i)) { - if (status_number.hasOwnProperty(Test.prototype.status_formats[i])) { - var status = Test.prototype.status_formats[i]; - rv[0].push(["div", {}, - ["label", {}, - ["input", {type:"checkbox", checked:"checked"}], - status_number[status] + " ", - ["span", {"class":status_class(status)}, status]]]); - } - i++; - } - return rv; - }, - ]; - - log.appendChild(render(summary_template, {num_tests:tests.length}, output_document)); - - forEach(output_document.querySelectorAll("section#summary label"), - function(element) - { - on_event(element, "click", - function(e) - { - if (output_document.getElementById("results") === null) { - e.preventDefault(); - return; - } - var result_class = element.querySelector("span[class]").getAttribute("class"); - var style_element = output_document.querySelector("style#hide-" + result_class); - var input_element = element.querySelector("input"); - if (!style_element && !input_element.checked) { - style_element = output_document.createElementNS(xhtml_ns, "style"); - style_element.id = "hide-" + result_class; - style_element.textContent = "table#results > tbody > tr.overall-"+result_class+"{display:none}"; - output_document.body.appendChild(style_element); - } else if (style_element && input_element.checked) { - style_element.parentNode.removeChild(style_element); - } - }); - }); - - // This use of innerHTML plus manual escaping is not recommended in - // general, but is necessary here for performance. Using textContent - // on each individual adds tens of seconds of execution time for - // large test suites (tens of thousands of tests). - function escape_html(s) - { - return s.replace(/\&/g, "&") - .replace(/ { - if (!asserts_run_by_test.has(assert.test)) { - asserts_run_by_test.set(assert.test, []); - } - asserts_run_by_test.get(assert.test).push(assert); - }); - - function get_asserts_output(test) { - var asserts = asserts_run_by_test.get(test); - if (!asserts) { - return "No asserts ran"; - } - rv = ""; - rv += asserts.map(assert => { - var output_fn = "" + escape_html(assert.assert_name) + "("; - var prefix_len = output_fn.length; - var output_args = assert.args; - var output_len = output_args.reduce((prev, current) => prev+current, prefix_len); - if (output_len[output_len.length - 1] > 50) { - output_args = output_args.map((x, i) => - (i > 0 ? " ".repeat(prefix_len) : "" )+ x + (i < output_args.length - 1 ? ",\n" : "")); - } else { - output_args = output_args.map((x, i) => x + (i < output_args.length - 1 ? ", " : "")); - } - output_fn += escape_html(output_args.join("")); - output_fn += ')'; - var output_location; - if (assert.stack) { - output_location = assert.stack.split("\n", 1)[0].replace(/@?\w+:\/\/[^ "\/]+(?::\d+)?/g, " "); - } - return "" + - "" + - ""; - } - ).join("\n"); - rv += "
      " + - Test.prototype.status_formats[assert.status] + "
      " +
      -                    output_fn +
      -                    (output_location ? "\n" + escape_html(output_location) : "") +
      -                    "
      "; - return rv; - } - - log.appendChild(document.createElementNS(xhtml_ns, "section")); - var assertions = has_assertions(); - var html = "

      Details

      " + - "" + - (assertions ? "" : "") + - "" + - ""; - for (var i = 0; i < tests.length; i++) { - var test = tests[i]; - html += '' + - '"; - } - html += "
      ResultTest NameAssertionMessage
      ' + - test.format_status() + - "" + - escape_html(test.name) + - "" + - (assertions ? escape_html(get_assertion(test)) + "" : "") + - escape_html(test.message ? tests[i].message : " ") + - (tests[i].stack ? "
      " +
      -                 escape_html(tests[i].stack) +
      -                 "
      ": ""); - if (!(test instanceof RemoteTest)) { - html += "
      Asserts run" + get_asserts_output(test) + "
      " - } - html += "
      "; - try { - log.lastChild.innerHTML = html; - } catch (e) { - log.appendChild(document.createElementNS(xhtml_ns, "p")) - .textContent = "Setting innerHTML for the log threw an exception."; - log.appendChild(document.createElementNS(xhtml_ns, "pre")) - .textContent = html; - } - }; - - /* - * Template code - * - * A template is just a JavaScript structure. An element is represented as: - * - * [tag_name, {attr_name:attr_value}, child1, child2] - * - * the children can either be strings (which act like text nodes), other templates or - * functions (see below) - * - * A text node is represented as - * - * ["{text}", value] - * - * String values have a simple substitution syntax; ${foo} represents a variable foo. - * - * It is possible to embed logic in templates by using a function in a place where a - * node would usually go. The function must either return part of a template or null. - * - * In cases where a set of nodes are required as output rather than a single node - * with children it is possible to just use a list - * [node1, node2, node3] - * - * Usage: - * - * render(template, substitutions) - take a template and an object mapping - * variable names to parameters and return either a DOM node or a list of DOM nodes - * - * substitute(template, substitutions) - take a template and variable mapping object, - * make the variable substitutions and return the substituted template - * - */ - - function is_single_node(template) - { - return typeof template[0] === "string"; - } - - function substitute(template, substitutions) - { - if (typeof template === "function") { - var replacement = template(substitutions); - if (!replacement) { - return null; - } - - return substitute(replacement, substitutions); - } - - if (is_single_node(template)) { - return substitute_single(template, substitutions); - } - - return filter(map(template, function(x) { - return substitute(x, substitutions); - }), function(x) {return x !== null;}); - } - - function substitute_single(template, substitutions) - { - var substitution_re = /\$\{([^ }]*)\}/g; - - function do_substitution(input) { - var components = input.split(substitution_re); - var rv = []; - for (var i = 0; i < components.length; i += 2) { - rv.push(components[i]); - if (components[i + 1]) { - rv.push(String(substitutions[components[i + 1]])); - } - } - return rv; - } - - function substitute_attrs(attrs, rv) - { - rv[1] = {}; - for (var name in template[1]) { - if (attrs.hasOwnProperty(name)) { - var new_name = do_substitution(name).join(""); - var new_value = do_substitution(attrs[name]).join(""); - rv[1][new_name] = new_value; - } - } - } - - function substitute_children(children, rv) - { - for (var i = 0; i < children.length; i++) { - if (children[i] instanceof Object) { - var replacement = substitute(children[i], substitutions); - if (replacement !== null) { - if (is_single_node(replacement)) { - rv.push(replacement); - } else { - extend(rv, replacement); - } - } - } else { - extend(rv, do_substitution(String(children[i]))); - } - } - return rv; - } - - var rv = []; - rv.push(do_substitution(String(template[0])).join("")); - - if (template[0] === "{text}") { - substitute_children(template.slice(1), rv); - } else { - substitute_attrs(template[1], rv); - substitute_children(template.slice(2), rv); - } - - return rv; - } - - function make_dom_single(template, doc) - { - var output_document = doc || document; - var element; - if (template[0] === "{text}") { - element = output_document.createTextNode(""); - for (var i = 1; i < template.length; i++) { - element.data += template[i]; - } - } else { - element = output_document.createElementNS(xhtml_ns, template[0]); - for (var name in template[1]) { - if (template[1].hasOwnProperty(name)) { - element.setAttribute(name, template[1][name]); - } - } - for (var i = 2; i < template.length; i++) { - if (template[i] instanceof Object) { - var sub_element = make_dom(template[i]); - element.appendChild(sub_element); - } else { - var text_node = output_document.createTextNode(template[i]); - element.appendChild(text_node); - } - } - } - - return element; - } - - function make_dom(template, substitutions, output_document) - { - if (is_single_node(template)) { - return make_dom_single(template, output_document); - } - - return map(template, function(x) { - return make_dom_single(x, output_document); - }); - } - - function render(template, substitutions, output_document) - { - return make_dom(substitute(template, substitutions), output_document); - } - - /* - * Utility functions - */ - function assert(expected_true, function_name, description, error, substitutions) - { - if (expected_true !== true) { - var msg = make_message(function_name, description, - error, substitutions); - throw new AssertionError(msg); - } - } - - /** - * @class - * Exception type that represents a failing assert. - * - * @param {string} message - Error message. - */ - function AssertionError(message) - { - if (typeof message == "string") { - message = sanitize_unpaired_surrogates(message); - } - this.message = message; - this.stack = get_stack(); - } - expose(AssertionError, "AssertionError"); - - AssertionError.prototype = Object.create(Error.prototype); - - const get_stack = function() { - var stack = new Error().stack; - - // 'Error.stack' is not supported in all browsers/versions - if (!stack) { - return "(Stack trace unavailable)"; - } - - var lines = stack.split("\n"); - - // Create a pattern to match stack frames originating within testharness.js. These include the - // script URL, followed by the line/col (e.g., '/resources/testharness.js:120:21'). - // Escape the URL per http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript - // in case it contains RegExp characters. - var script_url = get_script_url(); - var re_text = script_url ? script_url.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') : "\\btestharness.js"; - var re = new RegExp(re_text + ":\\d+:\\d+"); - - // Some browsers include a preamble that specifies the type of the error object. Skip this by - // advancing until we find the first stack frame originating from testharness.js. - var i = 0; - while (!re.test(lines[i]) && i < lines.length) { - i++; - } - - // Then skip the top frames originating from testharness.js to begin the stack at the test code. - while (re.test(lines[i]) && i < lines.length) { - i++; - } - - // Paranoid check that we didn't skip all frames. If so, return the original stack unmodified. - if (i >= lines.length) { - return stack; - } - - return lines.slice(i).join("\n"); - } - - function OptionalFeatureUnsupportedError(message) - { - AssertionError.call(this, message); - } - OptionalFeatureUnsupportedError.prototype = Object.create(AssertionError.prototype); - expose(OptionalFeatureUnsupportedError, "OptionalFeatureUnsupportedError"); - - function make_message(function_name, description, error, substitutions) - { - for (var p in substitutions) { - if (substitutions.hasOwnProperty(p)) { - substitutions[p] = format_value(substitutions[p]); - } - } - var node_form = substitute(["{text}", "${function_name}: ${description}" + error], - merge({function_name:function_name, - description:(description?description + " ":"")}, - substitutions)); - return node_form.slice(1).join(""); - } - - function filter(array, callable, thisObj) { - var rv = []; - for (var i = 0; i < array.length; i++) { - if (array.hasOwnProperty(i)) { - var pass = callable.call(thisObj, array[i], i, array); - if (pass) { - rv.push(array[i]); - } - } - } - return rv; - } - - function map(array, callable, thisObj) - { - var rv = []; - rv.length = array.length; - for (var i = 0; i < array.length; i++) { - if (array.hasOwnProperty(i)) { - rv[i] = callable.call(thisObj, array[i], i, array); - } - } - return rv; - } - - function extend(array, items) - { - Array.prototype.push.apply(array, items); - } - - function forEach(array, callback, thisObj) - { - for (var i = 0; i < array.length; i++) { - if (array.hasOwnProperty(i)) { - callback.call(thisObj, array[i], i, array); - } - } - } - - /** - * Immediately invoke a "iteratee" function with a series of values in - * parallel and invoke a final "done" function when all of the "iteratee" - * invocations have signaled completion. - * - * If all callbacks complete synchronously (or if no callbacks are - * specified), the ``done_callback`` will be invoked synchronously. It is the - * responsibility of the caller to ensure asynchronicity in cases where - * that is desired. - * - * @param {array} value Zero or more values to use in the invocation of - * ``iter_callback`` - * @param {function} iter_callback A function that will be invoked - * once for each of the values min - * ``value``. Two arguments will - * be available in each - * invocation: the value from - * ``value`` and a function that - * must be invoked to signal - * completion - * @param {function} done_callback A function that will be invoked after - * all operations initiated by the - * ``iter_callback`` function have signaled - * completion - */ - function all_async(values, iter_callback, done_callback) - { - var remaining = values.length; - - if (remaining === 0) { - done_callback(); - } - - forEach(values, - function(element) { - var invoked = false; - var elDone = function() { - if (invoked) { - return; - } - - invoked = true; - remaining -= 1; - - if (remaining === 0) { - done_callback(); - } - }; - - iter_callback(element, elDone); - }); - } - - function merge(a,b) - { - var rv = {}; - var p; - for (p in a) { - rv[p] = a[p]; - } - for (p in b) { - rv[p] = b[p]; - } - return rv; - } - - function expose(object, name) - { - var components = name.split("."); - var target = global_scope; - for (var i = 0; i < components.length - 1; i++) { - if (!(components[i] in target)) { - target[components[i]] = {}; - } - target = target[components[i]]; - } - target[components[components.length - 1]] = object; - } - - function is_same_origin(w) { - try { - 'random_prop' in w; - return true; - } catch (e) { - return false; - } - } - - /** Returns the 'src' URL of the first - -
      -