Tests: Replace load-reference-page debug action with internals method

WPT reference tests can add metadata to tests to instruct the test
runner how to interpret the results. Because of this, it is not enough
to have an action that starts loading the (mis)match reference: we need
the test runner to receive the metadata so it can act accordingly.

This sets our test runner up for potentially supporting multiple
(mis)match references, and fuzzy rendering matches - the latter will be
implemented in the following commit.
This commit is contained in:
Jelle Raaijmakers 2025-07-16 10:24:15 +02:00 committed by Tim Ledbetter
commit e4b2253b63
Notes: github-actions[bot] 2025-07-17 12:00:33 +00:00
12 changed files with 87 additions and 44 deletions

View file

@ -1,9 +1,11 @@
/*
* Copyright (c) 2023, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/JsonObject.h>
#include <LibJS/Runtime/Date.h>
#include <LibJS/Runtime/VM.h>
#include <LibUnicode/TimeZone.h>
@ -12,6 +14,7 @@
#include <LibWeb/DOM/Document.h>
#include <LibWeb/DOM/Event.h>
#include <LibWeb/DOM/EventTarget.h>
#include <LibWeb/DOM/NodeList.h>
#include <LibWeb/DOMURL/DOMURL.h>
#include <LibWeb/HTML/HTMLElement.h>
#include <LibWeb/HTML/Window.h>
@ -19,7 +22,6 @@
#include <LibWeb/Page/InputEvent.h>
#include <LibWeb/Page/Page.h>
#include <LibWeb/Painting/PaintableBox.h>
#include <LibWeb/Painting/ViewportPaintable.h>
namespace Web::Internals {
@ -50,6 +52,39 @@ void Internals::set_test_timeout(double milliseconds)
page().client().page_did_set_test_timeout(milliseconds);
}
// https://web-platform-tests.org/writing-tests/reftests.html#components-of-a-reftest
WebIDL::ExceptionOr<void> Internals::load_reference_test_metadata()
{
auto& vm = this->vm();
auto& page = this->page();
auto* document = page.top_level_browsing_context().active_document();
if (!document)
return vm.throw_completion<JS::InternalError>("No active document available"sv);
JsonObject metadata;
// Collect all <link rel="match"> and <link rel="mismatch"> references.
auto collect_references = [&vm, &document](StringView type) -> WebIDL::ExceptionOr<JsonArray> {
JsonArray references;
auto reference_nodes = TRY(document->query_selector_all(MUST(String::formatted("link[rel={}]", type))));
for (size_t i = 0; i < reference_nodes->length(); ++i) {
auto const* reference_node = reference_nodes->item(i);
auto href = as<DOM::Element>(reference_node)->get_attribute_value(HTML::AttributeNames::href);
auto url = document->encoding_parse_url(href);
if (!url.has_value())
return vm.throw_completion<JS::InternalError>(MUST(String::formatted("Failed to construct URL for '{}'", href)));
references.must_append(url->to_string());
}
return references;
};
metadata.set("match_references"sv, TRY(collect_references("match"sv)));
metadata.set("mismatch_references"sv, TRY(collect_references("mismatch"sv)));
page.client().page_did_receive_reference_test_metadata(metadata);
return {};
}
void Internals::gc()
{
vm().heap().collect_garbage();

View file

@ -22,6 +22,7 @@ public:
void signal_test_is_done(String const& text);
void set_test_timeout(double milliseconds);
WebIDL::ExceptionOr<void> load_reference_test_metadata();
WebIDL::ExceptionOr<String> set_time_zone(StringView time_zone);

View file

@ -7,6 +7,7 @@ interface Internals {
undefined signalTestIsDone(DOMString text);
undefined setTestTimeout(double milliseconds);
undefined loadReferenceTestMetadata();
DOMString setTimeZone(DOMString timeZone);

View file

@ -388,6 +388,7 @@ public:
virtual void page_did_finish_test([[maybe_unused]] String const& text) { }
virtual void page_did_set_test_timeout([[maybe_unused]] double milliseconds) { }
virtual void page_did_receive_reference_test_metadata(JsonValue) { }
virtual void page_did_set_browser_zoom([[maybe_unused]] double factor) { }

View file

@ -224,6 +224,7 @@ public:
Function<void(Web::DragEvent const&)> on_finish_handling_drag_event;
Function<void(String const&)> on_test_finish;
Function<void(double milliseconds)> on_set_test_timeout;
Function<void(JsonValue)> on_reference_test_metadata;
Function<void(double factor)> on_set_browser_zoom;
Function<void(size_t current_match_index, Optional<size_t> const& total_match_count)> on_find_in_page;
Function<void(Gfx::Color)> on_theme_color_change;

View file

@ -132,6 +132,14 @@ void WebContentClient::did_set_test_timeout(u64 page_id, double milliseconds)
}
}
void WebContentClient::did_receive_reference_test_metadata(u64 page_id, JsonValue metadata)
{
if (auto view = view_for_page_id(page_id); view.has_value()) {
if (view->on_reference_test_metadata)
view->on_reference_test_metadata(metadata);
}
}
void WebContentClient::did_set_browser_zoom(u64 page_id, double factor)
{
if (auto view = view_for_page_id(page_id); view.has_value()) {

View file

@ -129,6 +129,7 @@ private:
virtual void did_finish_handling_input_event(u64 page_id, Web::EventResult event_result) override;
virtual void did_finish_test(u64 page_id, String text) override;
virtual void did_set_test_timeout(u64 page_id, double milliseconds) override;
virtual void did_receive_reference_test_metadata(u64 page_id, JsonValue) override;
virtual void did_set_browser_zoom(u64 page_id, double factor) override;
virtual void did_find_in_page(u64 page_id, size_t current_match_index, Optional<size_t> total_match_count) override;
virtual void did_change_theme_color(u64 page_id, Gfx::Color color) override;