Application.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. /*
  2. * Copyright (c) 2024, Tim Flynn <trflynn89@ladybird.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibCore/AnonymousBuffer.h>
  7. #include <LibCore/ArgsParser.h>
  8. #include <LibCore/System.h>
  9. #include <LibWebView/HelperProcess.h>
  10. #include <LibWebView/Utilities.h>
  11. #include <UI/Headless/Application.h>
  12. #include <UI/Headless/Fixture.h>
  13. #include <UI/Headless/HeadlessWebView.h>
  14. namespace Ladybird {
  15. Application::Application(Badge<WebView::Application>, Main::Arguments&)
  16. : resources_folder(WebView::s_ladybird_resource_root)
  17. , test_concurrency(Core::System::hardware_concurrency())
  18. , python_executable_path("python3")
  19. {
  20. }
  21. Application::~Application()
  22. {
  23. for (auto& fixture : Fixture::all())
  24. fixture->teardown();
  25. }
  26. void Application::create_platform_arguments(Core::ArgsParser& args_parser)
  27. {
  28. args_parser.add_option(screenshot_timeout, "Take a screenshot after [n] seconds (default: 1)", "screenshot", 's', "n");
  29. args_parser.add_option(dump_layout_tree, "Dump layout tree and exit", "dump-layout-tree", 'd');
  30. args_parser.add_option(dump_text, "Dump text and exit", "dump-text", 'T');
  31. args_parser.add_option(test_concurrency, "Maximum number of tests to run at once", "test-concurrency", 'j', "jobs");
  32. args_parser.add_option(python_executable_path, "Path to python3", "python-executable", 'P', "path");
  33. args_parser.add_option(test_root_path, "Run tests in path", "run-tests", 'R', "test-root-path");
  34. args_parser.add_option(test_glob, "Only run tests matching the given glob", "filter", 'f', "glob");
  35. args_parser.add_option(test_dry_run, "List the tests that would be run, without running them", "dry-run");
  36. args_parser.add_option(dump_failed_ref_tests, "Dump screenshots of failing ref tests", "dump-failed-ref-tests", 'D');
  37. args_parser.add_option(dump_gc_graph, "Dump GC graph", "dump-gc-graph", 'G');
  38. args_parser.add_option(resources_folder, "Path of the base resources folder (defaults to /res)", "resources", 'r', "resources-root-path");
  39. args_parser.add_option(is_layout_test_mode, "Enable layout test mode", "layout-test-mode");
  40. args_parser.add_option(rebaseline, "Rebaseline any executed layout or text tests", "rebaseline");
  41. args_parser.add_option(per_test_timeout_in_seconds, "Per-test timeout (default: 30)", "per-test-timeout", 't', "seconds");
  42. args_parser.add_option(verbose, "Log extra information about test results", "verbose", 'v');
  43. args_parser.add_option(width, "Set viewport width in pixels (default: 800)", "width", 'W', "pixels");
  44. args_parser.add_option(height, "Set viewport height in pixels (default: 600)", "height", 'H', "pixels");
  45. }
  46. void Application::create_platform_options(WebView::ChromeOptions& chrome_options, WebView::WebContentOptions& web_content_options)
  47. {
  48. if (!test_root_path.is_empty()) {
  49. // --run-tests implies --layout-test-mode.
  50. is_layout_test_mode = true;
  51. }
  52. if (is_layout_test_mode) {
  53. // Allow window.open() to succeed for tests.
  54. chrome_options.allow_popups = WebView::AllowPopups::Yes;
  55. // Ensure consistent font rendering between operating systems.
  56. web_content_options.force_fontconfig = WebView::ForceFontconfig::Yes;
  57. }
  58. if (dump_gc_graph) {
  59. // Force all tests to run in serial if we are interested in the GC graph.
  60. test_concurrency = 1;
  61. }
  62. web_content_options.is_layout_test_mode = is_layout_test_mode ? WebView::IsLayoutTestMode::Yes : WebView::IsLayoutTestMode::No;
  63. }
  64. ErrorOr<void> Application::launch_test_fixtures()
  65. {
  66. Fixture::initialize_fixtures();
  67. // FIXME: Add option to only run specific fixtures from command line by name
  68. // And an option to not run any fixtures at all
  69. for (auto& fixture : Fixture::all()) {
  70. if (auto result = fixture->setup(); result.is_error())
  71. return result;
  72. }
  73. return {};
  74. }
  75. HeadlessWebView& Application::create_web_view(Core::AnonymousBuffer theme, Web::DevicePixelSize window_size)
  76. {
  77. auto web_view = HeadlessWebView::create(move(theme), window_size);
  78. m_web_views.append(move(web_view));
  79. return *m_web_views.last();
  80. }
  81. HeadlessWebView& Application::create_child_web_view(HeadlessWebView const& parent, u64 page_index)
  82. {
  83. auto web_view = HeadlessWebView::create_child(parent, page_index);
  84. m_web_views.append(move(web_view));
  85. return *m_web_views.last();
  86. }
  87. void Application::destroy_web_views()
  88. {
  89. m_web_views.clear();
  90. }
  91. }