From ec0838b84eb662b715b79141ea983339569644d3 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Thu, 24 Oct 2024 19:21:55 +0200 Subject: [PATCH] LibWeb: Implement HTMLElement.innerText closer to spec And here's the wild part: instead of cloning WPT tests, import the relevant WPT tests that this fixes into our own test suite. This works by adding a small Ladybird-specific callback in resources/testharnessreport.js (which is what that file is meant for!) Note that these run as text tests, and so they must signal the runner when they are done. Tests using the "usual" WPT harness should just work, but tests that do something more freestyle will need manual signaling if they are to be imported. I've also increased the test timeout here from 30 to 60 seconds, to accommodate the larger WPT-style tests. --- .prettierignore | 2 + Ladybird/Headless/Test.h | 2 +- .../expected/DOM/Range-deleteContents.txt | 3 +- .../input-into-empty-contenteditable.txt | 3 +- ...ith-unsupported-type-in-data-attribute.txt | 4 +- .../dynamic-getter.txt | 17 + .../getter-first-letter-marker-multicol.txt | 11 + .../getter.txt | 282 + .../innertext-domnoderemoved-crash.txt | 1 + .../innertext-setter.txt | 136 + .../innertext-whitespace-pre-line.txt | 12 + .../outertext-setter.txt | 54 + .../dynamic-getter.html | 88 + .../getter-first-letter-marker-multicol.html | 18 + .../getter-tests.js | 414 ++ .../getter.html | 64 + .../innertext-domnoderemoved-crash.html | 19 + .../innertext-setter-tests.js | 42 + .../innertext-setter.html | 88 + .../innertext-whitespace-pre-line.html | 42 + .../multiple-text-nodes.window.js | 16 + .../outertext-setter.html | 180 + .../input/wpt-import/resources/testharness.js | 4959 +++++++++++++++++ .../wpt-import/resources/testharnessreport.js | 45 + .../Libraries/LibWeb/HTML/HTMLElement.cpp | 157 +- 25 files changed, 6638 insertions(+), 21 deletions(-) create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/dynamic-getter.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/getter-first-letter-marker-multicol.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/getter.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/innertext-domnoderemoved-crash.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/innertext-setter.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/innertext-whitespace-pre-line.txt create mode 100644 Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.txt create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/dynamic-getter.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/getter-first-letter-marker-multicol.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/getter-tests.js create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/getter.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/innertext-domnoderemoved-crash.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/innertext-setter-tests.js create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/innertext-setter.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/innertext-whitespace-pre-line.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/multiple-text-nodes.window.js create mode 100644 Tests/LibWeb/Text/input/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/outertext-setter.html create mode 100644 Tests/LibWeb/Text/input/wpt-import/resources/testharness.js create mode 100644 Tests/LibWeb/Text/input/wpt-import/resources/testharnessreport.js diff --git a/.prettierignore b/.prettierignore index 3a49c298575..cc85b4ff23d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -7,3 +7,5 @@ Userland/Libraries/LibJS/Tests/builtins/DisposableStack/DisposableStack.prototyp Userland/Libraries/LibJS/Tests/modules/top-level-dispose.mjs Userland/Libraries/LibJS/Tests/using-declaration.js Userland/Libraries/LibJS/Tests/using-for-loops.js + +Tests/LibWeb/Text/input/wpt-import diff --git a/Ladybird/Headless/Test.h b/Ladybird/Headless/Test.h index 3c629387ab7..7d163b1b939 100644 --- a/Ladybird/Headless/Test.h +++ b/Ladybird/Headless/Test.h @@ -75,7 +75,7 @@ struct TestCompletion { using TestPromise = Core::Promise; -constexpr inline int DEFAULT_TIMEOUT_MS = 30000; // 30sec +constexpr inline int DEFAULT_TIMEOUT_MS = 60'000; ErrorOr run_tests(Core::AnonymousBuffer const& theme, Gfx::IntSize window_size); void run_dump_test(HeadlessWebView&, Test&, URL::URL const&, int timeout_in_milliseconds = DEFAULT_TIMEOUT_MS); diff --git a/Tests/LibWeb/Text/expected/DOM/Range-deleteContents.txt b/Tests/LibWeb/Text/expected/DOM/Range-deleteContents.txt index f238bad6799..8f783d3a80c 100644 --- a/Tests/LibWeb/Text/expected/DOM/Range-deleteContents.txt +++ b/Tests/LibWeb/Text/expected/DOM/Range-deleteContents.txt @@ -1 +1,2 @@ -before after +before + after diff --git a/Tests/LibWeb/Text/expected/Editing/input-into-empty-contenteditable.txt b/Tests/LibWeb/Text/expected/Editing/input-into-empty-contenteditable.txt index c8673204538..824135e7fda 100644 --- a/Tests/LibWeb/Text/expected/Editing/input-into-empty-contenteditable.txt +++ b/Tests/LibWeb/Text/expected/Editing/input-into-empty-contenteditable.txt @@ -1 +1,2 @@ -hello +hello + diff --git a/Tests/LibWeb/Text/expected/object-with-unsupported-type-in-data-attribute.txt b/Tests/LibWeb/Text/expected/object-with-unsupported-type-in-data-attribute.txt index c9a1bf3b3e9..26995309a47 100644 --- a/Tests/LibWeb/Text/expected/object-with-unsupported-type-in-data-attribute.txt +++ b/Tests/LibWeb/Text/expected/object-with-unsupported-type-in-data-attribute.txt @@ -1 +1,3 @@ - Fallback + +Fallback + diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/dynamic-getter.txt b/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/dynamic-getter.txt new file mode 100644 index 00000000000..74de1763d62 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/dynamic-getter.txt @@ -0,0 +1,17 @@ +Summary + +Harness status: OK + +Rerun + +Found 7 tests + +7 Pass +Details +Result Test Name MessagePass text-transform applied to child element ("
abc") +Pass text-transform applied to parent element ("
abc") +Pass display: none applied to child element ("
abc
def") +Pass display: none applied to parent element ("
invisible
abc") +Pass insert node into sub-tree ("
abc") +Pass remove node from sub-tree ("
abc
def") +Pass insert whole sub-tree ("
") \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/getter-first-letter-marker-multicol.txt b/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/getter-first-letter-marker-multicol.txt new file mode 100644 index 00000000000..563f6094449 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/getter-first-letter-marker-multicol.txt @@ -0,0 +1,11 @@ +Summary + +Harness status: OK + +Rerun + +Found 1 tests + +1 Pass +Details +Result Test Name MessagePass Test innerText/outerText for a combination of a list item with ::first-letter in multicol \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/getter.txt b/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/getter.txt new file mode 100644 index 00000000000..7e68a0171b1 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/html/dom/elements/the-innertext-and-outertext-properties/getter.txt @@ -0,0 +1,282 @@ +Summary + +Harness status: OK + +Rerun + +Found 271 tests + +209 Pass +62 Fail +Details +Result Test Name MessagePass Simplest possible test ("
abc") +Fail Leading whitespace removed ("
abc") assert_equals: innerText expected "abc" but got " abc" +Fail Trailing whitespace removed ("
abc ") assert_equals: innerText expected "abc" but got "abc " +Pass Internal whitespace compressed ("
abc def") +Pass \n converted to space ("
abc\ndef") +Pass \r converted to space ("
abc\rdef") +Pass \t converted to space ("
abc\tdef") +Fail Trailing whitespace before hard line break removed ("
abc
def") assert_equals: innerText expected "abc\ndef" but got "abc \ndef" +Fail Leading whitespace after hard line break removed ("
abc
def") assert_equals: innerText expected "abc\ndef" but got "abc\n def" +Pass Leading whitespace preserved ("
 abc")	
+Pass	Trailing whitespace preserved ("
abc ")	
+Pass	Internal whitespace preserved ("
abc def")	
+Pass	\n preserved ("
abc\ndef")	
+Pass	\r converted to newline ("
abc\rdef")	
+Pass	\t preserved ("
abc\tdef")	
+Pass	Two 
 siblings ("
abc
def
") +Pass Leading whitespace preserved ("
abc") +Pass Trailing whitespace preserved ("
abc ") +Pass Internal whitespace preserved ("
abc def") +Pass \n preserved ("
abc\ndef") +Pass \r converted to newline ("
abc\rdef") +Pass \t preserved ("
abc\tdef") +Pass Leading whitespace preserved (" abc") +Pass Trailing whitespace preserved ("abc ") +Pass Internal whitespace preserved ("abc def") +Pass \n preserved ("abc\ndef") +Pass \r converted to newline ("abc\rdef") +Pass \t preserved ("abc\tdef") +Fail Leading whitespace removed ("
abc") assert_equals: innerText expected "abc" but got " abc" +Fail Trailing whitespace removed ("
abc ") assert_equals: innerText expected "abc" but got "abc " +Pass Internal whitespace collapsed ("
abc def") +Fail \n preserved ("
abc\ndef") assert_equals: innerText expected "abc\ndef" but got "abc def" +Fail \r converted to newline ("
abc\rdef") assert_equals: innerText expected "abc\ndef" but got "abc def" +Pass \t converted to space ("
abc\tdef") +Fail Whitespace collapses across element boundaries ("
abc def") assert_equals: innerText expected "abc def" but got "abc def" +Fail Whitespace collapses across element boundaries ("
abc def") assert_equals: innerText expected "abc def" but got "abc def" +Fail Whitespace collapses across element boundaries ("
abc def") assert_equals: innerText expected "abc def" but got "abc def" +Pass Whitespace around should not be collapsed ("
abc def") +Pass Whitespace around inline-block should not be collapsed ("
abc def") +Fail Trailing space at end of inline-block should be collapsed ("
abc def ghi") assert_equals: innerText expected "abc def ghi" but got "abc def ghi" +Pass Whitespace around inline-flex should not be collapsed ("
abc def") +Fail Trailing space at end of inline-flex should be collapsed ("
abc def ghi") assert_equals: innerText expected "abc def ghi" but got "abc def ghi" +Pass Whitespace around inline-grid should not be collapsed ("
abc def") +Fail Trailing space at end of grid-flex should be collapsed ("
abc def ghi") assert_equals: innerText expected "abc def ghi" but got "abc def ghi" +Fail Whitespace between and block should be collapsed ("
abc
") assert_equals: innerText expected "abc" but got " \nabc" +Fail Whitespace between inline-block and block should be collapsed ("
abc
") assert_equals: innerText expected "abc" but got " \nabc" +Fail Whitespace between inline-flex and block should be collapsed ("
abc
") assert_equals: innerText expected "abc" but got " \nabc" +Fail Whitespace between inline-grid and block should be collapsed ("
abc
") assert_equals: innerText expected "abc" but got " \nabc" +Pass Whitespace around should not be collapsed ("
abc def") +Pass Whitespace around should not be collapsed ("
abc def") +Pass Leading whitesapce should not be collapsed ("
abc") +Pass Trailing whitesapce should not be collapsed ("
abc ") +Fail Whitespace around empty span should be collapsed ("
abc def") assert_equals: innerText expected "abc def" but got "abc def" +Fail Whitespace around empty spans should be collapsed ("
abc def") assert_equals: innerText expected "abc def" but got "abc def" +Pass should not collapse following space ("
abc") +Fail Replaced element with display:block should be treated as block-level ("
abc def") assert_equals: innerText expected "abc\ndef" but got "abc \n def" +Fail Replaced element with display:block should be treated as block-level ("
abc def") assert_equals: innerText expected "abc\ndef" but got "abc \n def" +Pass Soft line breaks ignored ("
abc def") +Pass Soft line break at hyphen ignored ("
abc-def") +Pass Whitespace text node preserved ("
abc def") +Pass Soft breaks ignored in presence of word-break:break-word ("
Hello Kitty
") +Pass Element boundaries ignored for soft break handling (1) ("
Hello Kitty
") +Fail Whitespace collapses across element boundaries at soft break (1) ("
Hello Kitty
") assert_equals: innerText expected "Hello Kitty" but got "Hello Kitty" +Pass Element boundaries ignored for soft break handling (2) ("
Hello Kitty
") +Fail Whitespace collapses across element boundaries at soft break (2) ("
Hello Kitty
") assert_equals: innerText expected "Hello Kitty" but got "Hello Kitty" +Pass Element boundaries ignored for soft break handling (3) ("
Hello Kitty
") +Fail Whitespace collapses across element boundaries at soft break (3) ("
Hello Kitty
") assert_equals: innerText expected "Hello Kitty" but got "Hello Kitty" +Fail Whitespace collapses across element boundaries at soft break (4) ("
Hello Kitty
") assert_equals: innerText expected "Hello Kitty" but got "Hello Kitty" +Pass Element boundaries ignored for soft break handling (4) ("
Hello Kitty
") +Pass Element boundaries ignored for soft break handling (5) ("
Hello Kitty
") +Pass Soft breaks ignored, text-transform applied ("
Hello Kitty
") +Fail
returned as newline, following space collapsed ("
Hello
Kitty
") assert_equals: innerText expected "Hello\nKitty" but got "Hello\n Kitty" +Fail
returned as newline, preceding space collapsed ("
Hello
Kitty
") assert_equals: innerText expected "Hello\nKitty" but got "Hello \nKitty" +Fail
returned as newline, adjacent spaces collapsed across element boundaries ("
Hello
Kitty
") assert_equals: innerText expected "Hello\nKitty" but got "Hello \n Kitty" +Fail ::first-line styles applied ("
abc def") assert_equals: innerText expected "ABC def" but got "abc def" +Fail ::first-letter styles applied ("
abc def") assert_equals: innerText expected "Abc def" but got "abc def" +Pass ::first-letter float ignored ("
abc def") +Pass   preserved ("
 ") +Pass display:none container ("
abc") +Pass No whitespace compression in display:none container ("
abc def") +Pass No removal of leading/trailing whitespace in display:none container ("
abc def ") +Pass display:none child not rendered ("
123abc") +Pass display:none container with non-display-none target child ("
abc") +Pass non-display-none child of svg ("
abc") +Pass display:none child of svg ("