2024-10-10 15:56:27 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
|
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <Ladybird/Headless/Application.h>
|
2024-11-05 23:44:19 +00:00
|
|
|
#include <Ladybird/Headless/Fixture.h>
|
2024-10-10 15:56:27 +00:00
|
|
|
#include <Ladybird/Headless/HeadlessWebView.h>
|
|
|
|
#include <Ladybird/HelperProcess.h>
|
|
|
|
#include <Ladybird/Utilities.h>
|
|
|
|
#include <LibCore/AnonymousBuffer.h>
|
|
|
|
#include <LibCore/ArgsParser.h>
|
|
|
|
#include <LibCore/System.h>
|
|
|
|
|
|
|
|
namespace Ladybird {
|
|
|
|
|
|
|
|
Application::Application(Badge<WebView::Application>, Main::Arguments&)
|
|
|
|
: resources_folder(s_ladybird_resource_root)
|
|
|
|
, test_concurrency(Core::System::hardware_concurrency())
|
2024-11-05 23:45:43 +00:00
|
|
|
, python_executable_path("python3")
|
|
|
|
|
2024-10-10 15:56:27 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2024-11-05 23:44:19 +00:00
|
|
|
Application::~Application()
|
|
|
|
{
|
|
|
|
for (auto& fixture : Fixture::all())
|
|
|
|
fixture->teardown();
|
|
|
|
}
|
|
|
|
|
2024-10-10 15:56:27 +00:00
|
|
|
void Application::create_platform_arguments(Core::ArgsParser& args_parser)
|
|
|
|
{
|
|
|
|
args_parser.add_option(screenshot_timeout, "Take a screenshot after [n] seconds (default: 1)", "screenshot", 's', "n");
|
|
|
|
args_parser.add_option(dump_layout_tree, "Dump layout tree and exit", "dump-layout-tree", 'd');
|
|
|
|
args_parser.add_option(dump_text, "Dump text and exit", "dump-text", 'T');
|
|
|
|
args_parser.add_option(test_concurrency, "Maximum number of tests to run at once", "test-concurrency", 'j', "jobs");
|
2024-11-05 23:45:43 +00:00
|
|
|
args_parser.add_option(python_executable_path, "Path to python3", "python-executable", 'P', "path");
|
2024-10-10 15:56:27 +00:00
|
|
|
args_parser.add_option(test_root_path, "Run tests in path", "run-tests", 'R', "test-root-path");
|
|
|
|
args_parser.add_option(test_glob, "Only run tests matching the given glob", "filter", 'f', "glob");
|
|
|
|
args_parser.add_option(test_dry_run, "List the tests that would be run, without running them", "dry-run");
|
|
|
|
args_parser.add_option(dump_failed_ref_tests, "Dump screenshots of failing ref tests", "dump-failed-ref-tests", 'D');
|
|
|
|
args_parser.add_option(dump_gc_graph, "Dump GC graph", "dump-gc-graph", 'G');
|
|
|
|
args_parser.add_option(resources_folder, "Path of the base resources folder (defaults to /res)", "resources", 'r', "resources-root-path");
|
|
|
|
args_parser.add_option(is_layout_test_mode, "Enable layout test mode", "layout-test-mode");
|
|
|
|
args_parser.add_option(rebaseline, "Rebaseline any executed layout or text tests", "rebaseline");
|
2024-10-13 13:23:27 +00:00
|
|
|
args_parser.add_option(log_slowest_tests, "Log the tests with the slowest run times", "log-slowest-tests");
|
2024-10-26 16:22:18 +00:00
|
|
|
args_parser.add_option(per_test_timeout_in_seconds, "Per-test timeout (default: 30)", "per-test-timeout", 't', "seconds");
|
2024-10-10 15:56:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Application::create_platform_options(WebView::ChromeOptions& chrome_options, WebView::WebContentOptions& web_content_options)
|
|
|
|
{
|
|
|
|
if (!test_root_path.is_empty()) {
|
|
|
|
// --run-tests implies --layout-test-mode.
|
|
|
|
is_layout_test_mode = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_layout_test_mode) {
|
|
|
|
// Allow window.open() to succeed for tests.
|
|
|
|
chrome_options.allow_popups = WebView::AllowPopups::Yes;
|
2024-10-24 23:23:51 +00:00
|
|
|
|
|
|
|
// Ensure consistent font rendering between operating systems.
|
|
|
|
web_content_options.force_fontconfig = WebView::ForceFontconfig::Yes;
|
2024-10-10 15:56:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dump_gc_graph) {
|
|
|
|
// Force all tests to run in serial if we are interested in the GC graph.
|
|
|
|
test_concurrency = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
web_content_options.is_layout_test_mode = is_layout_test_mode ? WebView::IsLayoutTestMode::Yes : WebView::IsLayoutTestMode::No;
|
|
|
|
}
|
|
|
|
|
|
|
|
ErrorOr<void> Application::launch_services()
|
|
|
|
{
|
|
|
|
auto request_server_paths = TRY(get_paths_for_helper_process("RequestServer"sv));
|
|
|
|
m_request_client = TRY(launch_request_server_process(request_server_paths, resources_folder));
|
|
|
|
|
|
|
|
auto image_decoder_paths = TRY(get_paths_for_helper_process("ImageDecoder"sv));
|
|
|
|
m_image_decoder_client = TRY(launch_image_decoder_process(image_decoder_paths));
|
|
|
|
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2024-11-05 23:44:19 +00:00
|
|
|
ErrorOr<void> Application::launch_test_fixtures()
|
|
|
|
{
|
|
|
|
Fixture::initialize_fixtures();
|
|
|
|
|
|
|
|
// FIXME: Add option to only run specific fixtures from command line by name
|
|
|
|
// And an option to not run any fixtures at all
|
|
|
|
for (auto& fixture : Fixture::all()) {
|
|
|
|
if (auto result = fixture->setup(); result.is_error())
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2024-10-21 22:54:25 +00:00
|
|
|
HeadlessWebView& Application::create_web_view(Core::AnonymousBuffer theme, Gfx::IntSize window_size)
|
2024-10-10 15:56:27 +00:00
|
|
|
{
|
2024-10-21 22:54:25 +00:00
|
|
|
auto web_view = HeadlessWebView::create(move(theme), window_size);
|
2024-10-10 15:56:27 +00:00
|
|
|
m_web_views.append(move(web_view));
|
|
|
|
|
2024-10-21 22:54:25 +00:00
|
|
|
return *m_web_views.last();
|
|
|
|
}
|
|
|
|
|
|
|
|
HeadlessWebView& Application::create_child_web_view(HeadlessWebView const& parent, u64 page_index)
|
|
|
|
{
|
|
|
|
auto web_view = HeadlessWebView::create_child(parent, page_index);
|
|
|
|
m_web_views.append(move(web_view));
|
|
|
|
|
|
|
|
return *m_web_views.last();
|
2024-10-10 15:56:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Application::destroy_web_views()
|
|
|
|
{
|
|
|
|
m_web_views.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|