diff --git a/Userland/Applications/Browser/WebDriverConnection.cpp b/Userland/Applications/Browser/WebDriverConnection.cpp index 4e7ffda3c3..8bcdcb76e7 100644 --- a/Userland/Applications/Browser/WebDriverConnection.cpp +++ b/Userland/Applications/Browser/WebDriverConnection.cpp @@ -1,12 +1,15 @@ /* * Copyright (c) 2022, Florent Castelli * Copyright (c) 2022, Sam Atkins + * Copyright (c) 2022, Tobias Christiansen * * SPDX-License-Identifier: BSD-2-Clause */ #include "WebDriverConnection.h" #include "BrowserWindow.h" +#include +#include namespace Browser { @@ -67,4 +70,15 @@ void WebDriverConnection::forward() browser_window->active_tab().go_forward(); } +Messages::WebDriverSessionClient::GetAllCookiesResponse WebDriverConnection::get_all_cookies() +{ + dbgln("WebDriverConnection: get_cookies"); + if (auto browser_window = m_browser_window.strong_ref()) { + if (browser_window->active_tab().on_get_cookies_entries) { + return { browser_window->active_tab().on_get_cookies_entries() }; + } + } + return { {} }; +} + } diff --git a/Userland/Applications/Browser/WebDriverConnection.h b/Userland/Applications/Browser/WebDriverConnection.h index 780ba9f016..17f394ef1c 100644 --- a/Userland/Applications/Browser/WebDriverConnection.h +++ b/Userland/Applications/Browser/WebDriverConnection.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2022, Florent Castelli * Copyright (c) 2022, Sam Atkins + * Copyright (c) 2022, Tobias Christiansen * * SPDX-License-Identifier: BSD-2-Clause */ @@ -42,6 +43,7 @@ public: virtual void refresh() override; virtual void back() override; virtual void forward() override; + virtual Messages::WebDriverSessionClient::GetAllCookiesResponse get_all_cookies() override; private: WebDriverConnection(NonnullOwnPtr socket, NonnullRefPtr browser_window); diff --git a/Userland/Applications/Browser/WebDriverSessionClient.ipc b/Userland/Applications/Browser/WebDriverSessionClient.ipc index 872de32c3f..974fc1cc49 100644 --- a/Userland/Applications/Browser/WebDriverSessionClient.ipc +++ b/Userland/Applications/Browser/WebDriverSessionClient.ipc @@ -1,4 +1,6 @@ #include +#include +#include endpoint WebDriverSessionClient { quit() =| @@ -9,4 +11,5 @@ endpoint WebDriverSessionClient { refresh() =| back() =| forward() =| + get_all_cookies() => (Vector cookies) } diff --git a/Userland/Services/WebDriver/CMakeLists.txt b/Userland/Services/WebDriver/CMakeLists.txt index c8365b127f..10aae0d3cc 100644 --- a/Userland/Services/WebDriver/CMakeLists.txt +++ b/Userland/Services/WebDriver/CMakeLists.txt @@ -8,12 +8,12 @@ set(SOURCES Client.cpp Session.cpp main.cpp -) + ) set(GENERATED_SOURCES ../../Applications/Browser/WebDriverSessionClientEndpoint.h ../../Applications/Browser/WebDriverSessionServerEndpoint.h -) + ) serenity_bin(WebDriver) -target_link_libraries(WebDriver LibCore LibHTTP LibMain LibIPC) +target_link_libraries(WebDriver LibCore LibHTTP LibMain LibIPC LibWeb) diff --git a/Userland/Services/WebDriver/Client.cpp b/Userland/Services/WebDriver/Client.cpp index 293a0511ef..8974cdd568 100644 --- a/Userland/Services/WebDriver/Client.cpp +++ b/Userland/Services/WebDriver/Client.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2022, Florent Castelli * Copyright (c) 2022, Sam Atkins + * Copyright (c) 2022, Tobias Christiansen * * SPDX-License-Identifier: BSD-2-Clause */ @@ -29,6 +30,7 @@ Vector Client::s_routes = { { HTTP::HttpRequest::Method::POST, { "session", ":session_id", "refresh" }, &Client::handle_refresh }, { HTTP::HttpRequest::Method::POST, { "session", ":session_id", "back" }, &Client::handle_back }, { HTTP::HttpRequest::Method::POST, { "session", ":session_id", "forward" }, &Client::handle_forward }, + { HTTP::HttpRequest::Method::GET, { "session", ":session_id", "cookie" }, &Client::handle_get_all_cookies }, }; Client::Client(NonnullOwnPtr socket, Core::Object* parent) @@ -487,4 +489,16 @@ ErrorOr Client::handle_forward(Vector paramete return make_json_value(result); } +// GET /session/{session id}/cookie https://w3c.github.io/webdriver/#dfn-get-all-cookies +ErrorOr Client::handle_get_all_cookies(Vector parameters, JsonValue const&) +{ + dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session//cookie"); + Session* session = TRY(find_session_with_id(parameters[0])); + + // NOTE: Spec steps handled in Session::get_all_cookies(). + auto cookies = TRY(session->get_all_cookies()); + + return make_json_value(cookies); +} + } diff --git a/Userland/Services/WebDriver/Client.h b/Userland/Services/WebDriver/Client.h index 47c9fb34dc..b8d5ba9ad2 100644 --- a/Userland/Services/WebDriver/Client.h +++ b/Userland/Services/WebDriver/Client.h @@ -56,6 +56,7 @@ private: ErrorOr handle_refresh(Vector, JsonValue const& payload); ErrorOr handle_back(Vector, JsonValue const& payload); ErrorOr handle_forward(Vector, JsonValue const& payload); + ErrorOr handle_get_all_cookies(Vector, JsonValue const& payload); ErrorOr find_session_with_id(StringView session_id); JsonValue make_json_value(JsonValue const&); diff --git a/Userland/Services/WebDriver/Session.cpp b/Userland/Services/WebDriver/Session.cpp index a6bc4c2fce..02a4c32951 100644 --- a/Userland/Services/WebDriver/Session.cpp +++ b/Userland/Services/WebDriver/Session.cpp @@ -1,6 +1,7 @@ /* * Copyright (c) 2022, Florent Castelli * Copyright (c) 2022, Sam Atkins + * Copyright (c) 2022, Tobias Christiansen * * SPDX-License-Identifier: BSD-2-Clause */ @@ -11,6 +12,7 @@ #include #include #include +#include #include namespace WebDriver { @@ -229,4 +231,46 @@ ErrorOr Session::forward() return JsonValue(); } +// https://w3c.github.io/webdriver/#dfn-serialized-cookie +static JsonObject serialize_cookie(Web::Cookie::Cookie const& cookie) +{ + JsonObject serialized_cookie = {}; + serialized_cookie.set("name", cookie.name); + serialized_cookie.set("value", cookie.value); + serialized_cookie.set("path", cookie.path); + serialized_cookie.set("domain", cookie.domain); + serialized_cookie.set("secure", cookie.secure); + serialized_cookie.set("httpOnly", cookie.http_only); + serialized_cookie.set("expiry", cookie.expiry_time.timestamp()); + // FIXME: Add sameSite to Cookie and serialize it here too. + + return serialized_cookie; +} + +// GET /session/{session id}/cookie https://w3c.github.io/webdriver/#dfn-get-all-cookies +ErrorOr Session::get_all_cookies() +{ + // 1. If the current browsing context is no longer open, return error with error code no such window. + auto current_window = get_window_object(); + if (!current_window.has_value()) + return HttpError { 404, "no such window", "Window not found" }; + + // FIXME: 2. Handle any user prompts, and return its value if it is an error. + + // 3. Let cookies be a new JSON List. + JsonArray cookies = {}; + + // 4. For each cookie in all associated cookies of the current browsing context’s active document: + for (auto const& cookie : m_browser_connection->get_all_cookies()) { + // 1. Let serialized cookie be the result of serializing cookie. + auto serialized_cookie = serialize_cookie(cookie); + + // 2. Append serialized cookie to cookies + cookies.append(serialized_cookie); + } + + // 5. Return success with data cookies. + return JsonValue(cookies); +} + } diff --git a/Userland/Services/WebDriver/Session.h b/Userland/Services/WebDriver/Session.h index 053edca7df..f34bc37b11 100644 --- a/Userland/Services/WebDriver/Session.h +++ b/Userland/Services/WebDriver/Session.h @@ -40,6 +40,7 @@ public: ErrorOr refresh(); ErrorOr back(); ErrorOr forward(); + ErrorOr get_all_cookies(); private: NonnullRefPtr m_client;