diff --git a/Userland/Applications/Browser/BrowserWindow.cpp b/Userland/Applications/Browser/BrowserWindow.cpp index 65305c7cb01..7f43d69b385 100644 --- a/Userland/Applications/Browser/BrowserWindow.cpp +++ b/Userland/Applications/Browser/BrowserWindow.cpp @@ -42,6 +42,7 @@ #include #include #include +#include namespace Browser { @@ -630,6 +631,10 @@ void BrowserWindow::create_new_tab(URL url, bool activate) return active_tab().view().get_element_tag_name(element_id); }; + new_tab.webdriver_endpoints().on_execute_script = [this](String const& body, Vector const& json_arguments, Optional const& timeout, bool async) { + return active_tab().view().webdriver_execute_script(body, json_arguments, timeout, async); + }; + new_tab.load(url); dbgln_if(SPAM_DEBUG, "Added new tab {:p}, loading {}", &new_tab, url); diff --git a/Userland/Applications/Browser/WebDriverConnection.cpp b/Userland/Applications/Browser/WebDriverConnection.cpp index c0fb8950c61..a4dbec53aa2 100644 --- a/Userland/Applications/Browser/WebDriverConnection.cpp +++ b/Userland/Applications/Browser/WebDriverConnection.cpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace Browser { @@ -116,6 +117,21 @@ void WebDriverConnection::minimize_window() browser_window->set_minimized(true); } +Messages::WebDriverSessionClient::ExecuteScriptResponse WebDriverConnection::execute_script(String const& body, Vector const& json_arguments, Optional const& timeout, bool async) +{ + dbgln("WebDriverConnection: execute_script"); + if (auto browser_window = m_browser_window.strong_ref()) { + auto& tab = browser_window->active_tab(); + if (tab.webdriver_endpoints().on_execute_script) { + auto response = tab.webdriver_endpoints().on_execute_script(body, json_arguments, timeout, async); + // WebContentServer's and WebDriverSessionClient's ExecuteScriptResponse have an identical + // structure but are distinct types, so we have to convert here. + return { response.result_type(), response.json_result() }; + } + } + return { {} }; +} + Messages::WebDriverSessionClient::GetAllCookiesResponse WebDriverConnection::get_all_cookies() { dbgln_if(WEBDRIVER_DEBUG, "WebDriverConnection: get_cookies"); diff --git a/Userland/Applications/Browser/WebDriverConnection.h b/Userland/Applications/Browser/WebDriverConnection.h index 9bf1627de8b..6a8ddde2b75 100644 --- a/Userland/Applications/Browser/WebDriverConnection.h +++ b/Userland/Applications/Browser/WebDriverConnection.h @@ -49,6 +49,7 @@ public: virtual void set_window_position(Gfx::IntPoint const&) override; virtual void maximize_window() override; virtual void minimize_window() override; + virtual Messages::WebDriverSessionClient::ExecuteScriptResponse execute_script(String const& body, Vector const& json_arguments, Optional const& timeout, bool async) override; virtual Messages::WebDriverSessionClient::GetAllCookiesResponse get_all_cookies() override; virtual Messages::WebDriverSessionClient::GetNamedCookieResponse get_named_cookie(String const& name) override; virtual void add_cookie(Web::Cookie::ParsedCookie const&) override; diff --git a/Userland/Applications/Browser/WebDriverEndpoints.h b/Userland/Applications/Browser/WebDriverEndpoints.h index c4f522c64ff..d10138e10dd 100644 --- a/Userland/Applications/Browser/WebDriverEndpoints.h +++ b/Userland/Applications/Browser/WebDriverEndpoints.h @@ -10,6 +10,10 @@ #include #include +namespace Messages::WebContentServer { +class WebdriverExecuteScriptResponse; +} + namespace Browser { class WebDriverEndpoints { @@ -25,6 +29,7 @@ public: Function on_get_computed_value_for_element; Function on_get_element_text; Function on_get_element_tag_name; + 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 0e577c70cf9..2a4885255d3 100644 --- a/Userland/Applications/Browser/WebDriverSessionClient.ipc +++ b/Userland/Applications/Browser/WebDriverSessionClient.ipc @@ -6,6 +6,7 @@ #include #include #include +#include endpoint WebDriverSessionClient { quit() =| @@ -22,6 +23,7 @@ endpoint WebDriverSessionClient { set_window_position(Gfx::IntPoint position) =| maximize_window() =| minimize_window() =| + execute_script(String body, Vector json_arguments, Optional timeout, bool async) => (Web::WebDriver::ExecuteScriptResultType result_type, String json_result) get_all_cookies() => (Vector cookies) get_named_cookie(String name) => (Optional cookie) add_cookie(Web::Cookie::ParsedCookie cookie) =| diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp index 8a801d15020..078f8041b24 100644 --- a/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp +++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.cpp @@ -592,6 +592,11 @@ Gfx::ShareableBitmap OutOfProcessWebView::take_screenshot() const return {}; } +Messages::WebContentServer::WebdriverExecuteScriptResponse OutOfProcessWebView::webdriver_execute_script(String const& body, Vector const& json_arguments, Optional const& timeout, bool async) +{ + return client().webdriver_execute_script(body, json_arguments, timeout, async); +} + void OutOfProcessWebView::focusin_event(GUI::FocusEvent&) { client().async_set_has_focus(true); diff --git a/Userland/Libraries/LibWebView/OutOfProcessWebView.h b/Userland/Libraries/LibWebView/OutOfProcessWebView.h index a081c4dc26a..8d5a379826d 100644 --- a/Userland/Libraries/LibWebView/OutOfProcessWebView.h +++ b/Userland/Libraries/LibWebView/OutOfProcessWebView.h @@ -13,6 +13,10 @@ #include #include +namespace Messages::WebContentServer { +class WebdriverExecuteScriptResponse; +} + namespace WebView { class WebContentClient; @@ -77,6 +81,8 @@ public: Gfx::ShareableBitmap take_screenshot() const; + Messages::WebContentServer::WebdriverExecuteScriptResponse webdriver_execute_script(String const& body, Vector const& json_arguments, Optional const& timeout, bool async); + Function on_context_menu_request; Function on_link_click; Function on_link_context_menu_request;