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 ba69e3e181..ded6b679c3 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 e5fc1a4a37..e46b6e2ca6 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 08274e9a83..3601cfcaa4 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 b986125636..17f982184b 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 a905760f26..30016e2857 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 67b7b5d4cd..fd74a7fb15 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 8d197a7db2..5cba402fc2 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 ef0472d6b5..f815a628e2 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 51c44c98d1..0c4dab17b6 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 01f6a7acb0..1779e7d9ff 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 0a15417edf..e0f2d3f5ed 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 769e548242..49c2e8633a 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 5d8175c8da..0db94b3111 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 dd09a5e507..0f92a6e4b7 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 c5efcb9c49..e49a3e7ac6 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 7019467fc3..3c8b9e4db8 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 f5620c1ef0..7c969a52c6 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 83969660e1..25b20b08ac 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 77bec13927..0dfc51eabe 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 0a8f7bd6f8..4db84c5a45 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); };