diff --git a/Userland/Services/WebContent/WebDriverClient.ipc b/Userland/Services/WebContent/WebDriverClient.ipc index e05233f3bb..e2d0ae7a8c 100644 --- a/Userland/Services/WebContent/WebDriverClient.ipc +++ b/Userland/Services/WebContent/WebDriverClient.ipc @@ -1,6 +1,7 @@ #include endpoint WebDriverClient { + close_session() => () set_is_webdriver_active(bool active) =| navigate_to(JsonValue payload) => (Web::WebDriver::Response response) get_current_url() => (Web::WebDriver::Response response) diff --git a/Userland/Services/WebContent/WebDriverConnection.cpp b/Userland/Services/WebContent/WebDriverConnection.cpp index 7b21161888..53c7c3ae03 100644 --- a/Userland/Services/WebContent/WebDriverConnection.cpp +++ b/Userland/Services/WebContent/WebDriverConnection.cpp @@ -50,6 +50,16 @@ WebDriverConnection::WebDriverConnection(NonnullOwnPtr socket, PageHost& page_host); virtual void die() override { } + + virtual void close_session() override; virtual void set_is_webdriver_active(bool) override; virtual Messages::WebDriverClient::NavigateToResponse navigate_to(JsonValue const& payload) override; virtual Messages::WebDriverClient::GetCurrentUrlResponse get_current_url() override; diff --git a/Userland/Services/WebDriver/Client.cpp b/Userland/Services/WebDriver/Client.cpp index 0f826b0e74..51d318527a 100644 --- a/Userland/Services/WebDriver/Client.cpp +++ b/Userland/Services/WebDriver/Client.cpp @@ -331,6 +331,21 @@ ErrorOr Client::find_session_with_id(StringView return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSessionId, "Invalid session id"); } +ErrorOr, Web::WebDriver::Error> Client::take_session_with_id(StringView session_id) +{ + auto session_id_or_error = session_id.to_uint<>(); + if (!session_id_or_error.has_value()) + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSessionId, "Invalid session id"); + + for (size_t i = 0; i < Client::s_sessions.size(); ++i) { + if (Client::s_sessions[i].session_id() == session_id_or_error.value()) { + return Client::s_sessions.take(i); + } + } + + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSessionId, "Invalid session id"); +} + void Client::close_session(unsigned session_id) { bool found = Client::s_sessions.remove_first_matching([&](auto const& it) { @@ -426,11 +441,8 @@ Web::WebDriver::Response Client::handle_delete_session(Vector const& dbgln_if(WEBDRIVER_DEBUG, "Handling DELETE /session/"); // 1. If the current session is an active session, try to close the session. - auto* session = TRY(find_session_with_id(parameters[0])); - - auto stop_result = session->stop(); - if (stop_result.is_error()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::UnsupportedOperation, stop_result.error().string_literal()); + auto session = TRY(take_session_with_id(parameters[0])); + TRY(session->stop()); // 2. Return success with data null. return make_json_value(JsonValue()); diff --git a/Userland/Services/WebDriver/Client.h b/Userland/Services/WebDriver/Client.h index 6caaad4a6d..f9a02fbc50 100644 --- a/Userland/Services/WebDriver/Client.h +++ b/Userland/Services/WebDriver/Client.h @@ -91,6 +91,7 @@ private: Web::WebDriver::Response handle_take_element_screenshot(Vector const&, JsonValue const& payload); ErrorOr find_session_with_id(StringView session_id); + ErrorOr, Web::WebDriver::Error> take_session_with_id(StringView session_id); JsonValue make_json_value(JsonValue const&); template diff --git a/Userland/Services/WebDriver/Session.cpp b/Userland/Services/WebDriver/Session.cpp index 65c1363138..98ab4d3783 100644 --- a/Userland/Services/WebDriver/Session.cpp +++ b/Userland/Services/WebDriver/Session.cpp @@ -136,10 +136,23 @@ ErrorOr Session::start() return {}; } -ErrorOr Session::stop() +// https://w3c.github.io/webdriver/#dfn-close-the-session +Web::WebDriver::Response Session::stop() { + // 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. + + // 3. Perform any implementation-specific cleanup steps. m_browser_connection->async_quit(); - return {}; + m_started = false; + + // 4. If an error has occurred in any of the steps above, return the error, otherwise return success with data null. + return JsonValue {}; } // 9.1 Get Timeouts, https://w3c.github.io/webdriver/#dfn-get-timeouts diff --git a/Userland/Services/WebDriver/Session.h b/Userland/Services/WebDriver/Session.h index 329249ab16..414accbcf3 100644 --- a/Userland/Services/WebDriver/Session.h +++ b/Userland/Services/WebDriver/Session.h @@ -48,7 +48,7 @@ public: } ErrorOr start(); - ErrorOr stop(); + Web::WebDriver::Response stop(); JsonObject get_timeouts(); Web::WebDriver::Response set_timeouts(JsonValue const& payload); Web::WebDriver::Response back();