From 56b08bddd833f772796db3d2c1debf868e8236fa Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Tue, 9 Sep 2025 20:40:13 +0800 Subject: [PATCH] migrate more tests to htmlRunner --- src/browser/dom/node.zig | 261 +----------------------------- src/browser/dom/node_filter.zig | 13 +- src/browser/dom/node_iterator.zig | 69 +------- src/browser/dom/nodelist.zig | 20 +-- src/browser/html/elements.zig | 2 +- src/tests/dom/node.html | 225 ++++++++++++++++++++++++++ src/tests/dom/node_filter.html | 8 + src/tests/dom/node_iterator.html | 61 +++++++ src/tests/dom/node_list.html | 18 +++ src/tests/dom/node_owner.html | 33 ++++ 10 files changed, 355 insertions(+), 355 deletions(-) create mode 100644 src/tests/dom/node.html create mode 100644 src/tests/dom/node_filter.html create mode 100644 src/tests/dom/node_iterator.html create mode 100644 src/tests/dom/node_list.html create mode 100644 src/tests/dom/node_owner.html diff --git a/src/browser/dom/node.zig b/src/browser/dom/node.zig index 5dc171b4..35f91208 100644 --- a/src/browser/dom/node.zig +++ b/src/browser/dom/node.zig @@ -631,262 +631,7 @@ pub const Node = struct { }; const testing = @import("../../testing.zig"); -test "Browser.DOM.node" { - var runner = try testing.jsRunner(testing.tracking_allocator, .{}); - defer runner.deinit(); - - { - var err_out: ?[]const u8 = null; - try runner.exec( - \\ function trimAndReplace(str) { - \\ str = str.replace(/(\r\n|\n|\r)/gm,''); - \\ str = str.replace(/\s+/g, ' '); - \\ str = str.trim(); - \\ return str; - \\ } - , "trimAndReplace", &err_out); - } - - try runner.testCases(&.{ - .{ "document.body.compareDocumentPosition(document.firstChild); ", "10" }, - .{ "document.getElementById(\"para-empty\").compareDocumentPosition(document.getElementById(\"content\"));", "10" }, - .{ "document.getElementById(\"content\").compareDocumentPosition(document.getElementById(\"para-empty\"));", "20" }, - .{ "document.getElementById(\"link\").compareDocumentPosition(document.getElementById(\"link\"));", "0" }, - .{ "document.getElementById(\"para-empty\").compareDocumentPosition(document.getElementById(\"link\"));", "2" }, - .{ "document.getElementById(\"link\").compareDocumentPosition(document.getElementById(\"para-empty\"));", "4" }, - }, .{}); - - try runner.testCases(&.{ - .{ "document.getElementById('content').getRootNode().__proto__.constructor.name", "HTMLDocument" }, - }, .{}); - - try runner.testCases(&.{ - // for next test cases - .{ "let content = document.getElementById('content')", "undefined" }, - .{ "let link = document.getElementById('link')", "undefined" }, - .{ "let first_child = content.firstChild.nextSibling", "undefined" }, // nextSibling because of line return \n - - .{ "let body_first_child = document.body.firstChild", "undefined" }, - .{ "body_first_child.localName", "div" }, - .{ "body_first_child.__proto__.constructor.name", "HTMLDivElement" }, - .{ "document.getElementById('para-empty').firstChild.firstChild", "null" }, - }, .{}); - - try runner.testCases(&.{ - .{ "let last_child = content.lastChild.previousSibling", "undefined" }, // previousSibling because of line return \n - .{ "last_child.__proto__.constructor.name", "Comment" }, - }, .{}); - - try runner.testCases(&.{ - .{ "let next_sibling = link.nextSibling.nextSibling", "undefined" }, - .{ "next_sibling.localName", "p" }, - .{ "next_sibling.__proto__.constructor.name", "HTMLParagraphElement" }, - .{ "content.nextSibling.nextSibling", "null" }, - }, .{}); - - try runner.testCases(&.{ - .{ "let prev_sibling = document.getElementById('para-empty').previousSibling.previousSibling", "undefined" }, - .{ "prev_sibling.localName", "a" }, - .{ "prev_sibling.__proto__.constructor.name", "HTMLAnchorElement" }, - .{ "content.previousSibling", "null" }, - }, .{}); - - try runner.testCases(&.{ - .{ "let parent = document.getElementById('para').parentElement", "undefined" }, - .{ "parent.localName", "div" }, - .{ "parent.__proto__.constructor.name", "HTMLDivElement" }, - .{ "let h = content.parentElement.parentElement", "undefined" }, - .{ "h.parentElement", "null" }, - .{ "h.parentNode.__proto__.constructor.name", "HTMLDocument" }, - }, .{}); - - try runner.testCases(&.{ - .{ "first_child.nodeName === 'A'", "true" }, - .{ "link.firstChild.nodeName === '#text'", "true" }, - .{ "last_child.nodeName === '#comment'", "true" }, - .{ "document.nodeName === '#document'", "true" }, - }, .{}); - - try runner.testCases(&.{ - .{ "first_child.nodeType === 1", "true" }, - .{ "link.firstChild.nodeType === 3", "true" }, - .{ "last_child.nodeType === 8", "true" }, - .{ "document.nodeType === 9", "true" }, - }, .{}); - - try runner.testCases(&.{ - .{ "let owner = content.ownerDocument", "undefined" }, - .{ "owner.__proto__.constructor.name", "HTMLDocument" }, - .{ "document.ownerDocument", "null" }, - .{ "let owner2 = document.createElement('div').ownerDocument", "undefined" }, - .{ "owner2.__proto__.constructor.name", "HTMLDocument" }, - }, .{}); - - try runner.testCases(&.{ - .{ "content.isConnected", "true" }, - .{ "document.isConnected", "true" }, - .{ "const connDiv = document.createElement('div')", null }, - .{ "connDiv.isConnected", "false" }, - .{ "const connParentDiv = document.createElement('div')", null }, - .{ "connParentDiv.appendChild(connDiv)", null }, - .{ "connDiv.isConnected", "false" }, - .{ "content.appendChild(connParentDiv)", null }, - .{ "connDiv.isConnected", "true" }, - }, .{}); - - try runner.testCases(&.{ - .{ "last_child.nodeValue === 'comment'", "true" }, - .{ "link.nodeValue === null", "true" }, - .{ "let text = link.firstChild", "undefined" }, - .{ "text.nodeValue === 'OK'", "true" }, - .{ "text.nodeValue = 'OK modified'", "OK modified" }, - .{ "text.nodeValue === 'OK modified'", "true" }, - .{ "link.nodeValue = 'nothing'", "nothing" }, - }, .{}); - - try runner.testCases(&.{ - .{ "text.textContent === 'OK modified'", "true" }, - .{ "trimAndReplace(content.textContent) === 'OK modified And'", "true" }, - .{ "text.textContent = 'OK'", "OK" }, - .{ "text.textContent", "OK" }, - .{ "trimAndReplace(document.getElementById('para-empty').textContent)", "" }, - .{ "document.getElementById('para-empty').textContent = 'OK'", "OK" }, - .{ "document.getElementById('para-empty').firstChild.nodeName === '#text'", "true" }, - }, .{}); - - try runner.testCases(&.{ - .{ "let append = document.createElement('h1')", "undefined" }, - .{ "content.appendChild(append).toString()", "[object HTMLHeadingElement]" }, - .{ "content.lastChild.__proto__.constructor.name", "HTMLHeadingElement" }, - .{ "content.appendChild(link).toString()", "[object HTMLAnchorElement]" }, - }, .{}); - - try runner.testCases(&.{ - .{ "let clone = link.cloneNode()", "undefined" }, - .{ "clone.toString()", "[object HTMLAnchorElement]" }, - .{ "clone.parentNode === null", "true" }, - .{ "clone.firstChild === null", "true" }, - .{ "let clone_deep = link.cloneNode(true)", "undefined" }, - .{ "clone_deep.firstChild.nodeName === '#text'", "true" }, - }, .{}); - - try runner.testCases(&.{ - .{ "link.contains(text)", "true" }, - .{ "text.contains(link)", "false" }, - }, .{}); - - try runner.testCases(&.{ - .{ "link.hasChildNodes()", "true" }, - .{ "text.hasChildNodes()", "false" }, - }, .{}); - - try runner.testCases(&.{ - .{ "link.childNodes.length", "1" }, - .{ "text.childNodes.length", "0" }, - }, .{}); - - try runner.testCases(&.{ - .{ "let insertBefore = document.createElement('a')", "undefined" }, - .{ "link.insertBefore(insertBefore, text) !== undefined", "true" }, - .{ "link.firstChild.localName === 'a'", "true" }, - - .{ "let insertBefore2 = document.createElement('b')", null }, - .{ "link.insertBefore(insertBefore2, null).localName", "b" }, - .{ "link.childNodes[link.childNodes.length - 1].localName", "b" }, - }, .{}); - - try runner.testCases(&.{ - // TODO: does not seems to work - // .{ "link.isDefaultNamespace('')", "true" }, - .{ "link.isDefaultNamespace('false')", "false" }, - }, .{}); - - try runner.testCases(&.{ - .{ "let equal1 = document.createElement('a')", "undefined" }, - .{ "let equal2 = document.createElement('a')", "undefined" }, - .{ "equal1.textContent = 'is equal'", "is equal" }, - .{ "equal2.textContent = 'is equal'", "is equal" }, - // TODO: does not seems to work - // .{ "equal1.isEqualNode(equal2)", "true" }, - }, .{}); - - try runner.testCases(&.{ - .{ "document.body.isSameNode(document.body)", "true" }, - }, .{}); - - try runner.testCases(&.{ - // TODO: no test - .{ "link.normalize()", "undefined" }, - }, .{}); - - try runner.testCases(&.{ - .{ "link.baseURI", "https://lightpanda.io/opensource-browser/" }, - }, .{}); - - try runner.testCases(&.{ - .{ "content.removeChild(append) !== undefined", "true" }, - .{ "last_child.__proto__.constructor.name !== 'HTMLHeadingElement'", "true" }, - }, .{}); - - try runner.testCases(&.{ - .{ "let replace = document.createElement('div')", "undefined" }, - .{ "link.replaceChild(replace, insertBefore) !== undefined", "true" }, - }, .{}); - - try runner.testCases(&.{ - .{ "Node.ELEMENT_NODE", "1" }, - .{ "Node.ATTRIBUTE_NODE", "2" }, - .{ "Node.TEXT_NODE", "3" }, - .{ "Node.CDATA_SECTION_NODE", "4" }, - .{ "Node.PROCESSING_INSTRUCTION_NODE", "7" }, - .{ "Node.COMMENT_NODE", "8" }, - .{ "Node.DOCUMENT_NODE", "9" }, - .{ "Node.DOCUMENT_TYPE_NODE", "10" }, - .{ "Node.DOCUMENT_FRAGMENT_NODE", "11" }, - .{ "Node.ENTITY_REFERENCE_NODE", "5" }, - .{ "Node.ENTITY_NODE", "6" }, - .{ "Node.NOTATION_NODE", "12" }, - }, .{}); -} - -test "Browser.DOM.node.owner" { - var runner = try testing.jsRunner(testing.tracking_allocator, .{ .html = - \\
- \\

- \\ I am the original reference node. - \\

- \\
" - }); - - defer runner.deinit(); - - try runner.testCases(&.{ - .{ - \\ const parser = new DOMParser(); - \\ const newDoc = parser.parseFromString('

Hey

Marked
', 'text/html'); - \\ const newNode = newDoc.getElementById('new-node'); - \\ const parent = document.getElementById('target-container'); - \\ const referenceNode = document.getElementById('reference-node'); - \\ parent.insertBefore(newNode, referenceNode); - \\ const k = document.getElementById('new-node'); - \\ const ptag = k.querySelector('p'); - \\ const spanTag = k.querySelector('span'); - \\ const anotherDoc = parser.parseFromString('
', 'text/html'); - \\ const anotherNewNode = anotherDoc.getElementById('another-new-node'); - \\ - \\ parent.appendChild(anotherNewNode) - , - "[object HTMLDivElement]", - }, - - .{ "parent.ownerDocument === newNode.ownerDocument", "true" }, - .{ "parent.ownerDocument === anotherNewNode.ownerDocument", "true" }, - .{ "newNode.firstChild.nodeName", "P" }, - .{ "ptag.ownerDocument === parent.ownerDocument", "true" }, - .{ "spanTag.ownerDocument === parent.ownerDocument", "true" }, - .{ "parent.contains(newNode)", "true" }, - .{ "parent.contains(anotherNewNode)", "true" }, - .{ "anotherDoc.contains(anotherNewNode)", "false" }, - .{ "newDoc.contains(newNode)", "false" }, - }, .{}); +test "Browser: DOM.Node" { + try testing.htmlRunner("dom/node.html"); + try testing.htmlRunner("dom/node_owner.html"); } diff --git a/src/browser/dom/node_filter.zig b/src/browser/dom/node_filter.zig index 88cb4e57..1539c1e9 100644 --- a/src/browser/dom/node_filter.zig +++ b/src/browser/dom/node_filter.zig @@ -75,15 +75,6 @@ pub fn verify(what_to_show: u32, filter: ?Env.Function, node: *parser.Node) !Ver } const testing = @import("../../testing.zig"); -test "Browser.DOM.NodeFilter" { - var runner = try testing.jsRunner(testing.tracking_allocator, .{}); - defer runner.deinit(); - - try runner.testCases(&.{ - .{ "NodeFilter.FILTER_ACCEPT", "1" }, - .{ "NodeFilter.FILTER_REJECT", "2" }, - .{ "NodeFilter.FILTER_SKIP", "3" }, - .{ "NodeFilter.SHOW_ALL", "4294967295" }, - .{ "NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT", "129" }, - }, .{}); +test "Browser: DOM.NodeFilter" { + try testing.htmlRunner("dom/node_filter.html"); } diff --git a/src/browser/dom/node_iterator.zig b/src/browser/dom/node_iterator.zig index 0d3c53a6..be497008 100644 --- a/src/browser/dom/node_iterator.zig +++ b/src/browser/dom/node_iterator.zig @@ -268,71 +268,6 @@ pub const NodeIterator = struct { }; const testing = @import("../../testing.zig"); -test "Browser.DOM.NodeFilter" { - var runner = try testing.jsRunner(testing.tracking_allocator, .{}); - defer runner.deinit(); - - try runner.testCases(&.{ - .{ - \\ const nodeIterator = document.createNodeIterator( - \\ document.body, - \\ NodeFilter.SHOW_ELEMENT, - \\ { - \\ acceptNode(node) { - \\ return NodeFilter.FILTER_ACCEPT; - \\ }, - \\ }, - \\ ); - \\ nodeIterator.nextNode().nodeName; - , - "BODY", - }, - .{ "nodeIterator.nextNode().nodeName", "DIV" }, - .{ "nodeIterator.nextNode().nodeName", "A" }, - .{ "nodeIterator.previousNode().nodeName", "A" }, // pointer_before_current flips - .{ "nodeIterator.nextNode().nodeName", "A" }, // pointer_before_current flips - .{ "nodeIterator.previousNode().nodeName", "A" }, // pointer_before_current flips - .{ "nodeIterator.previousNode().nodeName", "DIV" }, - .{ "nodeIterator.previousNode().nodeName", "BODY" }, - .{ "nodeIterator.previousNode()", "null" }, // Not HEAD since body is root - .{ "nodeIterator.previousNode()", "null" }, // Keeps returning null - .{ "nodeIterator.nextNode().nodeName", "BODY" }, - - .{ "nodeIterator.nextNode().nodeName", null }, - .{ "nodeIterator.nextNode().nodeName", null }, - .{ "nodeIterator.nextNode().nodeName", null }, - .{ "nodeIterator.nextNode().nodeName", "SPAN" }, - .{ "nodeIterator.nextNode().nodeName", "P" }, - .{ "nodeIterator.nextNode()", "null" }, // Just the last one - .{ "nodeIterator.nextNode()", "null" }, // Keeps returning null - .{ "nodeIterator.previousNode().nodeName", "P" }, - }, .{}); - - try runner.testCases(&.{ - .{ - \\ const notationIterator = document.createNodeIterator( - \\ document.body, - \\ NodeFilter.SHOW_NOTATION, - \\ ); - \\ notationIterator.nextNode(); - , - "null", - }, - .{ "notationIterator.previousNode()", "null" }, - }, .{}); - - try runner.testCases(&.{ - .{ "nodeIterator.filter.acceptNode(document.body)", "1" }, - .{ "notationIterator.filter", "null" }, - .{ - \\ const rejectIterator = document.createNodeIterator( - \\ document.body, - \\ NodeFilter.SHOW_ALL, - \\ (e => { return NodeFilter.FILTER_REJECT}), - \\ ); - \\ rejectIterator.filter(document.body); - , - "2", - }, - }, .{}); +test "Browser: DOM.NodeIterator" { + try testing.htmlRunner("dom/node_iterator.html"); } diff --git a/src/browser/dom/nodelist.zig b/src/browser/dom/nodelist.zig index 22e8708f..d098cfd3 100644 --- a/src/browser/dom/nodelist.zig +++ b/src/browser/dom/nodelist.zig @@ -177,22 +177,6 @@ pub const NodeList = struct { }; const testing = @import("../../testing.zig"); -test "Browser.DOM.NodeList" { - var runner = try testing.jsRunner(testing.tracking_allocator, .{}); - defer runner.deinit(); - - try runner.testCases(&.{ - .{ "let list = document.getElementById('content').childNodes", "undefined" }, - .{ "list.length", "9" }, - .{ "list[0].__proto__.constructor.name", "Text" }, - .{ - \\ let i = 0; - \\ list.forEach(function (n, idx) { - \\ i += idx; - \\ }); - \\ i; - , - "36", - }, - }, .{}); +test "Browser: DOM.NodeList" { + try testing.htmlRunner("dom/node_list.html"); } diff --git a/src/browser/html/elements.zig b/src/browser/html/elements.zig index 6acb818e..e1820571 100644 --- a/src/browser/html/elements.zig +++ b/src/browser/html/elements.zig @@ -1055,7 +1055,7 @@ pub const HTMLSlotElement = struct { fn findAssignedSlotNodes(self: *parser.Slot, opts: AssignedNodesOpts, page: *Page) !?[]NodeUnion { if (opts.flatten) { - log.warn(.web_api, "not implemented", .{ .feature = "HTMLSlotElement flatten assignedNodes" }); + log.debug(.web_api, "not implemented", .{ .feature = "HTMLSlotElement flatten assignedNodes" }); } const slot_name = try parser.elementGetAttribute(@ptrCast(@alignCast(self)), "name"); diff --git a/src/tests/dom/node.html b/src/tests/dom/node.html new file mode 100644 index 00000000..8879b846 --- /dev/null +++ b/src/tests/dom/node.html @@ -0,0 +1,225 @@ +
+ OK +

+ +

+

And

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/tests/dom/node_filter.html b/src/tests/dom/node_filter.html new file mode 100644 index 00000000..21e21a8f --- /dev/null +++ b/src/tests/dom/node_filter.html @@ -0,0 +1,8 @@ + + diff --git a/src/tests/dom/node_iterator.html b/src/tests/dom/node_iterator.html new file mode 100644 index 00000000..740a3369 --- /dev/null +++ b/src/tests/dom/node_iterator.html @@ -0,0 +1,61 @@ + + + + +
+ OK +

+ +

+

And

+ +
+ diff --git a/src/tests/dom/node_list.html b/src/tests/dom/node_list.html new file mode 100644 index 00000000..9260cf6f --- /dev/null +++ b/src/tests/dom/node_list.html @@ -0,0 +1,18 @@ +
+ OK +

+ +

+

And

+ +
+ + + diff --git a/src/tests/dom/node_owner.html b/src/tests/dom/node_owner.html new file mode 100644 index 00000000..2b4aee04 --- /dev/null +++ b/src/tests/dom/node_owner.html @@ -0,0 +1,33 @@ +
+

+ I am the original reference node. +

+
+ + +