diff --git a/Userland/Applications/Browser/BrowserWindow.cpp b/Userland/Applications/Browser/BrowserWindow.cpp index aea52c5f95..f2a957f28b 100644 --- a/Userland/Applications/Browser/BrowserWindow.cpp +++ b/Userland/Applications/Browser/BrowserWindow.cpp @@ -635,6 +635,10 @@ void BrowserWindow::create_new_tab(URL url, bool activate) return active_tab().view().get_element_rect(element_id); }; + new_tab.webdriver_endpoints().on_is_element_enabled = [this](i32 element_id) { + return active_tab().view().is_element_enabled(element_id); + }; + new_tab.webdriver_endpoints().on_serialize_source = [this]() { return active_tab().view().serialize_source(); }; diff --git a/Userland/Applications/Browser/WebDriverConnection.cpp b/Userland/Applications/Browser/WebDriverConnection.cpp index d213269054..091d3cba45 100644 --- a/Userland/Applications/Browser/WebDriverConnection.cpp +++ b/Userland/Applications/Browser/WebDriverConnection.cpp @@ -2,6 +2,7 @@ * Copyright (c) 2022, Florent Castelli * Copyright (c) 2022, Sam Atkins * Copyright (c) 2022, Tobias Christiansen + * Copyright (c) 2022, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -294,6 +295,17 @@ Messages::WebDriverSessionClient::GetElementRectResponse WebDriverConnection::ge return { {} }; } +Messages::WebDriverSessionClient::IsElementEnabledResponse WebDriverConnection::is_element_enabled(i32 element_id) +{ + dbgln("WebDriverConnection: is_element_enabled {}", element_id); + if (auto browser_window = m_browser_window.strong_ref()) { + auto& tab = browser_window->active_tab(); + if (tab.webdriver_endpoints().on_is_element_enabled) + return { tab.webdriver_endpoints().on_is_element_enabled(element_id) }; + } + return { false }; +} + Messages::WebDriverSessionClient::TakeScreenshotResponse WebDriverConnection::take_screenshot() { dbgln_if(WEBDRIVER_DEBUG, "WebDriverConnection: take_screenshot"); diff --git a/Userland/Applications/Browser/WebDriverConnection.h b/Userland/Applications/Browser/WebDriverConnection.h index c4415d072c..8f39e36db8 100644 --- a/Userland/Applications/Browser/WebDriverConnection.h +++ b/Userland/Applications/Browser/WebDriverConnection.h @@ -2,6 +2,7 @@ * Copyright (c) 2022, Florent Castelli * Copyright (c) 2022, Sam Atkins * Copyright (c) 2022, Tobias Christiansen + * Copyright (c) 2022, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -64,6 +65,7 @@ public: virtual Messages::WebDriverSessionClient::GetElementTextResponse get_element_text(i32 element_id) override; virtual Messages::WebDriverSessionClient::GetElementTagNameResponse get_element_tag_name(i32 element_id) override; virtual Messages::WebDriverSessionClient::GetElementRectResponse get_element_rect(i32 element_id) override; + virtual Messages::WebDriverSessionClient::IsElementEnabledResponse is_element_enabled(i32 element_id) override; virtual Messages::WebDriverSessionClient::TakeScreenshotResponse take_screenshot() override; private: diff --git a/Userland/Applications/Browser/WebDriverEndpoints.h b/Userland/Applications/Browser/WebDriverEndpoints.h index 8066e11d69..9410a61520 100644 --- a/Userland/Applications/Browser/WebDriverEndpoints.h +++ b/Userland/Applications/Browser/WebDriverEndpoints.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2022, Tobias Christiansen + * Copyright (c) 2022, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -31,6 +32,7 @@ public: Function on_get_element_text; Function on_get_element_tag_name; Function on_get_element_rect; + Function on_is_element_enabled; Function on_serialize_source; Function const& json_arguments, Optional const& timeout, bool async)> on_execute_script; }; diff --git a/Userland/Applications/Browser/WebDriverSessionClient.ipc b/Userland/Applications/Browser/WebDriverSessionClient.ipc index 05e35fa4cc..6dac30564d 100644 --- a/Userland/Applications/Browser/WebDriverSessionClient.ipc +++ b/Userland/Applications/Browser/WebDriverSessionClient.ipc @@ -38,5 +38,6 @@ endpoint WebDriverSessionClient { get_element_text(i32 element_id) => (String text) get_element_tag_name(i32 element_id) => (String tag_name) get_element_rect(i32 element_id) => (Gfx::IntRect rect) + is_element_enabled(i32 element_id) => (bool enabled) take_screenshot() => (Gfx::ShareableBitmap data) } diff --git a/Userland/Services/WebDriver/Client.cpp b/Userland/Services/WebDriver/Client.cpp index 5d11e82c2d..77cc5bb0b6 100644 --- a/Userland/Services/WebDriver/Client.cpp +++ b/Userland/Services/WebDriver/Client.cpp @@ -3,6 +3,7 @@ * Copyright (c) 2022, Sam Atkins * Copyright (c) 2022, Tobias Christiansen * Copyright (c) 2022, Linus Groh + * Copyright (c) 2022, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -50,6 +51,7 @@ Vector Client::s_routes = { { HTTP::HttpRequest::Method::GET, { "session", ":session_id", "element", ":element_id", "text" }, &Client::handle_get_element_text }, { HTTP::HttpRequest::Method::GET, { "session", ":session_id", "element", ":element_id", "name" }, &Client::handle_get_element_tag_name }, { HTTP::HttpRequest::Method::GET, { "session", ":session_id", "element", ":element_id", "rect" }, &Client::handle_get_element_rect }, + { HTTP::HttpRequest::Method::GET, { "session", ":session_id", "element", ":element_id", "enabled" }, &Client::handle_is_element_enabled }, { HTTP::HttpRequest::Method::GET, { "session", ":session_id", "source" }, &Client::handle_get_source }, { HTTP::HttpRequest::Method::POST, { "session", ":session_id", "execute", "sync" }, &Client::handle_execute_script }, { HTTP::HttpRequest::Method::POST, { "session", ":session_id", "execute", "async" }, &Client::handle_execute_async_script }, @@ -699,6 +701,16 @@ ErrorOr Client::handle_get_element_rect(Vector Client::handle_is_element_enabled(Vector const& parameters, JsonValue const&) +{ + dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session//element//enabled"); + auto* session = TRY(find_session_with_id(parameters[0])); + auto result = TRY(session->is_element_enabled(parameters[1])); + return make_json_value(result); +} + // 13.1 Get Page Source, https://w3c.github.io/webdriver/#dfn-get-page-source // GET /session/{session id}/source ErrorOr Client::handle_get_source(Vector const& parameters, JsonValue const&) diff --git a/Userland/Services/WebDriver/Client.h b/Userland/Services/WebDriver/Client.h index ab1511b7dc..4ca56b8f89 100644 --- a/Userland/Services/WebDriver/Client.h +++ b/Userland/Services/WebDriver/Client.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2022, Florent Castelli * Copyright (c) 2022, Linus Groh + * Copyright (c) 2022, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -75,6 +76,7 @@ private: ErrorOr handle_get_element_text(Vector const&, JsonValue const& payload); ErrorOr handle_get_element_tag_name(Vector const&, JsonValue const& payload); ErrorOr handle_get_element_rect(Vector const&, JsonValue const& payload); + ErrorOr handle_is_element_enabled(Vector const&, JsonValue const& payload); ErrorOr handle_get_source(Vector const&, JsonValue const& payload); ErrorOr handle_execute_script(Vector const&, JsonValue const& payload); ErrorOr handle_execute_async_script(Vector const&, JsonValue const& payload); diff --git a/Userland/Services/WebDriver/Session.cpp b/Userland/Services/WebDriver/Session.cpp index 02b50a5d77..7501ef360f 100644 --- a/Userland/Services/WebDriver/Session.cpp +++ b/Userland/Services/WebDriver/Session.cpp @@ -3,6 +3,7 @@ * Copyright (c) 2022, Sam Atkins * Copyright (c) 2022, Tobias Christiansen * Copyright (c) 2022, Linus Groh + * Copyright (c) 2022, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -936,6 +937,32 @@ ErrorOr Session::get_element_rect(StringView paramete return body; } +// 12.4.8 Is Element Enabled, https://w3c.github.io/webdriver/#dfn-is-element-enabled +ErrorOr Session::is_element_enabled(StringView parameter_element_id) +{ + // 1. If the current 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. Let element be the result of trying to get a known connected element with url variable element id. + // NOTE: The whole concept of "connected elements" is not implemented yet. See get_or_create_a_web_element_reference() + // For now the element is only represented by its ID + auto maybe_element_id = parameter_element_id.to_int(); + if (!maybe_element_id.has_value()) + return WebDriverError::from_code(ErrorCode::InvalidArgument, "Element ID is not an i32"); + + auto element_id = maybe_element_id.release_value(); + + // 4. Let enabled be a boolean initially set to true if the current browsing context’s active document’s type is not "xml". + // 5. Otherwise, let enabled to false and jump to the last step of this algorithm. + // 6. Set enabled to false if a form control is disabled. + auto enabled = m_browser_connection->is_element_enabled(element_id); + + // 7. Return success with data enabled. + return enabled; +} + // 13.1 Get Page Source, https://w3c.github.io/webdriver/#dfn-get-page-source ErrorOr Session::get_source() { diff --git a/Userland/Services/WebDriver/Session.h b/Userland/Services/WebDriver/Session.h index bfff084833..4ce2824ba0 100644 --- a/Userland/Services/WebDriver/Session.h +++ b/Userland/Services/WebDriver/Session.h @@ -1,6 +1,7 @@ /* * Copyright (c) 2022, Florent Castelli * Copyright (c) 2022, Linus Groh + * Copyright (c) 2022, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -64,6 +65,7 @@ public: ErrorOr get_element_text(JsonValue const& payload, StringView element_id); ErrorOr get_element_tag_name(JsonValue const& payload, StringView element_id); ErrorOr get_element_rect(StringView element_id); + ErrorOr is_element_enabled(StringView element_id); ErrorOr get_source(); ErrorOr execute_script(JsonValue const& payload); ErrorOr execute_async_script(JsonValue const& payload);