mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-25 09:00:22 +00:00
WebContent+WebDriver: Consolidate driver execution completion callbacks
Some WebDriver hooks will need to inform the client that execution has completed, but without any knowledge of what endpoint was running. Since there can only ever be a single WebDriver endpoint executing at once, we can replace the completion callbacks with a single callback.
This commit is contained in:
parent
1be67faab7
commit
9dc1302768
Notes:
github-actions[bot]
2024-11-02 10:10:43 +00:00
Author: https://github.com/trflynn89 Commit: https://github.com/LadybirdBrowser/ladybird/commit/9dc13027687 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2100
7 changed files with 126 additions and 289 deletions
|
@ -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<int>()));
|
||||
async_driver_execution_complete(serialize_rect(rect.to_type<int>()));
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -2553,7 +2553,7 @@ void WebDriverConnection::page_did_open_dialog(Badge<PageClient>)
|
|||
// [[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 {});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
#include <LibWeb/WebDriver/Response.h>
|
||||
|
||||
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) =|
|
||||
}
|
||||
|
|
|
@ -241,7 +241,10 @@ Web::WebDriver::Response Client::navigate_to(Web::WebDriver::Parameters paramete
|
|||
{
|
||||
dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/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/<session_id>/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/<session_id>/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/<session_id>/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/<session_id>/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/<session_id>/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/<session_id>/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/<session_id>/element/<element_id>/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/<session_id>/element/<element_id>/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/<session_id>/shadow/<shadow_id>/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/<session_id>/shadow/<shadow_id>/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/<session_id>/element/<element_id>/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/<session_id>/element/<element_id>/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/<session_id>/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/<session_id>/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/<session_id>/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/<session_id>/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/<session_id>/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/<session_id>/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/<session_id>/element/<element_id>/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
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
#include "Session.h"
|
||||
#include "Client.h"
|
||||
#include <AK/JsonObject.h>
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <AK/JsonValue.h>
|
||||
#include <LibCore/LocalServer.h>
|
||||
#include <LibCore/StandardPaths.h>
|
||||
#include <LibCore/System.h>
|
||||
|
@ -185,160 +184,4 @@ ErrorOr<void, Web::WebDriver::Error> Session::ensure_current_window_handle_is_va
|
|||
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchWindow, "Window not found"sv);
|
||||
}
|
||||
|
||||
template<typename Handler, typename Action>
|
||||
static Web::WebDriver::Response perform_async_action(Handler& handler, Action&& action)
|
||||
{
|
||||
Optional<Web::WebDriver::Response> 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));
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Error.h>
|
||||
#include <AK/JsonValue.h>
|
||||
#include <AK/RefCounted.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/ScopeGuard.h>
|
||||
#include <AK/String.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/Promise.h>
|
||||
#include <LibWeb/WebDriver/Capabilities.h>
|
||||
#include <LibWeb/WebDriver/Error.h>
|
||||
#include <LibWeb/WebDriver/Response.h>
|
||||
#include <WebDriver/WebContentConnection.h>
|
||||
|
@ -57,35 +57,23 @@ public:
|
|||
Web::WebDriver::Response get_window_handles() const;
|
||||
ErrorOr<void, Web::WebDriver::Error> ensure_current_window_handle_is_valid() const;
|
||||
|
||||
Web::WebDriver::Response navigate_to(JsonValue) const;
|
||||
template<typename Action>
|
||||
Web::WebDriver::Response perform_async_action(Action&& action)
|
||||
{
|
||||
Optional<Web::WebDriver::Response> 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<ErrorOr<void>>;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -22,24 +22,12 @@ public:
|
|||
explicit WebContentConnection(IPC::Transport transport);
|
||||
|
||||
Function<void()> on_close;
|
||||
Function<void(Web::WebDriver::Response)> on_navigation_complete;
|
||||
Function<void(Web::WebDriver::Response)> on_window_rect_updated;
|
||||
Function<void(Web::WebDriver::Response)> on_find_elements_complete;
|
||||
Function<void(Web::WebDriver::Response)> on_script_executed;
|
||||
Function<void(Web::WebDriver::Response)> on_actions_performed;
|
||||
Function<void(Web::WebDriver::Response)> on_dialog_closed;
|
||||
Function<void(Web::WebDriver::Response)> on_screenshot_taken;
|
||||
Function<void(Web::WebDriver::Response)> 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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue