+
+
+
diff --git a/tests/wpt/dom/nodes/Element-matches-init.js b/tests/wpt/dom/nodes/Element-matches-init.js
new file mode 100644
index 00000000..254af615
--- /dev/null
+++ b/tests/wpt/dom/nodes/Element-matches-init.js
@@ -0,0 +1,65 @@
+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
new file mode 100644
index 00000000..e61b11ca
--- /dev/null
+++ b/tests/wpt/dom/nodes/Element-matches-namespaced-elements.html
@@ -0,0 +1,24 @@
+
+
+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
new file mode 100644
index 00000000..de234b66
--- /dev/null
+++ b/tests/wpt/dom/nodes/Element-matches.html
@@ -0,0 +1,22 @@
+
+
+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
new file mode 100644
index 00000000..a1455c67
--- /dev/null
+++ b/tests/wpt/dom/nodes/Element-matches.js
@@ -0,0 +1,135 @@
+/*
+ * 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-remove.html b/tests/wpt/dom/nodes/Element-remove.html
new file mode 100644
index 00000000..ab642d66
--- /dev/null
+++ b/tests/wpt/dom/nodes/Element-remove.html
@@ -0,0 +1,16 @@
+
+
+Element.remove
+
+
+
+
+
+
diff --git a/tests/wpt/dom/nodes/Element-siblingElement-null-svg.svg b/tests/wpt/dom/nodes/Element-siblingElement-null-svg.svg
new file mode 100644
index 00000000..48c981b8
--- /dev/null
+++ b/tests/wpt/dom/nodes/Element-siblingElement-null-svg.svg
@@ -0,0 +1,20 @@
+
+
diff --git a/tests/wpt/dom/nodes/Element-siblingElement-null-xhtml.xhtml b/tests/wpt/dom/nodes/Element-siblingElement-null-xhtml.xhtml
new file mode 100644
index 00000000..fcf4d54f
--- /dev/null
+++ b/tests/wpt/dom/nodes/Element-siblingElement-null-xhtml.xhtml
@@ -0,0 +1,20 @@
+
+
+
+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
new file mode 100644
index 00000000..a7920b4f
--- /dev/null
+++ b/tests/wpt/dom/nodes/Element-siblingElement-null.html
@@ -0,0 +1,16 @@
+
+
+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
new file mode 100644
index 00000000..43e7a2d2
--- /dev/null
+++ b/tests/wpt/dom/nodes/Element-tagName.html
@@ -0,0 +1,57 @@
+
+Element.tagName
+
+
+
+
diff --git a/tests/wpt/dom/nodes/Element-webkitMatchesSelector.html b/tests/wpt/dom/nodes/Element-webkitMatchesSelector.html
new file mode 100644
index 00000000..107f8102
--- /dev/null
+++ b/tests/wpt/dom/nodes/Element-webkitMatchesSelector.html
@@ -0,0 +1,22 @@
+
+
+Selectors-API Level 2 Test Suite: HTML with Selectors Level 3
+
+
+
+
+
+
+
+
+
+