diff options
author | Timothy Flynn <trflynn89@pm.me> | 2022-11-14 11:55:10 -0500 |
---|---|---|
committer | Tim Flynn <trflynn89@pm.me> | 2022-11-14 13:43:24 -0500 |
commit | 826d5f8f9ab0e28606a0d07847056bd6562ebc49 (patch) | |
tree | ca6fc6b089abac4d56747b24e1ba5be4d84f3b0d /Userland/Services | |
parent | be50806a18f6691feb4cca4d70e10f4c49c4d184 (diff) | |
download | serenity-826d5f8f9ab0e28606a0d07847056bd6562ebc49.zip |
WebContent+WebDriver: Move Window commands to WebContent
This moves Get Window Handle, Close Window, and Get Window Handles over
to WebContent so they may be implemented closer to the spec and be used
by Ladybird.
Diffstat (limited to 'Userland/Services')
-rw-r--r-- | Userland/Services/WebContent/WebDriverClient.ipc | 3 | ||||
-rw-r--r-- | Userland/Services/WebContent/WebDriverConnection.cpp | 49 | ||||
-rw-r--r-- | Userland/Services/WebContent/WebDriverConnection.h | 12 | ||||
-rw-r--r-- | Userland/Services/WebDriver/Client.cpp | 11 | ||||
-rw-r--r-- | Userland/Services/WebDriver/Session.cpp | 79 | ||||
-rw-r--r-- | Userland/Services/WebDriver/Session.h | 20 |
6 files changed, 76 insertions, 98 deletions
diff --git a/Userland/Services/WebContent/WebDriverClient.ipc b/Userland/Services/WebContent/WebDriverClient.ipc index d330dc902d..c0922a3095 100644 --- a/Userland/Services/WebContent/WebDriverClient.ipc +++ b/Userland/Services/WebContent/WebDriverClient.ipc @@ -11,6 +11,9 @@ endpoint WebDriverClient { forward() => (Web::WebDriver::Response response) refresh() => (Web::WebDriver::Response response) get_title() => (Web::WebDriver::Response response) + get_window_handle() => (Web::WebDriver::Response response) + close_window() => (Web::WebDriver::Response response) + get_window_handles() => (Web::WebDriver::Response response) get_window_rect() => (Web::WebDriver::Response response) set_window_rect(JsonValue payload) => (Web::WebDriver::Response response) maximize_window() => (Web::WebDriver::Response response) diff --git a/Userland/Services/WebContent/WebDriverConnection.cpp b/Userland/Services/WebContent/WebDriverConnection.cpp index 0bfa776900..932d7434ca 100644 --- a/Userland/Services/WebContent/WebDriverConnection.cpp +++ b/Userland/Services/WebContent/WebDriverConnection.cpp @@ -216,7 +216,9 @@ WebDriverConnection::WebDriverConnection(NonnullOwnPtr<Core::Stream::LocalSocket : IPC::ConnectionToServer<WebDriverClientEndpoint, WebDriverServerEndpoint>(*this, move(socket)) , m_web_content_client(web_content_client) , m_page_host(page_host) + , m_current_window_handle("main"sv) { + m_windows.set(m_current_window_handle, { m_current_window_handle, true }); } // https://w3c.github.io/webdriver/#dfn-close-the-session @@ -226,7 +228,8 @@ void WebDriverConnection::close_session() set_is_webdriver_active(false); // 2. An endpoint node must close any top-level browsing contexts associated with the session, without prompting to unload. - m_page_host.page().top_level_browsing_context().close(); + if (!m_page_host.page().top_level_browsing_context().has_been_discarded()) + m_page_host.page().top_level_browsing_context().close(); } void WebDriverConnection::set_is_webdriver_active(bool is_webdriver_active) @@ -377,6 +380,50 @@ Messages::WebDriverClient::GetTitleResponse WebDriverConnection::get_title() return title; } +// 11.1 Get Window Handle, https://w3c.github.io/webdriver/#get-window-handle +Messages::WebDriverClient::GetWindowHandleResponse WebDriverConnection::get_window_handle() +{ + // 1. If the current top-level browsing context is no longer open, return error with error code no such window. + TRY(ensure_open_top_level_browsing_context()); + + // 2. Return success with data being the window handle associated with the current top-level browsing context. + return m_current_window_handle; +} + +// 11.2 Close Window, https://w3c.github.io/webdriver/#dfn-close-window +Messages::WebDriverClient::CloseWindowResponse WebDriverConnection::close_window() +{ + // 1. If the current top-level browsing context is no longer open, return error with error code no such window. + TRY(ensure_open_top_level_browsing_context()); + + // FIXME: 2. Handle any user prompts and return its value if it is an error. + + // 3. Close the current top-level browsing context. + m_page_host.page().top_level_browsing_context().close(); + m_windows.remove(m_current_window_handle); + + // 4. If there are no more open top-level browsing contexts, then close the session. + if (m_windows.is_empty()) + close_session(); + + // 5. Return the result of running the remote end steps for the Get Window Handles command. + return get_window_handles().take_response(); +} + +// 11.4 Get Window Handles, https://w3c.github.io/webdriver/#dfn-get-window-handles +Messages::WebDriverClient::GetWindowHandlesResponse WebDriverConnection::get_window_handles() +{ + // 1. Let handles be a JSON List. + JsonArray handles {}; + + // 2. For each top-level browsing context in the remote end, push the associated window handle onto handles. + for (auto const& window_handle : m_windows.keys()) + handles.append(window_handle); + + // 3. Return success with data handles. + return handles; +} + // 11.8.1 Get Window Rect, https://w3c.github.io/webdriver/#dfn-get-window-rect Messages::WebDriverClient::GetWindowRectResponse WebDriverConnection::get_window_rect() { diff --git a/Userland/Services/WebContent/WebDriverConnection.h b/Userland/Services/WebContent/WebDriverConnection.h index dbea45c7bc..64e4e2bd87 100644 --- a/Userland/Services/WebContent/WebDriverConnection.h +++ b/Userland/Services/WebContent/WebDriverConnection.h @@ -8,6 +8,8 @@ #pragma once +#include <AK/HashMap.h> +#include <AK/String.h> #include <LibIPC/ConnectionToServer.h> #include <LibJS/Forward.h> #include <LibJS/Heap/MarkedVector.h> @@ -44,6 +46,9 @@ private: virtual Messages::WebDriverClient::ForwardResponse forward() override; virtual Messages::WebDriverClient::RefreshResponse refresh() override; virtual Messages::WebDriverClient::GetTitleResponse get_title() override; + virtual Messages::WebDriverClient::GetWindowHandleResponse get_window_handle() override; + virtual Messages::WebDriverClient::CloseWindowResponse close_window() override; + virtual Messages::WebDriverClient::GetWindowHandlesResponse get_window_handles() override; virtual Messages::WebDriverClient::GetWindowRectResponse get_window_rect() override; virtual Messages::WebDriverClient::SetWindowRectResponse set_window_rect(JsonValue const& payload) override; virtual Messages::WebDriverClient::MaximizeWindowResponse maximize_window() override; @@ -90,6 +95,13 @@ private: // https://w3c.github.io/webdriver/#dfn-session-script-timeout Web::WebDriver::TimeoutsConfiguration m_timeouts_configuration; + + struct Window { + String handle; + bool is_open { false }; + }; + HashMap<String, Window> m_windows; + String m_current_window_handle; }; } diff --git a/Userland/Services/WebDriver/Client.cpp b/Userland/Services/WebDriver/Client.cpp index 987639a200..3d4810eb0c 100644 --- a/Userland/Services/WebDriver/Client.cpp +++ b/Userland/Services/WebDriver/Client.cpp @@ -252,7 +252,7 @@ Web::WebDriver::Response Client::get_window_handle(Web::WebDriver::Parameters pa { dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/window"); auto* session = TRY(find_session_with_id(parameters[0])); - return session->get_window_handle(); + return session->web_content_connection().get_window_handle(); } // 11.2 Close Window, https://w3c.github.io/webdriver/#dfn-close-window @@ -261,7 +261,12 @@ Web::WebDriver::Response Client::close_window(Web::WebDriver::Parameters paramet { dbgln_if(WEBDRIVER_DEBUG, "Handling DELETE /session/<session_id>/window"); auto* session = TRY(find_session_with_id(parameters[0])); - return session->close_window(); + + auto open_windows = TRY(session->web_content_connection().close_window()); + if (open_windows.is_array() && open_windows.as_array().is_empty()) + TRY(session->stop()); + + return open_windows; } // 11.4 Get Window Handles, https://w3c.github.io/webdriver/#dfn-get-window-handles @@ -270,7 +275,7 @@ Web::WebDriver::Response Client::get_window_handles(Web::WebDriver::Parameters p { dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/window/handles"); auto* session = TRY(find_session_with_id(parameters[0])); - return session->get_window_handles(); + return session->web_content_connection().get_window_handles(); } // 11.8.1 Get Window Rect, https://w3c.github.io/webdriver/#dfn-get-window-rect diff --git a/Userland/Services/WebDriver/Session.cpp b/Userland/Services/WebDriver/Session.cpp index 323ba5fde5..7510425cb6 100644 --- a/Userland/Services/WebDriver/Session.cpp +++ b/Userland/Services/WebDriver/Session.cpp @@ -10,16 +10,9 @@ #include "Session.h" #include "Client.h" -#include <AK/JsonObject.h> -#include <AK/JsonParser.h> -#include <AK/NumericLimits.h> -#include <AK/Time.h> #include <LibCore/LocalServer.h> #include <LibCore/Stream.h> #include <LibCore/System.h> -#include <LibGfx/Point.h> -#include <LibGfx/Rect.h> -#include <LibGfx/Size.h> #include <unistd.h> namespace WebDriver { @@ -32,26 +25,8 @@ Session::Session(unsigned session_id, NonnullRefPtr<Client> client) Session::~Session() { - if (m_started) { - auto error = stop(); - if (error.is_error()) { - warnln("Failed to stop session {}: {}", m_id, error.error()); - } - } -} - -ErrorOr<Session::Window*, Web::WebDriver::Error> Session::current_window() -{ - auto window = m_windows.get(m_current_window_handle); - if (!window.has_value()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchWindow, "Window not found"); - return window.release_value(); -} - -ErrorOr<void, Web::WebDriver::Error> Session::check_for_open_top_level_browsing_context_or_return_error() -{ - (void)TRY(current_window()); - return {}; + if (auto error = stop(); error.is_error()) + warnln("Failed to stop session {}: {}", m_id, error.error()); } ErrorOr<NonnullRefPtr<Core::LocalServer>> Session::create_server(String const& socket_path, NonnullRefPtr<ServerPromise> promise) @@ -102,19 +77,18 @@ ErrorOr<void> Session::start() TRY(promise->await()); m_started = true; - m_windows.set("main", make<Session::Window>("main", true)); - m_current_window_handle = "main"; - return {}; } // https://w3c.github.io/webdriver/#dfn-close-the-session Web::WebDriver::Response Session::stop() { + if (!m_started) + return JsonValue {}; + // 1. Perform the following substeps based on the remote endβs type: // NOTE: We perform the "Remote end is an endpoint node" steps in the WebContent process. m_web_content_connection->close_session(); - m_web_content_connection = nullptr; // 2. Remove the current session from active sessions. // NOTE: Handled by WebDriver::Client. @@ -131,47 +105,4 @@ Web::WebDriver::Response Session::stop() return JsonValue {}; } -// 11.1 Get Window Handle, https://w3c.github.io/webdriver/#get-window-handle -Web::WebDriver::Response Session::get_window_handle() -{ - // 1. If the current top-level browsing context is no longer open, return error with error code no such window. - TRY(check_for_open_top_level_browsing_context_or_return_error()); - - // 2. Return success with data being the window handle associated with the current top-level browsing context. - return JsonValue { m_current_window_handle }; -} - -// 11.2 Close Window, https://w3c.github.io/webdriver/#dfn-close-window -Web::WebDriver::Response Session::close_window() -{ - // 1. If the current top-level browsing context is no longer open, return error with error code no such window. - TRY(check_for_open_top_level_browsing_context_or_return_error()); - - // FIXME: 2. Handle any user prompts and return its value if it is an error. - - // 3. Close the current top-level browsing context. - m_windows.remove(m_current_window_handle); - - // 4. If there are no more open top-level browsing contexts, then close the session. - if (m_windows.is_empty()) - TRY(stop()); - - // 5. Return the result of running the remote end steps for the Get Window Handles command. - return get_window_handles(); -} - -// 11.4 Get Window Handles, https://w3c.github.io/webdriver/#dfn-get-window-handles -Web::WebDriver::Response Session::get_window_handles() const -{ - // 1. Let handles be a JSON List. - auto handles = JsonArray {}; - - // 2. For each top-level browsing context in the remote end, push the associated window handle onto handles. - for (auto const& window_handle : m_windows.keys()) - handles.append(window_handle); - - // 3. Return success with data handles. - return JsonValue { handles }; -} - } diff --git a/Userland/Services/WebDriver/Session.h b/Userland/Services/WebDriver/Session.h index 4385765e47..f039edbdf6 100644 --- a/Userland/Services/WebDriver/Session.h +++ b/Userland/Services/WebDriver/Session.h @@ -9,7 +9,6 @@ #pragma once #include <AK/Error.h> -#include <AK/JsonValue.h> #include <AK/RefPtr.h> #include <LibCore/Promise.h> #include <LibWeb/WebDriver/Error.h> @@ -26,19 +25,6 @@ public: unsigned session_id() const { return m_id; } - struct Window { - String handle; - bool is_open; - }; - - struct LocalElement { - i32 id; - }; - - ErrorOr<Window*, Web::WebDriver::Error> current_window(); - ErrorOr<void, Web::WebDriver::Error> check_for_open_top_level_browsing_context_or_return_error(); - String const& current_window_handle() { return m_current_window_handle; } - WebContentConnection& web_content_connection() { VERIFY(m_web_content_connection); @@ -47,10 +33,6 @@ public: ErrorOr<void> start(); Web::WebDriver::Response stop(); - Web::WebDriver::Response get_window_handle(); - Web::WebDriver::Response close_window(); - Web::WebDriver::Response get_window_handles() const; - Web::WebDriver::Response take_element_screenshot(StringView element_id); private: using ServerPromise = Core::Promise<ErrorOr<void>>; @@ -59,8 +41,6 @@ private: NonnullRefPtr<Client> m_client; bool m_started { false }; unsigned m_id { 0 }; - HashMap<String, NonnullOwnPtr<Window>> m_windows; - String m_current_window_handle; RefPtr<WebContentConnection> m_web_content_connection; Optional<pid_t> m_browser_pid; }; |