LibWebView+WebDriver+UI: Migrate headless browsing to main Ladybird exe

We currently create a separate headless-browser application to serve two
purposes:

1. Allow headless browsing to take a screenshot of a page or print its
   layout tree / internal text.
2. Run the LibWeb test framework.

This patch migrates (1) to the main Ladybird executable. The --headless
flag enables this mode. This matches the behavior of other browsers, and
means we have one less executable to ship at distribution time.

We want to avoid creating too many AppKit / Qt facilities in headless
mode. So this involves some shuffling of application init to ensure we
don't create them until after we've parsed the command line arguments.
Namely, we avoid creating the NSApp in AppKit and QCoreApplication in
Qt. Doing so also requires that we don't create the application event
loop until we've parsed the command line as well, because the loop we
create depends on whether we're creating those UI facilities.
This commit is contained in:
Timothy Flynn 2025-06-06 15:42:12 -04:00 committed by Tim Flynn
commit c011dc766f
Notes: github-actions[bot] 2025-06-10 16:06:04 +00:00
28 changed files with 535 additions and 494 deletions

View file

@ -490,7 +490,7 @@ static void set_ui_callbacks_for_tests(HeadlessWebView& view)
};
}
ErrorOr<void> run_tests(Core::AnonymousBuffer const& theme, Web::DevicePixelSize window_size)
ErrorOr<int> run_tests(Core::AnonymousBuffer const& theme, Web::DevicePixelSize window_size)
{
auto& app = Application::the();
TRY(load_test_config(app.test_root_path));
@ -527,7 +527,7 @@ ErrorOr<void> run_tests(Core::AnonymousBuffer const& theme, Web::DevicePixelSize
for (auto const& [i, test] : enumerate(tests))
outln("{}/{}: {}", i + 1, tests.size(), test.relative_path);
return {};
return 0;
}
if (tests.is_empty()) {
@ -560,7 +560,6 @@ ErrorOr<void> run_tests(Core::AnonymousBuffer const& theme, Web::DevicePixelSize
size_t timeout_count = 0;
size_t crashed_count = 0;
size_t skipped_count = 0;
bool all_tests_ok = true;
// Keep clearing and reusing the same line if stdout is a TTY.
bool log_on_one_line = app.verbosity < Application::VERBOSITY_LEVEL_LOG_TEST_DURATION && TRY(Core::System::isatty(STDOUT_FILENO));
@ -613,15 +612,12 @@ ErrorOr<void> run_tests(Core::AnonymousBuffer const& theme, Web::DevicePixelSize
++pass_count;
break;
case TestResult::Fail:
all_tests_ok = false;
++fail_count;
break;
case TestResult::Timeout:
all_tests_ok = false;
++timeout_count;
break;
case TestResult::Crashed:
all_tests_ok = false;
++crashed_count;
break;
case TestResult::Skipped:
@ -685,10 +681,7 @@ ErrorOr<void> run_tests(Core::AnonymousBuffer const& theme, Web::DevicePixelSize
}
}
if (all_tests_ok)
return {};
return Error::from_string_literal("Failed LibWeb tests");
return fail_count + timeout_count + crashed_count;
}
}