diff --git a/Userland/Services/WebContent/WebDriverConnection.cpp b/Userland/Services/WebContent/WebDriverConnection.cpp index c66fc4a6253..e838476adbc 100644 --- a/Userland/Services/WebContent/WebDriverConnection.cpp +++ b/Userland/Services/WebContent/WebDriverConnection.cpp @@ -301,7 +301,7 @@ Messages::WebDriverClient::NavigateToResponse WebDriverConnection::navigate_to(J // FIXME: 10. If the current top-level browsing context contains a refresh state pragma directive of time 1 second or less, wait until the refresh timeout has elapsed, a new navigate has begun, and return to the first step of this algorithm. - async_navigation_complete(move(result)); + async_driver_execution_complete(move(result)); }); // 8. If url is special except for file and current URL and URL do not have the same absolute URL: @@ -713,7 +713,7 @@ Messages::WebDriverClient::SetWindowRectResponse WebDriverConnection::set_window } if (m_pending_window_rect_requests == 0) - async_window_rect_updated(serialize_rect(compute_window_rect(page))); + async_driver_execution_complete(serialize_rect(compute_window_rect(page))); })); // 14. Return success with data set to the WindowRect object for the current top-level browsing context. @@ -759,7 +759,7 @@ Messages::WebDriverClient::MinimizeWindowResponse WebDriverConnection::minimize_ // 5. Iconify the window. iconify_the_window(JS::create_heap_function(current_top_level_browsing_context()->heap(), [this]() { auto& page = current_top_level_browsing_context()->page(); - async_window_rect_updated(serialize_rect(compute_window_rect(page))); + async_driver_execution_complete(serialize_rect(compute_window_rect(page))); })); // 6. Return success with data set to the WindowRect object for the current top-level browsing context. @@ -858,7 +858,7 @@ Messages::WebDriverClient::FindElementResponse WebDriverConnection::find_element // 9. Let result be the result of trying to Find with session, start node, location strategy, and selector. find(*location_strategy, move(selector), get_start_node, JS::create_heap_function(current_browsing_context().heap(), [this](Web::WebDriver::Response result) { // 10. If result is empty, return error with error code no such element. Otherwise, return the first element of result. - async_find_elements_complete(extract_first_element(move(result))); + async_driver_execution_complete(extract_first_element(move(result))); })); return JsonValue {}; @@ -899,7 +899,7 @@ Messages::WebDriverClient::FindElementsResponse WebDriverConnection::find_elemen // 9. Return the result of trying to Find with session, start node, location strategy, and selector. find(*location_strategy, move(selector), get_start_node, JS::create_heap_function(current_browsing_context().heap(), [this](Web::WebDriver::Response result) { - async_find_elements_complete(move(result)); + async_driver_execution_complete(move(result)); })); return JsonValue {}; @@ -934,7 +934,7 @@ Messages::WebDriverClient::FindElementFromElementResponse WebDriverConnection::f // 8. Let result be the value of trying to Find with session, start node, location strategy, and selector. find(*location_strategy, move(selector), get_start_node, JS::create_heap_function(current_browsing_context().heap(), [this](Web::WebDriver::Response result) { // 9. If result is empty, return error with error code no such element. Otherwise, return the first element of result. - async_find_elements_complete(extract_first_element(move(result))); + async_driver_execution_complete(extract_first_element(move(result))); })); return JsonValue {}; @@ -968,7 +968,7 @@ Messages::WebDriverClient::FindElementsFromElementResponse WebDriverConnection:: // 8. Return the result of trying to Find with session, start node, location strategy, and selector. find(*location_strategy, move(selector), get_start_node, JS::create_heap_function(current_browsing_context().heap(), [this](Web::WebDriver::Response result) { - async_find_elements_complete(move(result)); + async_driver_execution_complete(move(result)); })); return JsonValue {}; @@ -1003,7 +1003,7 @@ Messages::WebDriverClient::FindElementFromShadowRootResponse WebDriverConnection // 8. Let result be the value of trying to Find with session, start node, location strategy, and selector. find(*location_strategy, move(selector), get_start_node, JS::create_heap_function(current_browsing_context().heap(), [this](Web::WebDriver::Response result) { // 9. If result is empty, return error with error code no such element. Otherwise, return the first element of result. - async_find_elements_complete(extract_first_element(move(result))); + async_driver_execution_complete(extract_first_element(move(result))); })); return JsonValue {}; @@ -1037,7 +1037,7 @@ Messages::WebDriverClient::FindElementsFromShadowRootResponse WebDriverConnectio // 8. Return the result of trying to Find with session, start node, location strategy, and selector. find(*location_strategy, move(selector), get_start_node, JS::create_heap_function(current_browsing_context().heap(), [this](Web::WebDriver::Response result) { - async_find_elements_complete(move(result)); + async_driver_execution_complete(move(result)); })); return JsonValue {}; @@ -1408,9 +1408,9 @@ Messages::WebDriverClient::ElementClickResponse WebDriverConnection::element_cli // FIXME: 12. Try to run the post-navigation checks. if (navigation_result.is_error()) - async_actions_performed(move(navigation_result)); + async_driver_execution_complete(move(navigation_result)); else - async_actions_performed(move(result)); + async_driver_execution_complete(move(result)); })); }); @@ -1730,7 +1730,7 @@ Messages::WebDriverClient::ElementSendKeysResponse WebDriverConnection::element_ // NOTE: These events are fired by `did_select_files` as an element task. So instead of firing them here, we spin // the event loop once before informing the client that the action is complete. Web::HTML::queue_a_task(Web::HTML::Task::Source::Unspecified, nullptr, nullptr, JS::create_heap_function(current_browsing_context().heap(), [this]() { - async_actions_performed(JsonValue {}); + async_driver_execution_complete(JsonValue {}); })); // 8. Return success with data null. @@ -1754,7 +1754,7 @@ Messages::WebDriverClient::ElementSendKeysResponse WebDriverConnection::element_ // FIXME: 4. If element is suffering from bad input return an error with error code invalid argument. // 5. Return success with data null. - async_actions_performed(JsonValue {}); + async_driver_execution_complete(JsonValue {}); return JsonValue {}; } // -> element is content editable @@ -1810,7 +1810,7 @@ Messages::WebDriverClient::ElementSendKeysResponse WebDriverConnection::element_ // 14. Remove an input source with input state and input id. Web::WebDriver::remove_input_source(input_state, input_id); - async_actions_performed(move(result)); + async_driver_execution_complete(move(result)); })); // 15. Return success with data null. @@ -1926,7 +1926,7 @@ void WebDriverConnection::handle_script_response(Web::WebDriver::ExecuteScriptRe VERIFY_NOT_REACHED(); }(); - async_script_executed(move(response)); + async_driver_execution_complete(move(response)); } // 14.1 Get All Cookies, https://w3c.github.io/webdriver/#dfn-get-all-cookies @@ -2125,7 +2125,7 @@ Messages::WebDriverClient::PerformActionsResponse WebDriverConnection::perform_a // results in an error return that error. auto on_complete = JS::create_heap_function(current_browsing_context().heap(), [this](Web::WebDriver::Response result) { m_action_executor = nullptr; - async_actions_performed(move(result)); + async_driver_execution_complete(move(result)); }); m_action_executor = Web::WebDriver::dispatch_actions(input_state, move(actions_by_tick), current_browsing_context(), move(actions_options), on_complete); @@ -2176,7 +2176,7 @@ Messages::WebDriverClient::DismissAlertResponse WebDriverConnection::dismiss_ale // 3. Dismiss the current user prompt. current_browsing_context().page().dismiss_dialog(JS::create_heap_function(current_browsing_context().heap(), [this]() { - async_dialog_closed(JsonValue {}); + async_driver_execution_complete(JsonValue {}); })); // 4. Return success with data null. @@ -2195,7 +2195,7 @@ Messages::WebDriverClient::AcceptAlertResponse WebDriverConnection::accept_alert // 3. Accept the current user prompt. current_browsing_context().page().accept_dialog(JS::create_heap_function(current_browsing_context().heap(), [this]() { - async_dialog_closed(JsonValue {}); + async_driver_execution_complete(JsonValue {}); })); // 4. Return success with data null. @@ -2279,7 +2279,7 @@ Messages::WebDriverClient::TakeScreenshotResponse WebDriverConnection::take_scre // b. Let screenshot result be the result of trying to call draw a bounding box from the framebuffer, given root rect as an argument. auto screenshot_result = Web::WebDriver::draw_bounding_box_from_the_framebuffer(*current_top_level_browsing_context(), *document->document_element(), root_rect); if (screenshot_result.is_error()) { - async_screenshot_taken(screenshot_result.release_error()); + async_driver_execution_complete(screenshot_result.release_error()); return; } @@ -2291,7 +2291,7 @@ Messages::WebDriverClient::TakeScreenshotResponse WebDriverConnection::take_scre auto encoded_string = Web::WebDriver::encode_canvas_element(canvas); // 3. Return success with data encoded string. - async_screenshot_taken(move(encoded_string)); + async_driver_execution_complete(move(encoded_string)); })); return JsonValue {}; @@ -2323,7 +2323,7 @@ Messages::WebDriverClient::TakeElementScreenshotResponse WebDriverConnection::ta // b. Let screenshot result be the result of trying to call draw a bounding box from the framebuffer, given element rect as an argument. auto screenshot_result = Web::WebDriver::draw_bounding_box_from_the_framebuffer(current_browsing_context(), element, element_rect); if (screenshot_result.is_error()) { - async_screenshot_taken(screenshot_result.release_error()); + async_driver_execution_complete(screenshot_result.release_error()); return; } @@ -2335,7 +2335,7 @@ Messages::WebDriverClient::TakeElementScreenshotResponse WebDriverConnection::ta auto encoded_string = Web::WebDriver::encode_canvas_element(canvas); // 6. Return success with data encoded string. - async_screenshot_taken(move(encoded_string)); + async_driver_execution_complete(move(encoded_string)); })); return JsonValue {}; @@ -2377,7 +2377,7 @@ void WebDriverConnection::set_current_top_level_browsing_context(Web::HTML::Brow if (m_current_top_level_browsing_context) { m_current_top_level_browsing_context->page().set_window_rect_observer(JS::create_heap_function(m_current_top_level_browsing_context->heap(), [this](Web::DevicePixelRect rect) { if (m_pending_window_rect_requests > 0 && --m_pending_window_rect_requests == 0) - async_window_rect_updated(serialize_rect(rect.to_type())); + async_driver_execution_complete(serialize_rect(rect.to_type())); })); } @@ -2553,7 +2553,7 @@ void WebDriverConnection::page_did_open_dialog(Badge) // [[Value]]: null, [[Target]]: empty }, but continue to run the other steps of this algorithm in parallel. if (m_has_pending_script_execution) { m_has_pending_script_execution = false; - async_script_executed(JsonValue {}); + async_driver_execution_complete(JsonValue {}); } } diff --git a/Userland/Services/WebContent/WebDriverServer.ipc b/Userland/Services/WebContent/WebDriverServer.ipc index 53404b22add..b1293f5340f 100644 --- a/Userland/Services/WebContent/WebDriverServer.ipc +++ b/Userland/Services/WebContent/WebDriverServer.ipc @@ -1,11 +1,5 @@ #include endpoint WebDriverServer { - navigation_complete(Web::WebDriver::Response response) =| - window_rect_updated(Web::WebDriver::Response response) =| - find_elements_complete(Web::WebDriver::Response response) =| - script_executed(Web::WebDriver::Response response) =| - actions_performed(Web::WebDriver::Response response) =| - dialog_closed(Web::WebDriver::Response response) =| - screenshot_taken(Web::WebDriver::Response response) =| + driver_execution_complete(Web::WebDriver::Response response) =| } diff --git a/Userland/Services/WebDriver/Client.cpp b/Userland/Services/WebDriver/Client.cpp index 995c54e8b21..545d97c625a 100644 --- a/Userland/Services/WebDriver/Client.cpp +++ b/Userland/Services/WebDriver/Client.cpp @@ -241,7 +241,10 @@ Web::WebDriver::Response Client::navigate_to(Web::WebDriver::Parameters paramete { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//url"); auto session = TRY(find_session_with_id(parameters[0])); - return session->navigate_to(payload); + + return session->perform_async_action([&](auto& connection) { + return connection.navigate_to(move(payload)); + }); } // 10.2 Get Current URL, https://w3c.github.io/webdriver/#dfn-get-current-url @@ -397,7 +400,10 @@ Web::WebDriver::Response Client::set_window_rect(Web::WebDriver::Parameters para { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//window/rect"); auto session = TRY(find_session_with_id(parameters[0])); - return session->set_window_rect(payload); + + return session->perform_async_action([&](auto& connection) { + return connection.set_window_rect(move(payload)); + }); } // 11.8.3 Maximize Window, https://w3c.github.io/webdriver/#dfn-maximize-window @@ -406,7 +412,10 @@ Web::WebDriver::Response Client::maximize_window(Web::WebDriver::Parameters para { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//window/maximize"); auto session = TRY(find_session_with_id(parameters[0])); - return session->maximize_window(); + + return session->perform_async_action([&](auto& connection) { + return connection.maximize_window(); + }); } // 11.8.4 Minimize Window, https://w3c.github.io/webdriver/#minimize-window @@ -415,7 +424,10 @@ Web::WebDriver::Response Client::minimize_window(Web::WebDriver::Parameters para { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//window/minimize"); auto session = TRY(find_session_with_id(parameters[0])); - return session->minimize_window(); + + return session->perform_async_action([&](auto& connection) { + return connection.minimize_window(); + }); } // 11.8.5 Fullscreen Window, https://w3c.github.io/webdriver/#dfn-fullscreen-window @@ -424,7 +436,10 @@ Web::WebDriver::Response Client::fullscreen_window(Web::WebDriver::Parameters pa { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//window/fullscreen"); auto session = TRY(find_session_with_id(parameters[0])); - return session->fullscreen_window(); + + return session->perform_async_action([&](auto& connection) { + return connection.fullscreen_window(); + }); } // Extension: Consume User Activation, https://html.spec.whatwg.org/multipage/interaction.html#user-activation-user-agent-automation @@ -442,7 +457,10 @@ Web::WebDriver::Response Client::find_element(Web::WebDriver::Parameters paramet { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//element"); auto session = TRY(find_session_with_id(parameters[0])); - return session->find_element(payload); + + return session->perform_async_action([&](auto& connection) { + return connection.find_element(move(payload)); + }); } // 12.3.3 Find Elements, https://w3c.github.io/webdriver/#dfn-find-elements @@ -451,7 +469,10 @@ Web::WebDriver::Response Client::find_elements(Web::WebDriver::Parameters parame { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//elements"); auto session = TRY(find_session_with_id(parameters[0])); - return session->find_elements(payload); + + return session->perform_async_action([&](auto& connection) { + return connection.find_elements(move(payload)); + }); } // 12.3.4 Find Element From Element, https://w3c.github.io/webdriver/#dfn-find-element-from-element @@ -460,7 +481,10 @@ Web::WebDriver::Response Client::find_element_from_element(Web::WebDriver::Param { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//element//element"); auto session = TRY(find_session_with_id(parameters[0])); - return session->find_element_from_element(move(parameters[1]), move(payload)); + + return session->perform_async_action([&](auto& connection) { + return connection.find_element_from_element(move(payload), move(parameters[1])); + }); } // 12.3.5 Find Elements From Element, https://w3c.github.io/webdriver/#dfn-find-elements-from-element @@ -469,7 +493,10 @@ Web::WebDriver::Response Client::find_elements_from_element(Web::WebDriver::Para { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//element//elements"); auto session = TRY(find_session_with_id(parameters[0])); - return session->find_elements_from_element(move(parameters[1]), move(payload)); + + return session->perform_async_action([&](auto& connection) { + return connection.find_elements_from_element(move(payload), move(parameters[1])); + }); } // 12.3.6 Find Element From Shadow Root, https://w3c.github.io/webdriver/#find-element-from-shadow-root @@ -478,7 +505,10 @@ Web::WebDriver::Response Client::find_element_from_shadow_root(Web::WebDriver::P { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//shadow//element"); auto session = TRY(find_session_with_id(parameters[0])); - return session->find_element_from_shadow_root(move(parameters[1]), move(payload)); + + return session->perform_async_action([&](auto& connection) { + return connection.find_element_from_shadow_root(move(payload), move(parameters[1])); + }); } // 12.3.7 Find Elements From Shadow Root, https://w3c.github.io/webdriver/#find-elements-from-shadow-root @@ -487,7 +517,10 @@ Web::WebDriver::Response Client::find_elements_from_shadow_root(Web::WebDriver:: { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//shadow//elements"); auto session = TRY(find_session_with_id(parameters[0])); - return session->find_elements_from_shadow_root(move(parameters[1]), move(payload)); + + return session->perform_async_action([&](auto& connection) { + return connection.find_elements_from_shadow_root(move(payload), move(parameters[1])); + }); } // 12.3.8 Get Active Element, https://w3c.github.io/webdriver/#get-active-element @@ -604,7 +637,10 @@ Web::WebDriver::Response Client::element_click(Web::WebDriver::Parameters parame { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//element//click"); auto session = TRY(find_session_with_id(parameters[0])); - return session->element_click(move(parameters[1])); + + return session->perform_async_action([&](auto& connection) { + return connection.element_click(move(parameters[1])); + }); } // 12.5.2 Element Clear, https://w3c.github.io/webdriver/#dfn-element-clear @@ -622,7 +658,10 @@ Web::WebDriver::Response Client::element_send_keys(Web::WebDriver::Parameters pa { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//element//value"); auto session = TRY(find_session_with_id(parameters[0])); - return session->element_send_keys(move(parameters[1]), move(payload)); + + return session->perform_async_action([&](auto& connection) { + return connection.element_send_keys(move(parameters[1]), move(payload)); + }); } // 13.1 Get Page Source, https://w3c.github.io/webdriver/#dfn-get-page-source @@ -640,7 +679,10 @@ Web::WebDriver::Response Client::execute_script(Web::WebDriver::Parameters param { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//execute/sync"); auto session = TRY(find_session_with_id(parameters[0])); - return session->execute_script(move(payload), Session::ScriptMode::Sync); + + return session->perform_async_action([&](auto& connection) { + return connection.execute_script(move(payload)); + }); } // 13.2.2 Execute Async Script, https://w3c.github.io/webdriver/#dfn-execute-async-script @@ -649,7 +691,10 @@ Web::WebDriver::Response Client::execute_async_script(Web::WebDriver::Parameters { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//execute/async"); auto session = TRY(find_session_with_id(parameters[0])); - return session->execute_script(move(payload), Session::ScriptMode::Async); + + return session->perform_async_action([&](auto& connection) { + return connection.execute_async_script(move(payload)); + }); } // 14.1 Get All Cookies, https://w3c.github.io/webdriver/#dfn-get-all-cookies @@ -703,7 +748,10 @@ Web::WebDriver::Response Client::perform_actions(Web::WebDriver::Parameters para { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//actions"); auto session = TRY(find_session_with_id(parameters[0])); - return session->perform_actions(move(payload)); + + return session->perform_async_action([&](auto& connection) { + return connection.perform_actions(move(payload)); + }); } // 15.8 Release Actions, https://w3c.github.io/webdriver/#release-actions @@ -721,7 +769,10 @@ Web::WebDriver::Response Client::dismiss_alert(Web::WebDriver::Parameters parame { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//alert/dismiss"); auto session = TRY(find_session_with_id(parameters[0])); - return session->dismiss_alert(); + + return session->perform_async_action([&](auto& connection) { + return connection.dismiss_alert(); + }); } // 16.2 Accept Alert, https://w3c.github.io/webdriver/#accept-alert @@ -730,7 +781,10 @@ Web::WebDriver::Response Client::accept_alert(Web::WebDriver::Parameters paramet { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//alert/accept"); auto session = TRY(find_session_with_id(parameters[0])); - return session->accept_alert(); + + return session->perform_async_action([&](auto& connection) { + return connection.accept_alert(); + }); } // 16.3 Get Alert Text, https://w3c.github.io/webdriver/#get-alert-text @@ -757,7 +811,10 @@ Web::WebDriver::Response Client::take_screenshot(Web::WebDriver::Parameters para { dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session//screenshot"); auto session = TRY(find_session_with_id(parameters[0])); - return session->take_screenshot(); + + return session->perform_async_action([&](auto& connection) { + return connection.take_screenshot(); + }); } // 17.2 Take Element Screenshot, https://w3c.github.io/webdriver/#dfn-take-element-screenshot @@ -766,7 +823,10 @@ Web::WebDriver::Response Client::take_element_screenshot(Web::WebDriver::Paramet { dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session//element//screenshot"); auto session = TRY(find_session_with_id(parameters[0])); - return session->take_element_screenshot(move(parameters[1])); + + return session->perform_async_action([&](auto& connection) { + return connection.take_element_screenshot(move(parameters[1])); + }); } // 18.1 Print Page, https://w3c.github.io/webdriver/#dfn-print-page diff --git a/Userland/Services/WebDriver/Session.cpp b/Userland/Services/WebDriver/Session.cpp index 39c5a10c513..21de3302476 100644 --- a/Userland/Services/WebDriver/Session.cpp +++ b/Userland/Services/WebDriver/Session.cpp @@ -11,8 +11,7 @@ #include "Session.h" #include "Client.h" #include -#include -#include +#include #include #include #include @@ -185,160 +184,4 @@ ErrorOr Session::ensure_current_window_handle_is_va return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchWindow, "Window not found"sv); } -template -static Web::WebDriver::Response perform_async_action(Handler& handler, Action&& action) -{ - Optional response; - - ScopeGuard guard { [&]() { handler = nullptr; } }; - handler = [&](auto result) { response = move(result); }; - - TRY(action()); - - Core::EventLoop::current().spin_until([&]() { - return response.has_value(); - }); - - return response.release_value(); -} - -Web::WebDriver::Response Session::navigate_to(JsonValue payload) const -{ - return perform_async_action(web_content_connection().on_navigation_complete, [&]() { - return web_content_connection().navigate_to(move(payload)); - }); -} - -Web::WebDriver::Response Session::set_window_rect(JsonValue payload) const -{ - return perform_async_action(web_content_connection().on_window_rect_updated, [&]() { - return web_content_connection().set_window_rect(move(payload)); - }); -} - -Web::WebDriver::Response Session::maximize_window() const -{ - return perform_async_action(web_content_connection().on_window_rect_updated, [&]() { - return web_content_connection().maximize_window(); - }); -} - -Web::WebDriver::Response Session::minimize_window() const -{ - return perform_async_action(web_content_connection().on_window_rect_updated, [&]() { - return web_content_connection().minimize_window(); - }); -} - -Web::WebDriver::Response Session::fullscreen_window() const -{ - return perform_async_action(web_content_connection().on_window_rect_updated, [&]() { - return web_content_connection().fullscreen_window(); - }); -} - -Web::WebDriver::Response Session::find_element(JsonValue payload) const -{ - return perform_async_action(web_content_connection().on_find_elements_complete, [&]() { - return web_content_connection().find_element(move(payload)); - }); -} - -Web::WebDriver::Response Session::find_elements(JsonValue payload) const -{ - return perform_async_action(web_content_connection().on_find_elements_complete, [&]() { - return web_content_connection().find_elements(move(payload)); - }); -} - -Web::WebDriver::Response Session::find_element_from_element(String element_id, JsonValue payload) const -{ - return perform_async_action(web_content_connection().on_find_elements_complete, [&]() { - return web_content_connection().find_element_from_element(move(payload), move(element_id)); - }); -} - -Web::WebDriver::Response Session::find_elements_from_element(String element_id, JsonValue payload) const -{ - return perform_async_action(web_content_connection().on_find_elements_complete, [&]() { - return web_content_connection().find_elements_from_element(move(payload), move(element_id)); - }); -} - -Web::WebDriver::Response Session::find_element_from_shadow_root(String shadow_id, JsonValue payload) const -{ - return perform_async_action(web_content_connection().on_find_elements_complete, [&]() { - return web_content_connection().find_element_from_shadow_root(move(payload), move(shadow_id)); - }); -} - -Web::WebDriver::Response Session::find_elements_from_shadow_root(String shadow_id, JsonValue payload) const -{ - return perform_async_action(web_content_connection().on_find_elements_complete, [&]() { - return web_content_connection().find_elements_from_shadow_root(move(payload), move(shadow_id)); - }); -} - -Web::WebDriver::Response Session::execute_script(JsonValue payload, ScriptMode mode) const -{ - return perform_async_action(web_content_connection().on_script_executed, [&]() { - switch (mode) { - case ScriptMode::Sync: - return web_content_connection().execute_script(move(payload)); - case ScriptMode::Async: - return web_content_connection().execute_async_script(move(payload)); - } - VERIFY_NOT_REACHED(); - }); -} - -Web::WebDriver::Response Session::element_click(String element_id) const -{ - return perform_async_action(web_content_connection().on_actions_performed, [&]() { - return web_content_connection().element_click(move(element_id)); - }); -} - -Web::WebDriver::Response Session::element_send_keys(String element_id, JsonValue payload) const -{ - return perform_async_action(web_content_connection().on_actions_performed, [&]() { - return web_content_connection().element_send_keys(move(element_id), move(payload)); - }); -} - -Web::WebDriver::Response Session::perform_actions(JsonValue payload) const -{ - return perform_async_action(web_content_connection().on_actions_performed, [&]() { - return web_content_connection().perform_actions(move(payload)); - }); -} - -Web::WebDriver::Response Session::dismiss_alert() const -{ - return perform_async_action(web_content_connection().on_dialog_closed, [&]() { - return web_content_connection().dismiss_alert(); - }); -} - -Web::WebDriver::Response Session::accept_alert() const -{ - return perform_async_action(web_content_connection().on_dialog_closed, [&]() { - return web_content_connection().accept_alert(); - }); -} - -Web::WebDriver::Response Session::take_screenshot() const -{ - return perform_async_action(web_content_connection().on_screenshot_taken, [&]() { - return web_content_connection().take_screenshot(); - }); -} - -Web::WebDriver::Response Session::take_element_screenshot(String element_id) const -{ - return perform_async_action(web_content_connection().on_screenshot_taken, [&]() { - return web_content_connection().take_element_screenshot(move(element_id)); - }); -} - } diff --git a/Userland/Services/WebDriver/Session.h b/Userland/Services/WebDriver/Session.h index 8f784be8380..c0b00d80f64 100644 --- a/Userland/Services/WebDriver/Session.h +++ b/Userland/Services/WebDriver/Session.h @@ -9,12 +9,12 @@ #pragma once #include -#include #include #include +#include #include +#include #include -#include #include #include #include @@ -57,35 +57,23 @@ public: Web::WebDriver::Response get_window_handles() const; ErrorOr ensure_current_window_handle_is_valid() const; - Web::WebDriver::Response navigate_to(JsonValue) const; + template + Web::WebDriver::Response perform_async_action(Action&& action) + { + Optional response; + auto& connection = web_content_connection(); - enum class ScriptMode { - Sync, - Async, - }; - Web::WebDriver::Response execute_script(JsonValue, ScriptMode) const; + ScopeGuard guard { [&]() { connection.on_driver_execution_complete = nullptr; } }; + connection.on_driver_execution_complete = [&](auto result) { response = move(result); }; - Web::WebDriver::Response set_window_rect(JsonValue) const; - Web::WebDriver::Response maximize_window() const; - Web::WebDriver::Response minimize_window() const; - Web::WebDriver::Response fullscreen_window() const; + TRY(action(connection)); - Web::WebDriver::Response find_element(JsonValue) const; - Web::WebDriver::Response find_elements(JsonValue) const; - Web::WebDriver::Response find_element_from_element(String, JsonValue) const; - Web::WebDriver::Response find_elements_from_element(String, JsonValue) const; - Web::WebDriver::Response find_element_from_shadow_root(String, JsonValue) const; - Web::WebDriver::Response find_elements_from_shadow_root(String, JsonValue) const; + Core::EventLoop::current().spin_until([&]() { + return response.has_value(); + }); - Web::WebDriver::Response element_click(String) const; - Web::WebDriver::Response element_send_keys(String, JsonValue) const; - Web::WebDriver::Response perform_actions(JsonValue) const; - - Web::WebDriver::Response dismiss_alert() const; - Web::WebDriver::Response accept_alert() const; - - Web::WebDriver::Response take_screenshot() const; - Web::WebDriver::Response take_element_screenshot(String) const; + return response.release_value(); + } private: using ServerPromise = Core::Promise>; diff --git a/Userland/Services/WebDriver/WebContentConnection.cpp b/Userland/Services/WebDriver/WebContentConnection.cpp index 99e3316057b..a306399e70c 100644 --- a/Userland/Services/WebDriver/WebContentConnection.cpp +++ b/Userland/Services/WebDriver/WebContentConnection.cpp @@ -20,46 +20,10 @@ void WebContentConnection::die() on_close(); } -void WebContentConnection::navigation_complete(Web::WebDriver::Response const& response) +void WebContentConnection::driver_execution_complete(Web::WebDriver::Response const& response) { - if (on_navigation_complete) - on_navigation_complete(response); -} - -void WebContentConnection::window_rect_updated(Web::WebDriver::Response const& response) -{ - if (on_window_rect_updated) - on_window_rect_updated(response); -} - -void WebContentConnection::find_elements_complete(Web::WebDriver::Response const& response) -{ - if (on_find_elements_complete) - on_find_elements_complete(response); -} - -void WebContentConnection::script_executed(Web::WebDriver::Response const& response) -{ - if (on_script_executed) - on_script_executed(response); -} - -void WebContentConnection::actions_performed(Web::WebDriver::Response const& response) -{ - if (on_actions_performed) - on_actions_performed(response); -} - -void WebContentConnection::dialog_closed(Web::WebDriver::Response const& response) -{ - if (on_dialog_closed) - on_dialog_closed(response); -} - -void WebContentConnection::screenshot_taken(Web::WebDriver::Response const& response) -{ - if (on_screenshot_taken) - on_screenshot_taken(response); + if (on_driver_execution_complete) + on_driver_execution_complete(response); } } diff --git a/Userland/Services/WebDriver/WebContentConnection.h b/Userland/Services/WebDriver/WebContentConnection.h index 893c211d13d..7b2f7cf5d84 100644 --- a/Userland/Services/WebDriver/WebContentConnection.h +++ b/Userland/Services/WebDriver/WebContentConnection.h @@ -22,24 +22,12 @@ public: explicit WebContentConnection(IPC::Transport transport); Function on_close; - Function on_navigation_complete; - Function on_window_rect_updated; - Function on_find_elements_complete; - Function on_script_executed; - Function on_actions_performed; - Function on_dialog_closed; - Function on_screenshot_taken; + Function on_driver_execution_complete; private: virtual void die() override; - virtual void navigation_complete(Web::WebDriver::Response const&) override; - virtual void window_rect_updated(Web::WebDriver::Response const&) override; - virtual void find_elements_complete(Web::WebDriver::Response const&) override; - virtual void script_executed(Web::WebDriver::Response const&) override; - virtual void actions_performed(Web::WebDriver::Response const&) override; - virtual void dialog_closed(Web::WebDriver::Response const&) override; - virtual void screenshot_taken(Web::WebDriver::Response const&) override; + virtual void driver_execution_complete(Web::WebDriver::Response const&) override; }; }