Tests/LibWeb: Support WPT variant meta tags in test-web

Add support for WPT test variants, which allow a single test file to be
run multiple times with different URL query parameters. Tests declare
variants using `<meta name="variant" content="?param=value">` tags.

When test-web encounters a test with variants, it expands that test into
multiple runs, each with its own expectation file using the naming
convention `testname@variant.txt` (e.g., `test@run_type=uri.txt`).

Implementation details:
- WebContent observes variant meta tags and communicates them to the
  test runner via a new `did_receive_test_variant_metadata` IPC call
- test-web dynamically expands tests with variants during execution,
  waking idle views after each test completion to pick up new work
- Use index-based test tracking to avoid dangling references when the
  test vector grows during variant expansion
- Introduce TestRunContext to group test run state, and store a static
  pointer to it for signal handler access

This enables proper testing of WPT tests that use variants, such as the
html5lib parsing tests (which test uri, write, and write_single modes)
and the editing/bold tests (which split across multiple ranges).
This commit is contained in:
Jelle Raaijmakers
2026-01-13 17:33:48 +01:00
committed by Tim Ledbetter
parent 8b77b41661
commit bf77aeb3dc
Notes: github-actions[bot] 2026-01-16 16:45:23 +00:00
194 changed files with 3929 additions and 3358 deletions

View File

@@ -112,6 +112,29 @@ WebIDL::ExceptionOr<void> Internals::load_reference_test_metadata()
return {};
}
// https://web-platform-tests.org/writing-tests/testharness.html#variants
WebIDL::ExceptionOr<void> Internals::load_test_variants()
{
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);
auto variant_nodes = TRY(document->query_selector_all("meta[name=variant]"sv));
JsonArray variants;
for (size_t i = 0; i < variant_nodes->length(); ++i) {
auto const* variant_node = variant_nodes->item(i);
auto content = as<DOM::Element>(variant_node)->get_attribute_value(HTML::AttributeNames::content);
variants.must_append(content);
}
// Always fire callback so test runner knows variant check is complete.
page.client().page_did_receive_test_variant_metadata(variants);
return {};
}
void Internals::gc()
{
vm().heap().collect_garbage();