From 6f8be44c0efb387bfff4f00e025f5509e52bdd66 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Thu, 14 Sep 2023 19:17:32 +0200 Subject: [PATCH] LibWeb+WebContent+headless-browser: Support async text tests Previously, we used `on_load_finish` to determine when the text test was completed. This method did not allow testing of async functions because there was no way to indicate that the runner should wait for the async call to end. This change introduces a function in the `internals` object that is intended to be called when the text test execution is completed. The text test runner will now ignore `on_load_finish` which means a test will timeout if this new function is never called. `test(f)` function in `include.js` has been modified to automatically terminate a test once `load` event is fired on `window`. new `asyncTest(f)` function has been introduces. `f` receives function that will terminate a test as a first argument. Every test is expected to call either `test()` or `asyncTest()` to complete. If not, it will remain hanging until a timeout occurs. --- .../css/style-sheet-with-byte-order-mark.txt | 2 +- ...ripted-dom-insertion-during-html-parse.txt | 2 +- .../css/style-sheet-with-byte-order-mark.html | 9 +++++- Tests/LibWeb/Text/input/include.js | 10 ++++++ .../input/link-element-media-attribute.html | 24 +++++++------- .../input/link-element-onload-attribute.html | 14 ++++---- .../link-element-rel-preload-load-event.html | 32 ++++++++++--------- .../Text/input/link-element-search.html | 11 ++++--- ...ipted-dom-insertion-during-html-parse.html | 2 ++ .../Libraries/LibWeb/Internals/Internals.cpp | 7 ++++ .../Libraries/LibWeb/Internals/Internals.h | 2 ++ .../Libraries/LibWeb/Internals/Internals.idl | 1 + Userland/Libraries/LibWeb/Page/Page.h | 2 ++ .../Libraries/LibWebView/ViewImplementation.h | 1 + .../Libraries/LibWebView/WebContentClient.cpp | 6 ++++ .../Libraries/LibWebView/WebContentClient.h | 1 + Userland/Services/WebContent/PageHost.cpp | 5 +++ Userland/Services/WebContent/PageHost.h | 1 + .../Services/WebContent/WebContentClient.ipc | 2 ++ Userland/Utilities/headless-browser.cpp | 4 ++- 20 files changed, 98 insertions(+), 40 deletions(-) diff --git a/Tests/LibWeb/Text/expected/css/style-sheet-with-byte-order-mark.txt b/Tests/LibWeb/Text/expected/css/style-sheet-with-byte-order-mark.txt index ba69e3e1816..ded6b679c38 100644 --- a/Tests/LibWeb/Text/expected/css/style-sheet-with-byte-order-mark.txt +++ b/Tests/LibWeb/Text/expected/css/style-sheet-with-byte-order-mark.txt @@ -1 +1 @@ -PASS \ No newline at end of file +PASS \ No newline at end of file diff --git a/Tests/LibWeb/Text/expected/scripted-dom-insertion-during-html-parse.txt b/Tests/LibWeb/Text/expected/scripted-dom-insertion-during-html-parse.txt index e5fc1a4a37c..e46b6e2ca67 100644 --- a/Tests/LibWeb/Text/expected/scripted-dom-insertion-during-html-parse.txt +++ b/Tests/LibWeb/Text/expected/scripted-dom-insertion-during-html-parse.txt @@ -1 +1 @@ - PASS \ No newline at end of file + PASS \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/css/style-sheet-with-byte-order-mark.html b/Tests/LibWeb/Text/input/css/style-sheet-with-byte-order-mark.html index 08274e9a831..3601cfcaa4f 100644 --- a/Tests/LibWeb/Text/input/css/style-sheet-with-byte-order-mark.html +++ b/Tests/LibWeb/Text/input/css/style-sheet-with-byte-order-mark.html @@ -1 +1,8 @@ -
PASS + + + +
PASS
+ + diff --git a/Tests/LibWeb/Text/input/include.js b/Tests/LibWeb/Text/input/include.js index b9861256363..17f982184b3 100644 --- a/Tests/LibWeb/Text/input/include.js +++ b/Tests/LibWeb/Text/input/include.js @@ -12,4 +12,14 @@ document.addEventListener("DOMContentLoaded", function () { function test(f) { document.addEventListener("DOMContentLoaded", f); + window.addEventListener("load", () => { + internals.signalTextTestIsDone(); + }); +} + +function asyncTest(f) { + const done = () => internals.signalTextTestIsDone(); + document.addEventListener("DOMContentLoaded", () => { + f(done); + }); } diff --git a/Tests/LibWeb/Text/input/link-element-media-attribute.html b/Tests/LibWeb/Text/input/link-element-media-attribute.html index a905760f265..30016e28570 100644 --- a/Tests/LibWeb/Text/input/link-element-media-attribute.html +++ b/Tests/LibWeb/Text/input/link-element-media-attribute.html @@ -1,17 +1,19 @@ diff --git a/Tests/LibWeb/Text/input/link-element-onload-attribute.html b/Tests/LibWeb/Text/input/link-element-onload-attribute.html index 67b7b5d4cd8..fd74a7fb155 100644 --- a/Tests/LibWeb/Text/input/link-element-onload-attribute.html +++ b/Tests/LibWeb/Text/input/link-element-onload-attribute.html @@ -1,9 +1,11 @@ diff --git a/Tests/LibWeb/Text/input/link-element-rel-preload-load-event.html b/Tests/LibWeb/Text/input/link-element-rel-preload-load-event.html index 8d197a7db2f..5cba402fc26 100644 --- a/Tests/LibWeb/Text/input/link-element-rel-preload-load-event.html +++ b/Tests/LibWeb/Text/input/link-element-rel-preload-load-event.html @@ -1,20 +1,22 @@ diff --git a/Tests/LibWeb/Text/input/link-element-search.html b/Tests/LibWeb/Text/input/link-element-search.html index ef0472d6b5f..f815a628e2b 100644 --- a/Tests/LibWeb/Text/input/link-element-search.html +++ b/Tests/LibWeb/Text/input/link-element-search.html @@ -1,7 +1,10 @@ - diff --git a/Tests/LibWeb/Text/input/scripted-dom-insertion-during-html-parse.html b/Tests/LibWeb/Text/input/scripted-dom-insertion-during-html-parse.html index 51c44c98d1c..0c4dab17b67 100644 --- a/Tests/LibWeb/Text/input/scripted-dom-insertion-during-html-parse.html +++ b/Tests/LibWeb/Text/input/scripted-dom-insertion-during-html-parse.html @@ -1,4 +1,6 @@ + diff --git a/Userland/Libraries/LibWeb/Internals/Internals.cpp b/Userland/Libraries/LibWeb/Internals/Internals.cpp index 01f6a7acb09..1779e7d9ff6 100644 --- a/Userland/Libraries/LibWeb/Internals/Internals.cpp +++ b/Userland/Libraries/LibWeb/Internals/Internals.cpp @@ -28,6 +28,13 @@ void Internals::initialize(JS::Realm& realm) Object::set_prototype(&Bindings::ensure_web_prototype(realm, "Internals")); } +void Internals::signal_text_test_is_done() +{ + if (auto* page = global_object().browsing_context()->page()) { + page->client().page_did_finish_text_test(); + } +} + void Internals::gc() { vm().heap().collect_garbage(); diff --git a/Userland/Libraries/LibWeb/Internals/Internals.h b/Userland/Libraries/LibWeb/Internals/Internals.h index 0a15417edf3..e0f2d3f5ed2 100644 --- a/Userland/Libraries/LibWeb/Internals/Internals.h +++ b/Userland/Libraries/LibWeb/Internals/Internals.h @@ -16,6 +16,8 @@ class Internals final : public Bindings::PlatformObject { public: virtual ~Internals() override; + void signal_text_test_is_done(); + void gc(); JS::Object* hit_test(double x, double y); diff --git a/Userland/Libraries/LibWeb/Internals/Internals.idl b/Userland/Libraries/LibWeb/Internals/Internals.idl index 769e5482425..49c2e8633ae 100644 --- a/Userland/Libraries/LibWeb/Internals/Internals.idl +++ b/Userland/Libraries/LibWeb/Internals/Internals.idl @@ -1,5 +1,6 @@ [Exposed=Nobody] interface Internals { + undefined signalTextTestIsDone(); undefined gc(); object hitTest(double x, double y); diff --git a/Userland/Libraries/LibWeb/Page/Page.h b/Userland/Libraries/LibWeb/Page/Page.h index 5d8175c8da6..0db94b31118 100644 --- a/Userland/Libraries/LibWeb/Page/Page.h +++ b/Userland/Libraries/LibWeb/Page/Page.h @@ -241,6 +241,8 @@ public: // https://html.spec.whatwg.org/multipage/input.html#show-the-picker,-if-applicable virtual void page_did_request_file_picker(WeakPtr, [[maybe_unused]] bool multiple) {}; + virtual void page_did_finish_text_test() {}; + protected: virtual ~PageClient() = default; }; diff --git a/Userland/Libraries/LibWebView/ViewImplementation.h b/Userland/Libraries/LibWebView/ViewImplementation.h index dd09a5e507f..0f92a6e4b76 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.h +++ b/Userland/Libraries/LibWebView/ViewImplementation.h @@ -151,6 +151,7 @@ public: Function on_minimize_window; Function on_fullscreen_window; Function on_finish_handling_input_event; + Function on_text_test_finish; virtual Gfx::IntRect viewport_rect() const = 0; virtual Gfx::IntPoint to_content_position(Gfx::IntPoint widget_position) const = 0; diff --git a/Userland/Libraries/LibWebView/WebContentClient.cpp b/Userland/Libraries/LibWebView/WebContentClient.cpp index c5efcb9c492..e49a3e7ac68 100644 --- a/Userland/Libraries/LibWebView/WebContentClient.cpp +++ b/Userland/Libraries/LibWebView/WebContentClient.cpp @@ -44,6 +44,12 @@ void WebContentClient::did_finish_loading(AK::URL const& url) m_view.on_load_finish(url); } +void WebContentClient::did_finish_text_test() +{ + if (m_view.on_text_test_finish) + m_view.on_text_test_finish(); +} + void WebContentClient::did_request_navigate_back() { if (m_view.on_navigate_back) diff --git a/Userland/Libraries/LibWebView/WebContentClient.h b/Userland/Libraries/LibWebView/WebContentClient.h index 7019467fc3f..3c8b9e4db81 100644 --- a/Userland/Libraries/LibWebView/WebContentClient.h +++ b/Userland/Libraries/LibWebView/WebContentClient.h @@ -83,6 +83,7 @@ private: virtual Messages::WebContentClient::DidRequestFullscreenWindowResponse did_request_fullscreen_window() override; virtual void did_request_file(DeprecatedString const& path, i32) override; virtual void did_finish_handling_input_event(bool event_was_accepted) override; + virtual void did_finish_text_test() override; ViewImplementation& m_view; }; diff --git a/Userland/Services/WebContent/PageHost.cpp b/Userland/Services/WebContent/PageHost.cpp index f5620c1ef0f..7c969a52c67 100644 --- a/Userland/Services/WebContent/PageHost.cpp +++ b/Userland/Services/WebContent/PageHost.cpp @@ -291,6 +291,11 @@ void PageHost::page_did_finish_loading(const URL& url) m_client.async_did_finish_loading(url); } +void PageHost::page_did_finish_text_test() +{ + m_client.async_did_finish_text_test(); +} + void PageHost::page_did_request_context_menu(Web::CSSPixelPoint content_position) { m_client.async_did_request_context_menu(page().css_to_device_point(content_position).to_type()); diff --git a/Userland/Services/WebContent/PageHost.h b/Userland/Services/WebContent/PageHost.h index 83969660e12..25b20b08ac7 100644 --- a/Userland/Services/WebContent/PageHost.h +++ b/Userland/Services/WebContent/PageHost.h @@ -112,6 +112,7 @@ private: virtual void page_did_request_activate_tab() override; virtual void page_did_close_browsing_context(Web::HTML::BrowsingContext const&) override; virtual void request_file(Web::FileRequest) override; + virtual void page_did_finish_text_test() override; explicit PageHost(ConnectionFromClient&); diff --git a/Userland/Services/WebContent/WebContentClient.ipc b/Userland/Services/WebContent/WebContentClient.ipc index 77bec13927c..0dfc51eabe1 100644 --- a/Userland/Services/WebContent/WebContentClient.ipc +++ b/Userland/Services/WebContent/WebContentClient.ipc @@ -64,4 +64,6 @@ endpoint WebContentClient did_output_js_console_message(i32 message_index) =| did_get_js_console_messages(i32 start_index, Vector message_types, Vector messages) =| + did_finish_text_test() =| + } diff --git a/Userland/Utilities/headless-browser.cpp b/Userland/Utilities/headless-browser.cpp index 0a8f7bd6f85..4db84c5a45f 100644 --- a/Userland/Utilities/headless-browser.cpp +++ b/Userland/Utilities/headless-browser.cpp @@ -196,8 +196,10 @@ static ErrorOr run_dump_test(HeadlessWebContentView& view, StringVie result = builder.to_string().release_value_but_fixme_should_propagate_errors(); loop.quit(0); }; + view.on_text_test_finish = {}; } else if (mode == TestMode::Text) { - view.on_load_finish = [&](auto const&) { + view.on_load_finish = {}; + view.on_text_test_finish = [&]() { result = view.dump_text().release_value_but_fixme_should_propagate_errors(); loop.quit(0); };