WebContent+WebDriver: Convert all user prompt handlers to be async

Making these async were all actually pretty trivial. This patch does so,
and removes the deprecated synchronous user prompt handler.
This commit is contained in:
Timothy Flynn 2024-11-03 09:39:18 -05:00 committed by Andreas Kling
commit 3da20aca65
Notes: github-actions[bot] 2024-11-03 21:12:10 +00:00
4 changed files with 510 additions and 385 deletions

View file

@ -344,13 +344,15 @@ Messages::WebDriverClient::GetCurrentUrlResponse WebDriverConnection::get_curren
TRY(ensure_current_top_level_browsing_context_is_open()); TRY(ensure_current_top_level_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 3. Let url be the serialization of the current top-level browsing contexts active documents document URL. // 3. Let url be the serialization of the current top-level browsing contexts active documents document URL.
auto url = current_top_level_browsing_context()->active_document()->url().to_byte_string(); auto url = current_top_level_browsing_context()->active_document()->url();
// 4. Return success with data url. // 4. Return success with data url.
return url; async_driver_execution_complete({ url.to_byte_string() });
});
return JsonValue {};
} }
// 10.3 Back, https://w3c.github.io/webdriver/#dfn-back // 10.3 Back, https://w3c.github.io/webdriver/#dfn-back
@ -360,8 +362,7 @@ Messages::WebDriverClient::BackResponse WebDriverConnection::back()
TRY(ensure_current_top_level_browsing_context_is_open()); TRY(ensure_current_top_level_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 3. Traverse the history by a delta 1 for the current browsing context. // 3. Traverse the history by a delta 1 for the current browsing context.
current_browsing_context().page().client().page_did_request_navigate_back(); current_browsing_context().page().client().page_did_request_navigate_back();
@ -369,6 +370,9 @@ Messages::WebDriverClient::BackResponse WebDriverConnection::back()
// FIXME: 5. If the previous step completed by the session page load timeout being reached, and user prompts have been handled, return error with error code timeout. // FIXME: 5. If the previous step completed by the session page load timeout being reached, and user prompts have been handled, return error with error code timeout.
// 6. Return success with data null. // 6. Return success with data null.
async_driver_execution_complete(JsonValue {});
});
return JsonValue {}; return JsonValue {};
} }
@ -379,8 +383,7 @@ Messages::WebDriverClient::ForwardResponse WebDriverConnection::forward()
TRY(ensure_current_top_level_browsing_context_is_open()); TRY(ensure_current_top_level_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 3. Traverse the history by a delta 1 for the current browsing context. // 3. Traverse the history by a delta 1 for the current browsing context.
current_browsing_context().page().client().page_did_request_navigate_forward(); current_browsing_context().page().client().page_did_request_navigate_forward();
@ -388,6 +391,9 @@ Messages::WebDriverClient::ForwardResponse WebDriverConnection::forward()
// FIXME: 5. If the previous step completed by the session page load timeout being reached, and user prompts have been handled, return error with error code timeout. // FIXME: 5. If the previous step completed by the session page load timeout being reached, and user prompts have been handled, return error with error code timeout.
// 6. Return success with data null. // 6. Return success with data null.
async_driver_execution_complete(JsonValue {});
});
return JsonValue {}; return JsonValue {};
} }
@ -398,8 +404,7 @@ Messages::WebDriverClient::RefreshResponse WebDriverConnection::refresh()
TRY(ensure_current_top_level_browsing_context_is_open()); TRY(ensure_current_top_level_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 3. Initiate an overridden reload of the current top-level browsing contexts active document. // 3. Initiate an overridden reload of the current top-level browsing contexts active document.
current_top_level_browsing_context()->page().client().page_did_request_refresh(); current_top_level_browsing_context()->page().client().page_did_request_refresh();
@ -411,6 +416,9 @@ Messages::WebDriverClient::RefreshResponse WebDriverConnection::refresh()
set_current_browsing_context(*current_top_level_browsing_context()); set_current_browsing_context(*current_top_level_browsing_context());
// 6. Return success with data null. // 6. Return success with data null.
async_driver_execution_complete(JsonValue {});
});
return JsonValue {}; return JsonValue {};
} }
@ -421,13 +429,15 @@ Messages::WebDriverClient::GetTitleResponse WebDriverConnection::get_title()
TRY(ensure_current_top_level_browsing_context_is_open()); TRY(ensure_current_top_level_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 3. Let title be the initial value of the title IDL attribute of the current top-level browsing context's active document. // 3. Let title be the initial value of the title IDL attribute of the current top-level browsing context's active document.
auto title = current_top_level_browsing_context()->active_document()->title(); auto title = current_top_level_browsing_context()->active_document()->title();
// 4. Return success with data title. // 4. Return success with data title.
return title.to_byte_string(); async_driver_execution_complete({ title.to_byte_string() });
});
return JsonValue {};
} }
// 11.1 Get Window Handle, https://w3c.github.io/webdriver/#get-window-handle // 11.1 Get Window Handle, https://w3c.github.io/webdriver/#get-window-handle
@ -447,11 +457,13 @@ Messages::WebDriverClient::CloseWindowResponse WebDriverConnection::close_window
TRY(ensure_current_top_level_browsing_context_is_open()); TRY(ensure_current_top_level_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 3. Close the current top-level browsing context. // 3. Close the current top-level browsing context.
current_top_level_browsing_context()->top_level_traversable()->close_top_level_traversable(); current_top_level_browsing_context()->top_level_traversable()->close_top_level_traversable();
async_driver_execution_complete(JsonValue {});
});
return JsonValue {}; return JsonValue {};
} }
@ -495,16 +507,19 @@ Messages::WebDriverClient::NewWindowResponse WebDriverConnection::new_window(Jso
TRY(ensure_current_top_level_browsing_context_is_open()); TRY(ensure_current_top_level_browsing_context_is_open());
// 3. Handle any user prompts and return its value if it is an error. // 3. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, payload = move(const_cast<JsonValue&>(payload))]() {
// 4. Let type hint be the result of getting the property "type" from the parameters argument. // 4. Let type hint be the result of getting the property "type" from the parameters argument.
if (!payload.is_object()) if (!payload.is_object()) {
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload is not a JSON object"); async_driver_execution_complete(Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload is not a JSON object"));
return;
}
// FIXME: Actually use this value to decide between an OS window or tab. // FIXME: Actually use this value to decide between an OS window or tab.
auto type_hint = payload.as_object().get("type"sv); auto type_hint = payload.as_object().get("type"sv);
if (type_hint.has_value() && !type_hint->is_null() && !type_hint->is_string()) if (type_hint.has_value() && !type_hint->is_null() && !type_hint->is_string()) {
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload property `type` is not null or a string"sv); async_driver_execution_complete(Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload property `type` is not null or a string"sv));
return;
}
// 5. Create a new top-level browsing context by running the window open steps with url set to "about:blank", // 5. Create a new top-level browsing context by running the window open steps with url set to "about:blank",
// target set to the empty string, and features set to "noopener" and the user agent configured to create a new // target set to the empty string, and features set to "noopener" and the user agent configured to create a new
@ -532,7 +547,10 @@ Messages::WebDriverClient::NewWindowResponse WebDriverConnection::new_window(Jso
result.set("type"sv, JsonValue { type }); result.set("type"sv, JsonValue { type });
// 9. Return success with data result. // 9. Return success with data result.
return result; async_driver_execution_complete({ move(result) });
});
return JsonValue {};
} }
// 11.6 Switch To Frame, https://w3c.github.io/webdriver/#dfn-switch-to-frame // 11.6 Switch To Frame, https://w3c.github.io/webdriver/#dfn-switch-to-frame
@ -556,10 +574,12 @@ Messages::WebDriverClient::SwitchToFrameResponse WebDriverConnection::switch_to_
TRY(ensure_current_top_level_browsing_context_is_open()); TRY(ensure_current_top_level_browsing_context_is_open());
// 2. Try to handle any user prompts with session. // 2. Try to handle any user prompts with session.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 3. Set the current browsing context with session and session's current top-level browsing context. // 3. Set the current browsing context with session and session's current top-level browsing context.
set_current_browsing_context(*current_top_level_browsing_context()); set_current_browsing_context(*current_top_level_browsing_context());
async_driver_execution_complete(JsonValue {});
});
} }
// -> id is a Number object // -> id is a Number object
@ -572,6 +592,7 @@ Messages::WebDriverClient::SwitchToFrameResponse WebDriverConnection::switch_to_
// FIXME: 6. Let child window be the WindowProxy object obtained by calling window.[[GetOwnProperty]] (id). // FIXME: 6. Let child window be the WindowProxy object obtained by calling window.[[GetOwnProperty]] (id).
// FIXME: 7. Set the current browsing context with session and child window's browsing context. // FIXME: 7. Set the current browsing context with session and child window's browsing context.
dbgln("FIXME: WebDriverConnection::switch_to_frame(id={})", id); dbgln("FIXME: WebDriverConnection::switch_to_frame(id={})", id);
async_driver_execution_complete(JsonValue {});
} }
// -> id represents a web element // -> id represents a web element
@ -582,17 +603,18 @@ Messages::WebDriverClient::SwitchToFrameResponse WebDriverConnection::switch_to_
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Try to handle any user prompts with session. // 2. Try to handle any user prompts with session.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id = move(element_id)]() {
// 3. Let element be the result of trying to get a known element with session and id. // 3. Let element be the result of trying to get a known element with session and id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
// 4. If element is not a frame or iframe element, return error with error code no such frame. // 4. If element is not a frame or iframe element, return error with error code no such frame.
bool is_frame = is<Web::HTML::HTMLFrameElement>(*element); bool is_frame = is<Web::HTML::HTMLFrameElement>(*element);
bool is_iframe = is<Web::HTML::HTMLIFrameElement>(*element); bool is_iframe = is<Web::HTML::HTMLIFrameElement>(*element);
if (!is_frame && !is_iframe) if (!is_frame && !is_iframe) {
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchFrame, "element is not a frame"sv); async_driver_execution_complete(Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchFrame, "element is not a frame"sv));
return;
}
// 5. Set the current browsing context with session and element's content navigable's active browsing context. // 5. Set the current browsing context with session and element's content navigable's active browsing context.
if (is_frame) { if (is_frame) {
@ -602,6 +624,9 @@ Messages::WebDriverClient::SwitchToFrameResponse WebDriverConnection::switch_to_
auto& navigable_container = static_cast<Web::HTML::NavigableContainer&>(*element); auto& navigable_container = static_cast<Web::HTML::NavigableContainer&>(*element);
set_current_browsing_context(*navigable_container.content_navigable()->active_browsing_context()); set_current_browsing_context(*navigable_container.content_navigable()->active_browsing_context());
} }
async_driver_execution_complete(JsonValue {});
});
} }
// FIXME: 4. Update any implementation-specific state that would result from the user selecting session's current browsing context for interaction, without altering OS-level focus. // FIXME: 4. Update any implementation-specific state that would result from the user selecting session's current browsing context for interaction, without altering OS-level focus.
@ -622,22 +647,22 @@ Messages::WebDriverClient::SwitchToParentFrameResponse WebDriverConnection::swit
return JsonValue {}; return JsonValue {};
} }
auto parent_browsing_context = current_parent_browsing_context();
// 2. If session's current parent browsing context is no longer open, return error with error code no such window. // 2. If session's current parent browsing context is no longer open, return error with error code no such window.
TRY(ensure_browsing_context_is_open(parent_browsing_context)); TRY(ensure_browsing_context_is_open(current_parent_browsing_context()));
// 3. Try to handle any user prompts with session. // 3. Try to handle any user prompts with session.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 4. If session's current parent browsing context is not null, set the current browsing context with session and // 4. If session's current parent browsing context is not null, set the current browsing context with session and
// current parent browsing context. // current parent browsing context.
if (parent_browsing_context) if (auto parent_browsing_context = current_parent_browsing_context())
set_current_browsing_context(*current_parent_browsing_context()); set_current_browsing_context(*parent_browsing_context);
// FIXME: 5. Update any implementation-specific state that would result from the user selecting session's current browsing context for interaction, without altering OS-level focus. // FIXME: 5. Update any implementation-specific state that would result from the user selecting session's current browsing context for interaction, without altering OS-level focus.
// 6. Return success with data null. // 6. Return success with data null.
async_driver_execution_complete(JsonValue {});
});
return JsonValue {}; return JsonValue {};
} }
@ -648,10 +673,13 @@ Messages::WebDriverClient::GetWindowRectResponse WebDriverConnection::get_window
TRY(ensure_current_top_level_browsing_context_is_open()); TRY(ensure_current_top_level_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 3. Return success with data set to the WindowRect object for the current top-level browsing context. // 3. Return success with data set to the WindowRect object for the current top-level browsing context.
return serialize_rect(compute_window_rect(current_top_level_browsing_context()->page())); auto serialized_rect = serialize_rect(compute_window_rect(current_top_level_browsing_context()->page()));
async_driver_execution_complete(move(serialized_rect));
});
return JsonValue {};
} }
// 11.8.2 Set Window Rect, https://w3c.github.io/webdriver/#dfn-set-window-rect // 11.8.2 Set Window Rect, https://w3c.github.io/webdriver/#dfn-set-window-rect
@ -1064,17 +1092,22 @@ Messages::WebDriverClient::GetActiveElementResponse WebDriverConnection::get_act
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 3. Let active element be the active element of the current browsing contexts document element. // 3. Let active element be the active element of the current browsing contexts document element.
auto* active_element = current_browsing_context().active_document()->active_element(); auto const* active_element = current_browsing_context().active_document()->active_element();
// 4. If active element is a non-null element, return success with data set to web element reference object for active element. // 4. If active element is a non-null element, return success with data set to web element reference object for active element.
// Otherwise, return error with error code no such element. // Otherwise, return error with error code no such element.
if (active_element) if (active_element) {
return ByteString::number(active_element->unique_id().value()); auto serialized = Web::WebDriver::web_element_reference_object(current_browsing_context(), *active_element);
async_driver_execution_complete({ move(serialized) });
return;
}
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchElement, "The current document does not have an active element"sv); async_driver_execution_complete(Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchElement, "The current document does not have an active element"sv));
});
return JsonValue {};
} }
// 12.3.9 Get Element Shadow Root, https://w3c.github.io/webdriver/#get-element-shadow-root // 12.3.9 Get Element Shadow Root, https://w3c.github.io/webdriver/#get-element-shadow-root
@ -1084,23 +1117,27 @@ Messages::WebDriverClient::GetElementShadowRootResponse WebDriverConnection::get
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id]() {
// 3. Let element be the result of trying to get a known element with session and URL variables[element id]. // 3. Let element be the result of trying to get a known element with session and URL variables[element id].
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
// 4. Let shadow root be element's shadow root. // 4. Let shadow root be element's shadow root.
auto shadow_root = element->shadow_root(); auto shadow_root = element->shadow_root();
// 5. If shadow root is null, return error with error code no such shadow root. // 5. If shadow root is null, return error with error code no such shadow root.
if (!shadow_root) if (!shadow_root) {
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchShadowRoot, ByteString::formatted("Element with ID '{}' does not have a shadow root", element_id)); async_driver_execution_complete(Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchShadowRoot, ByteString::formatted("Element with ID '{}' does not have a shadow root", element_id)));
return;
}
// 6. Let serialized be the shadow root reference object for session and shadow root. // 6. Let serialized be the shadow root reference object for session and shadow root.
auto serialized = Web::WebDriver::shadow_root_reference_object(current_browsing_context(), *shadow_root); auto serialized = Web::WebDriver::shadow_root_reference_object(current_browsing_context(), *shadow_root);
// 7. Return success with data serialized. // 7. Return success with data serialized.
return serialized; async_driver_execution_complete({ move(serialized) });
});
return JsonValue {};
} }
// 12.4.1 Is Element Selected, https://w3c.github.io/webdriver/#dfn-is-element-selected // 12.4.1 Is Element Selected, https://w3c.github.io/webdriver/#dfn-is-element-selected
@ -1110,10 +1147,9 @@ Messages::WebDriverClient::IsElementSelectedResponse WebDriverConnection::is_ele
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id]() {
// 3. Let element be the result of trying to get a known connected element with url variable element id. // 3. Let element be the result of trying to get a known connected element with url variable element id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
// 4. Let selected be the value corresponding to the first matching statement: // 4. Let selected be the value corresponding to the first matching statement:
bool selected = false; bool selected = false;
@ -1136,7 +1172,10 @@ Messages::WebDriverClient::IsElementSelectedResponse WebDriverConnection::is_ele
// -> False. // -> False.
// 5. Return success with data selected. // 5. Return success with data selected.
return selected; async_driver_execution_complete({ selected });
});
return JsonValue {};
} }
// 12.4.2 Get Element Attribute, https://w3c.github.io/webdriver/#dfn-get-element-attribute // 12.4.2 Get Element Attribute, https://w3c.github.io/webdriver/#dfn-get-element-attribute
@ -1146,10 +1185,9 @@ Messages::WebDriverClient::GetElementAttributeResponse WebDriverConnection::get_
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id, name]() {
// 3. Let element be the result of trying to get a known connected element with url variable element id. // 3. Let element be the result of trying to get a known connected element with url variable element id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
// 4. Let result be the result of the first matching condition: // 4. Let result be the result of the first matching condition:
Optional<ByteString> result; Optional<ByteString> result;
@ -1168,8 +1206,13 @@ Messages::WebDriverClient::GetElementAttributeResponse WebDriverConnection::get_
} }
// 5. Return success with data result. // 5. Return success with data result.
if (result.has_value()) if (result.has_value()) {
return result.release_value(); async_driver_execution_complete({ result.release_value() });
return;
}
async_driver_execution_complete(JsonValue {});
});
return JsonValue {}; return JsonValue {};
} }
@ -1180,10 +1223,9 @@ Messages::WebDriverClient::GetElementPropertyResponse WebDriverConnection::get_e
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id, name]() {
// 3. Let element be the result of trying to get a known connected element with url variable element id. // 3. Let element be the result of trying to get a known connected element with url variable element id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
Optional<ByteString> result; Optional<ByteString> result;
@ -1201,8 +1243,13 @@ Messages::WebDriverClient::GetElementPropertyResponse WebDriverConnection::get_e
} }
// 6. Return success with data result. // 6. Return success with data result.
if (result.has_value()) if (result.has_value()) {
return result.release_value(); async_driver_execution_complete({ result.release_value() });
return;
}
async_driver_execution_complete(JsonValue {});
});
return JsonValue {}; return JsonValue {};
} }
@ -1213,10 +1260,9 @@ Messages::WebDriverClient::GetElementCssValueResponse WebDriverConnection::get_e
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id, name]() {
// 3. Let element be the result of trying to get a known connected element with url variable element id. // 3. Let element be the result of trying to get a known connected element with url variable element id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
// 4. Let computed value be the result of the first matching condition: // 4. Let computed value be the result of the first matching condition:
ByteString computed_value; ByteString computed_value;
@ -1236,7 +1282,10 @@ Messages::WebDriverClient::GetElementCssValueResponse WebDriverConnection::get_e
} }
// 5. Return success with data computed value. // 5. Return success with data computed value.
return computed_value; async_driver_execution_complete({ computed_value });
});
return JsonValue {};
} }
// 12.4.5 Get Element Text, https://w3c.github.io/webdriver/#dfn-get-element-text // 12.4.5 Get Element Text, https://w3c.github.io/webdriver/#dfn-get-element-text
@ -1246,16 +1295,18 @@ Messages::WebDriverClient::GetElementTextResponse WebDriverConnection::get_eleme
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id]() {
// 3. Let element be the result of trying to get a known connected element with url variable element id. // 3. Let element be the result of trying to get a known connected element with url variable element id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
// 4. Let rendered text be the result of performing implementation-specific steps whose result is exactly the same as the result of a Function.[[Call]](null, element) with bot.dom.getVisibleText as the this value. // 4. Let rendered text be the result of performing implementation-specific steps whose result is exactly the same as the result of a Function.[[Call]](null, element) with bot.dom.getVisibleText as the this value.
auto rendered_text = element->text_content(); auto rendered_text = element->text_content();
// 5. Return success with data rendered text. // 5. Return success with data rendered text.
return rendered_text.value_or(String {}).to_byte_string(); async_driver_execution_complete({ rendered_text.value_or(String {}).to_byte_string() });
});
return JsonValue {};
} }
// 12.4.6 Get Element Tag Name, https://w3c.github.io/webdriver/#dfn-get-element-tag-name // 12.4.6 Get Element Tag Name, https://w3c.github.io/webdriver/#dfn-get-element-tag-name
@ -1265,16 +1316,18 @@ Messages::WebDriverClient::GetElementTagNameResponse WebDriverConnection::get_el
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id]() {
// 3. Let element be the result of trying to get a known connected element with url variable element id. // 3. Let element be the result of trying to get a known connected element with url variable element id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
// 4. Let qualified name be the result of getting elements tagName IDL attribute. // 4. Let qualified name be the result of getting elements tagName IDL attribute.
auto qualified_name = element->tag_name(); auto qualified_name = element->tag_name();
// 5. Return success with data qualified name. // 5. Return success with data qualified name.
return MUST(JsonValue::from_string(qualified_name)); async_driver_execution_complete({ qualified_name.to_string().to_byte_string() });
});
return JsonValue {};
} }
// 12.4.7 Get Element Rect, https://w3c.github.io/webdriver/#dfn-get-element-rect // 12.4.7 Get Element Rect, https://w3c.github.io/webdriver/#dfn-get-element-rect
@ -1284,10 +1337,9 @@ Messages::WebDriverClient::GetElementRectResponse WebDriverConnection::get_eleme
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id]() {
// 3. Let element be the result of trying to get a known connected element with url variable element id. // 3. Let element be the result of trying to get a known connected element with url variable element id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
// 4. Calculate the absolute position of element and let it be coordinates. // 4. Calculate the absolute position of element and let it be coordinates.
// 5. Let rect be elements bounding rectangle. // 5. Let rect be elements bounding rectangle.
@ -1305,7 +1357,10 @@ Messages::WebDriverClient::GetElementRectResponse WebDriverConnection::get_eleme
auto body = serialize_rect(rect); auto body = serialize_rect(rect);
// 7. Return success with data body. // 7. Return success with data body.
return body; async_driver_execution_complete(move(body));
});
return JsonValue {};
} }
// 12.4.8 Is Element Enabled, https://w3c.github.io/webdriver/#dfn-is-element-enabled // 12.4.8 Is Element Enabled, https://w3c.github.io/webdriver/#dfn-is-element-enabled
@ -1315,10 +1370,9 @@ Messages::WebDriverClient::IsElementEnabledResponse WebDriverConnection::is_elem
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id]() {
// 3. Let element be the result of trying to get a known connected element with url variable element id. // 3. Let element be the result of trying to get a known connected element with url variable element id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
// 4. Let enabled be a boolean initially set to true if the current browsing contexts active documents type is not "xml". // 4. Let enabled be a boolean initially set to true if the current browsing contexts active documents type is not "xml".
// 5. Otherwise, let enabled to false and jump to the last step of this algorithm. // 5. Otherwise, let enabled to false and jump to the last step of this algorithm.
@ -1331,7 +1385,10 @@ Messages::WebDriverClient::IsElementEnabledResponse WebDriverConnection::is_elem
} }
// 7. Return success with data enabled. // 7. Return success with data enabled.
return enabled; async_driver_execution_complete({ enabled });
});
return JsonValue {};
} }
// 12.4.9 Get Computed Role, https://w3c.github.io/webdriver/#dfn-get-computed-role // 12.4.9 Get Computed Role, https://w3c.github.io/webdriver/#dfn-get-computed-role
@ -1341,18 +1398,22 @@ Messages::WebDriverClient::GetComputedRoleResponse WebDriverConnection::get_comp
TRY(ensure_current_top_level_browsing_context_is_open()); TRY(ensure_current_top_level_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id]() {
// 3. Let element be the result of trying to get a known connected element with url variable element id. // 3. Let element be the result of trying to get a known connected element with url variable element id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
// 4. Let role be the result of computing the WAI-ARIA role of element. // 4. Let role be the result of computing the WAI-ARIA role of element.
auto role = element->role_or_default(); auto role = element->role_or_default();
// 5. Return success with data role. // 5. Return success with data role.
if (role.has_value()) if (role.has_value()) {
return Web::ARIA::role_name(*role); async_driver_execution_complete({ Web::ARIA::role_name(*role) });
return ""sv; return;
}
async_driver_execution_complete(JsonValue {});
});
return JsonValue {};
} }
// 12.4.10 Get Computed Label, https://w3c.github.io/webdriver/#get-computed-label // 12.4.10 Get Computed Label, https://w3c.github.io/webdriver/#get-computed-label
@ -1362,16 +1423,18 @@ Messages::WebDriverClient::GetComputedLabelResponse WebDriverConnection::get_com
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, element_id]() {
// 3. Let element be the result of trying to get a known element with url variable element id. // 3. Let element be the result of trying to get a known element with url variable element id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = WEBDRIVER_TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
// 4. Let label be the result of a Accessible Name and Description Computation for the Accessible Name of the element. // 4. Let label be the result of a Accessible Name and Description Computation for the Accessible Name of the element.
auto label = element->accessible_name(element->document()).release_value_but_fixme_should_propagate_errors(); auto label = element->accessible_name(element->document()).release_value_but_fixme_should_propagate_errors();
// 5. Return success with data label. // 5. Return success with data label.
return label.to_byte_string(); async_driver_execution_complete({ label.to_byte_string() });
});
return JsonValue {};
} }
// 12.5.1 Element Click, https://w3c.github.io/webdriver/#element-click // 12.5.1 Element Click, https://w3c.github.io/webdriver/#element-click
@ -1557,6 +1620,19 @@ Web::WebDriver::Response WebDriverConnection::element_click_impl(String const& e
// 12.5.2 Element Clear, https://w3c.github.io/webdriver/#dfn-element-clear // 12.5.2 Element Clear, https://w3c.github.io/webdriver/#dfn-element-clear
Messages::WebDriverClient::ElementClearResponse WebDriverConnection::element_clear(String const& element_id) Messages::WebDriverClient::ElementClearResponse WebDriverConnection::element_clear(String const& element_id)
{
// 1. If session's current browsing context is no longer open, return error with error code no such window.
TRY(ensure_current_browsing_context_is_open());
// 2. Try to handle any user prompts with session.
handle_any_user_prompts([this, element_id]() {
async_driver_execution_complete(element_clear_impl(element_id));
});
return JsonValue {};
}
Web::WebDriver::Response WebDriverConnection::element_clear_impl(String const& element_id)
{ {
// https://w3c.github.io/webdriver/#dfn-clear-a-content-editable-element // https://w3c.github.io/webdriver/#dfn-clear-a-content-editable-element
auto clear_content_editable_element = [&](Web::DOM::Element& element) { auto clear_content_editable_element = [&](Web::DOM::Element& element) {
@ -1611,12 +1687,6 @@ Messages::WebDriverClient::ElementClearResponse WebDriverConnection::element_cle
Web::HTML::run_unfocusing_steps(&element); Web::HTML::run_unfocusing_steps(&element);
}; };
// 1. If session's current browsing context is no longer open, return error with error code no such window.
TRY(ensure_current_browsing_context_is_open());
// 2. Try to handle any user prompts with session.
TRY(deprecated_handle_any_user_prompts());
// 3. Let element be the result of trying to get a known element with session and element id. // 3. Let element be the result of trying to get a known element with session and element id.
auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id)); auto element = TRY(Web::WebDriver::get_known_element(current_browsing_context(), element_id));
@ -1851,21 +1921,23 @@ Messages::WebDriverClient::GetSourceResponse WebDriverConnection::get_source()
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts and return its value if it is an error. // 2. Handle any user prompts and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
auto* document = current_browsing_context().active_document(); auto* document = current_browsing_context().active_document();
Optional<ByteString> source; Optional<String> source;
// 3. Let source be the result of invoking the fragment serializing algorithm on a fictional node whose only child is the document element providing true for the require well-formed flag. If this causes an exception to be thrown, let source be null. // 3. Let source be the result of invoking the fragment serializing algorithm on a fictional node whose only child is the document element providing true for the require well-formed flag. If this causes an exception to be thrown, let source be null.
if (auto result = document->serialize_fragment(Web::DOMParsing::RequireWellFormed::Yes); !result.is_error()) if (auto result = document->serialize_fragment(Web::DOMParsing::RequireWellFormed::Yes); !result.is_error())
source = result.release_value().to_byte_string(); source = result.release_value();
// 4. Let source be the result of serializing to string the current browsing context active document, if source is null. // 4. Let source be the result of serializing to string the current browsing context active document, if source is null.
if (!source.has_value()) if (!source.has_value())
source = MUST(document->serialize_fragment(Web::DOMParsing::RequireWellFormed::No)).to_byte_string(); source = MUST(document->serialize_fragment(Web::DOMParsing::RequireWellFormed::No));
// 5. Return success with data source. // 5. Return success with data source.
return source.release_value(); async_driver_execution_complete({ source->to_byte_string() });
});
return JsonValue {};
} }
// 13.2.1 Execute Script, https://w3c.github.io/webdriver/#dfn-execute-script // 13.2.1 Execute Script, https://w3c.github.io/webdriver/#dfn-execute-script
@ -1965,8 +2037,7 @@ Messages::WebDriverClient::GetAllCookiesResponse WebDriverConnection::get_all_co
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts, and return its value if it is an error. // 2. Handle any user prompts, and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 3. Let cookies be a new JSON List. // 3. Let cookies be a new JSON List.
JsonArray cookies; JsonArray cookies;
@ -1978,11 +2049,14 @@ Messages::WebDriverClient::GetAllCookiesResponse WebDriverConnection::get_all_co
auto serialized_cookie = serialize_cookie(cookie); auto serialized_cookie = serialize_cookie(cookie);
// 2. Append serialized cookie to cookies // 2. Append serialized cookie to cookies
TRY(cookies.append(move(serialized_cookie))); cookies.must_append(move(serialized_cookie));
} }
// 5. Return success with data cookies. // 5. Return success with data cookies.
return cookies; async_driver_execution_complete({ move(cookies) });
});
return JsonValue {};
} }
// 14.2 Get Named Cookie, https://w3c.github.io/webdriver/#dfn-get-named-cookie // 14.2 Get Named Cookie, https://w3c.github.io/webdriver/#dfn-get-named-cookie
@ -1992,18 +2066,21 @@ Messages::WebDriverClient::GetNamedCookieResponse WebDriverConnection::get_named
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts, and return its value if it is an error. // 2. Handle any user prompts, and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, name]() {
// 3. If the url variable name is equal to a cookies cookie name amongst all associated cookies of the current browsing contexts active document, return success with the serialized cookie as data. // 3. If the url variable name is equal to a cookies cookie name amongst all associated cookies of the current browsing contexts active document, return success with the serialized cookie as data.
auto* document = current_browsing_context().active_document(); auto* document = current_browsing_context().active_document();
if (auto cookie = current_browsing_context().page().client().page_did_request_named_cookie(document->url(), name); cookie.has_value()) { if (auto cookie = current_browsing_context().page().client().page_did_request_named_cookie(document->url(), name); cookie.has_value()) {
auto serialized_cookie = serialize_cookie(*cookie); auto serialized_cookie = serialize_cookie(*cookie);
return serialized_cookie; async_driver_execution_complete(move(serialized_cookie));
return;
} }
// 4. Otherwise, return error with error code no such cookie. // 4. Otherwise, return error with error code no such cookie.
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchCookie, ByteString::formatted("Cookie '{}' not found", name)); async_driver_execution_complete(Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchCookie, ByteString::formatted("Cookie '{}' not found", name)));
});
return JsonValue {};
} }
// 14.3 Add Cookie, https://w3c.github.io/webdriver/#dfn-adding-a-cookie // 14.3 Add Cookie, https://w3c.github.io/webdriver/#dfn-adding-a-cookie
@ -2019,8 +2096,15 @@ Messages::WebDriverClient::AddCookieResponse WebDriverConnection::add_cookie(Jso
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 4. Handle any user prompts, and return its value if it is an error. // 4. Handle any user prompts, and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, data = move(const_cast<JsonObject&>(data))]() {
async_driver_execution_complete(add_cookie_impl(data));
});
return JsonValue {};
}
Web::WebDriver::Response WebDriverConnection::add_cookie_impl(JsonObject const& data)
{
auto* document = current_browsing_context().active_document(); auto* document = current_browsing_context().active_document();
// 5. If the current browsing contexts document element is a cookie-averse Document object, return error with // 5. If the current browsing contexts document element is a cookie-averse Document object, return error with
@ -2101,12 +2185,14 @@ Messages::WebDriverClient::DeleteCookieResponse WebDriverConnection::delete_cook
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts, and return its value if it is an error. // 2. Handle any user prompts, and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this, name]() {
// 3. Delete cookies using the url variable name parameter as the filter argument. // 3. Delete cookies using the url variable name parameter as the filter argument.
delete_cookies(name); delete_cookies(name);
// 4. Return success with data null. // 4. Return success with data null.
async_driver_execution_complete(JsonValue {});
});
return JsonValue {}; return JsonValue {};
} }
@ -2117,12 +2203,14 @@ Messages::WebDriverClient::DeleteAllCookiesResponse WebDriverConnection::delete_
TRY(ensure_current_browsing_context_is_open()); TRY(ensure_current_browsing_context_is_open());
// 2. Handle any user prompts, and return its value if it is an error. // 2. Handle any user prompts, and return its value if it is an error.
TRY(deprecated_handle_any_user_prompts()); handle_any_user_prompts([this]() {
// 3. Delete cookies, giving no filtering argument. // 3. Delete cookies, giving no filtering argument.
delete_cookies(); delete_cookies();
// 4. Return success with data null. // 4. Return success with data null.
async_driver_execution_complete(JsonValue {});
});
return JsonValue {}; return JsonValue {};
} }
@ -2472,56 +2560,6 @@ void WebDriverConnection::handle_any_user_prompts(Function<void()> on_dialog_clo
// 3. Return success. // 3. Return success.
} }
// https://w3c.github.io/webdriver/#dfn-handle-any-user-prompts
// FIXME: Handling of user prompts must become completely asynchronous, as we must wait for the UI process to close the
// dialog widget and inform WebContent of the result. Thus, all endpoints which handle user prompts must also be
// become async.
ErrorOr<void, Web::WebDriver::Error> WebDriverConnection::deprecated_handle_any_user_prompts()
{
// 1. If there is no current user prompt, abort these steps and return success.
if (!current_browsing_context().page().has_pending_dialog())
return {};
// 2. Perform the following substeps based on the current sessions user prompt handler:
switch (m_unhandled_prompt_behavior) {
// -> dismiss state
case Web::WebDriver::UnhandledPromptBehavior::Dismiss:
// Dismiss the current user prompt.
current_browsing_context().page().dismiss_dialog();
break;
// -> accept state
case Web::WebDriver::UnhandledPromptBehavior::Accept:
// Accept the current user prompt.
current_browsing_context().page().accept_dialog();
break;
// -> dismiss and notify state
case Web::WebDriver::UnhandledPromptBehavior::DismissAndNotify:
// Dismiss the current user prompt.
current_browsing_context().page().dismiss_dialog();
// Return an annotated unexpected alert open error.
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::UnexpectedAlertOpen, "A user dialog is open"sv);
// -> accept and notify state
case Web::WebDriver::UnhandledPromptBehavior::AcceptAndNotify:
// Accept the current user prompt.
current_browsing_context().page().accept_dialog();
// Return an annotated unexpected alert open error.
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::UnexpectedAlertOpen, "A user dialog is open"sv);
// -> ignore state
case Web::WebDriver::UnhandledPromptBehavior::Ignore:
// Return an annotated unexpected alert open error.
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::UnexpectedAlertOpen, "A user dialog is open"sv);
}
// 3. Return success.
return {};
}
// https://w3c.github.io/webdriver/#dfn-wait-for-navigation-to-complete // https://w3c.github.io/webdriver/#dfn-wait-for-navigation-to-complete
// FIXME: Update this AO to the latest spec steps. // FIXME: Update this AO to the latest spec steps.
void WebDriverConnection::wait_for_navigation_to_complete(OnNavigationComplete on_complete) void WebDriverConnection::wait_for_navigation_to_complete(OnNavigationComplete on_complete)

View file

@ -123,10 +123,11 @@ private:
ErrorOr<void, Web::WebDriver::Error> ensure_current_top_level_browsing_context_is_open(); ErrorOr<void, Web::WebDriver::Error> ensure_current_top_level_browsing_context_is_open();
Web::WebDriver::Response element_click_impl(String const& element_id); Web::WebDriver::Response element_click_impl(String const& element_id);
Web::WebDriver::Response element_clear_impl(String const& element_id);
Web::WebDriver::Response element_send_keys_impl(String const& element_id, ByteString const& text); Web::WebDriver::Response element_send_keys_impl(String const& element_id, ByteString const& text);
Web::WebDriver::Response add_cookie_impl(JsonObject const&);
void handle_any_user_prompts(Function<void()> on_dialog_closed); void handle_any_user_prompts(Function<void()> on_dialog_closed);
ErrorOr<void, Web::WebDriver::Error> deprecated_handle_any_user_prompts();
void maximize_the_window(); void maximize_the_window();
void iconify_the_window(JS::NonnullGCPtr<JS::HeapFunction<void()>>); void iconify_the_window(JS::NonnullGCPtr<JS::HeapFunction<void()>>);

View file

@ -253,7 +253,10 @@ Web::WebDriver::Response Client::get_current_url(Web::WebDriver::Parameters para
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/url"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/url");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_current_url();
return session->perform_async_action([&](auto& connection) {
return connection.get_current_url();
});
} }
// 10.3 Back, https://w3c.github.io/webdriver/#dfn-back // 10.3 Back, https://w3c.github.io/webdriver/#dfn-back
@ -262,7 +265,10 @@ Web::WebDriver::Response Client::back(Web::WebDriver::Parameters parameters, Jso
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/back"); dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/back");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().back();
return session->perform_async_action([&](auto& connection) {
return connection.back();
});
} }
// 10.4 Forward, https://w3c.github.io/webdriver/#dfn-forward // 10.4 Forward, https://w3c.github.io/webdriver/#dfn-forward
@ -271,7 +277,10 @@ Web::WebDriver::Response Client::forward(Web::WebDriver::Parameters parameters,
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/forward"); dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/forward");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().forward();
return session->perform_async_action([&](auto& connection) {
return connection.forward();
});
} }
// 10.5 Refresh, https://w3c.github.io/webdriver/#dfn-refresh // 10.5 Refresh, https://w3c.github.io/webdriver/#dfn-refresh
@ -280,7 +289,10 @@ Web::WebDriver::Response Client::refresh(Web::WebDriver::Parameters parameters,
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/refresh"); dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/refresh");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().refresh();
return session->perform_async_action([&](auto& connection) {
return connection.refresh();
});
} }
// 10.6 Get Title, https://w3c.github.io/webdriver/#dfn-get-title // 10.6 Get Title, https://w3c.github.io/webdriver/#dfn-get-title
@ -289,7 +301,10 @@ Web::WebDriver::Response Client::get_title(Web::WebDriver::Parameters parameters
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/title"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/title");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_title();
return session->perform_async_action([&](auto& connection) {
return connection.get_title();
});
} }
// 11.1 Get Window Handle, https://w3c.github.io/webdriver/#get-window-handle // 11.1 Get Window Handle, https://w3c.github.io/webdriver/#get-window-handle
@ -350,9 +365,12 @@ Web::WebDriver::Response Client::new_window(Web::WebDriver::Parameters parameter
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/window/new"); dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/window/new");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
auto handle = TRY(session->web_content_connection().new_window(payload));
constexpr u32 CONNECTION_TIMEOUT_MS = 5000; auto handle = TRY(session->perform_async_action([&](auto& connection) {
return connection.new_window(move(payload));
}));
static constexpr u32 CONNECTION_TIMEOUT_MS = 5000;
auto timeout_fired = false; auto timeout_fired = false;
auto timer = Core::Timer::create_single_shot(CONNECTION_TIMEOUT_MS, [&timeout_fired] { timeout_fired = true; }); auto timer = Core::Timer::create_single_shot(CONNECTION_TIMEOUT_MS, [&timeout_fired] { timeout_fired = true; });
timer->start(); timer->start();
@ -373,7 +391,10 @@ Web::WebDriver::Response Client::switch_to_frame(Web::WebDriver::Parameters para
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/frame"); dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/frame");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().switch_to_frame(move(payload));
return session->perform_async_action([&](auto& connection) {
return connection.switch_to_frame(move(payload));
});
} }
// 11.7 Switch To Parent Frame, https://w3c.github.io/webdriver/#dfn-switch-to-parent-frame // 11.7 Switch To Parent Frame, https://w3c.github.io/webdriver/#dfn-switch-to-parent-frame
@ -382,7 +403,10 @@ Web::WebDriver::Response Client::switch_to_parent_frame(Web::WebDriver::Paramete
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/frame/parent"); dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/frame/parent");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().switch_to_parent_frame(move(payload));
return session->perform_async_action([&](auto& connection) {
return connection.switch_to_parent_frame(move(payload));
});
} }
// 11.8.1 Get Window Rect, https://w3c.github.io/webdriver/#dfn-get-window-rect // 11.8.1 Get Window Rect, https://w3c.github.io/webdriver/#dfn-get-window-rect
@ -391,7 +415,10 @@ Web::WebDriver::Response Client::get_window_rect(Web::WebDriver::Parameters para
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/window/rect"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/window/rect");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_window_rect();
return session->perform_async_action([&](auto& connection) {
return connection.get_window_rect();
});
} }
// 11.8.2 Set Window Rect, https://w3c.github.io/webdriver/#dfn-set-window-rect // 11.8.2 Set Window Rect, https://w3c.github.io/webdriver/#dfn-set-window-rect
@ -529,7 +556,10 @@ Web::WebDriver::Response Client::get_active_element(Web::WebDriver::Parameters p
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/active"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/active");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_active_element();
return session->perform_async_action([&](auto& connection) {
return connection.get_active_element();
});
} }
// 12.3.9 Get Element Shadow Root, https://w3c.github.io/webdriver/#get-element-shadow-root // 12.3.9 Get Element Shadow Root, https://w3c.github.io/webdriver/#get-element-shadow-root
@ -538,7 +568,10 @@ Web::WebDriver::Response Client::get_element_shadow_root(Web::WebDriver::Paramet
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/shadow"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/shadow");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_element_shadow_root(move(parameters[1]));
return session->perform_async_action([&](auto& connection) {
return connection.get_element_shadow_root(move(parameters[1]));
});
} }
// 12.4.1 Is Element Selected, https://w3c.github.io/webdriver/#dfn-is-element-selected // 12.4.1 Is Element Selected, https://w3c.github.io/webdriver/#dfn-is-element-selected
@ -547,7 +580,10 @@ Web::WebDriver::Response Client::is_element_selected(Web::WebDriver::Parameters
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/selected"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/selected");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().is_element_selected(move(parameters[1]));
return session->perform_async_action([&](auto& connection) {
return connection.is_element_selected(move(parameters[1]));
});
} }
// 12.4.2 Get Element Attribute, https://w3c.github.io/webdriver/#dfn-get-element-attribute // 12.4.2 Get Element Attribute, https://w3c.github.io/webdriver/#dfn-get-element-attribute
@ -556,7 +592,10 @@ Web::WebDriver::Response Client::get_element_attribute(Web::WebDriver::Parameter
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/attribute/<name>"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/attribute/<name>");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_element_attribute(move(parameters[1]), move(parameters[2]));
return session->perform_async_action([&](auto& connection) {
return connection.get_element_attribute(move(parameters[1]), move(parameters[2]));
});
} }
// 12.4.3 Get Element Property, https://w3c.github.io/webdriver/#dfn-get-element-property // 12.4.3 Get Element Property, https://w3c.github.io/webdriver/#dfn-get-element-property
@ -565,7 +604,10 @@ Web::WebDriver::Response Client::get_element_property(Web::WebDriver::Parameters
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/property/<name>"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/property/<name>");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_element_property(move(parameters[1]), move(parameters[2]));
return session->perform_async_action([&](auto& connection) {
return connection.get_element_property(move(parameters[1]), move(parameters[2]));
});
} }
// 12.4.4 Get Element CSS Value, https://w3c.github.io/webdriver/#dfn-get-element-css-value // 12.4.4 Get Element CSS Value, https://w3c.github.io/webdriver/#dfn-get-element-css-value
@ -574,7 +616,10 @@ Web::WebDriver::Response Client::get_element_css_value(Web::WebDriver::Parameter
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/css/<property_name>"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/css/<property_name>");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_element_css_value(move(parameters[1]), move(parameters[2]));
return session->perform_async_action([&](auto& connection) {
return connection.get_element_css_value(move(parameters[1]), move(parameters[2]));
});
} }
// 12.4.5 Get Element Text, https://w3c.github.io/webdriver/#dfn-get-element-text // 12.4.5 Get Element Text, https://w3c.github.io/webdriver/#dfn-get-element-text
@ -583,7 +628,10 @@ Web::WebDriver::Response Client::get_element_text(Web::WebDriver::Parameters par
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/text"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/text");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_element_text(move(parameters[1]));
return session->perform_async_action([&](auto& connection) {
return connection.get_element_text(move(parameters[1]));
});
} }
// 12.4.6 Get Element Tag Name, https://w3c.github.io/webdriver/#dfn-get-element-tag-name // 12.4.6 Get Element Tag Name, https://w3c.github.io/webdriver/#dfn-get-element-tag-name
@ -592,7 +640,10 @@ Web::WebDriver::Response Client::get_element_tag_name(Web::WebDriver::Parameters
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/name"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/name");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_element_tag_name(move(parameters[1]));
return session->perform_async_action([&](auto& connection) {
return connection.get_element_tag_name(move(parameters[1]));
});
} }
// 12.4.7 Get Element Rect, https://w3c.github.io/webdriver/#dfn-get-element-rect // 12.4.7 Get Element Rect, https://w3c.github.io/webdriver/#dfn-get-element-rect
@ -601,7 +652,10 @@ Web::WebDriver::Response Client::get_element_rect(Web::WebDriver::Parameters par
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/rect"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/rect");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_element_rect(move(parameters[1]));
return session->perform_async_action([&](auto& connection) {
return connection.get_element_rect(move(parameters[1]));
});
} }
// 12.4.8 Is Element Enabled, https://w3c.github.io/webdriver/#dfn-is-element-enabled // 12.4.8 Is Element Enabled, https://w3c.github.io/webdriver/#dfn-is-element-enabled
@ -610,7 +664,10 @@ Web::WebDriver::Response Client::is_element_enabled(Web::WebDriver::Parameters p
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/enabled"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/enabled");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().is_element_enabled(move(parameters[1]));
return session->perform_async_action([&](auto& connection) {
return connection.is_element_enabled(move(parameters[1]));
});
} }
// 12.4.9 https://w3c.github.io/webdriver/#dfn-get-computed-role // 12.4.9 https://w3c.github.io/webdriver/#dfn-get-computed-role
@ -619,7 +676,10 @@ Web::WebDriver::Response Client::get_computed_role(Web::WebDriver::Parameters pa
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session id>/element/<element id>/computedrole"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session id>/element/<element id>/computedrole");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_computed_role(move(parameters[1]));
return session->perform_async_action([&](auto& connection) {
return connection.get_computed_role(move(parameters[1]));
});
} }
// 12.4.10 Get Computed Label, https://w3c.github.io/webdriver/#get-computed-label // 12.4.10 Get Computed Label, https://w3c.github.io/webdriver/#get-computed-label
@ -628,7 +688,10 @@ Web::WebDriver::Response Client::get_computed_label(Web::WebDriver::Parameters p
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session id>/element/<element id>/computedlabel"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session id>/element/<element id>/computedlabel");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_computed_label(move(parameters[1]));
return session->perform_async_action([&](auto& connection) {
return connection.get_computed_label(move(parameters[1]));
});
} }
// 12.5.1 Element Click, https://w3c.github.io/webdriver/#element-click // 12.5.1 Element Click, https://w3c.github.io/webdriver/#element-click
@ -649,7 +712,10 @@ Web::WebDriver::Response Client::element_clear(Web::WebDriver::Parameters parame
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/element/<element_id>/clear"); dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/element/<element_id>/clear");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().element_clear(move(parameters[1]));
return session->perform_async_action([&](auto& connection) {
return connection.element_clear(move(parameters[1]));
});
} }
// 12.5.3 Element Send Keys, https://w3c.github.io/webdriver/#dfn-element-send-keys // 12.5.3 Element Send Keys, https://w3c.github.io/webdriver/#dfn-element-send-keys
@ -670,7 +736,10 @@ Web::WebDriver::Response Client::get_source(Web::WebDriver::Parameters parameter
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/source"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/source");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_source();
return session->perform_async_action([&](auto& connection) {
return connection.get_source();
});
} }
// 13.2.1 Execute Script, https://w3c.github.io/webdriver/#dfn-execute-script // 13.2.1 Execute Script, https://w3c.github.io/webdriver/#dfn-execute-script
@ -703,7 +772,10 @@ Web::WebDriver::Response Client::get_all_cookies(Web::WebDriver::Parameters para
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/cookie"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/cookie");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_all_cookies();
return session->perform_async_action([&](auto& connection) {
return connection.get_all_cookies();
});
} }
// 14.2 Get Named Cookie, https://w3c.github.io/webdriver/#dfn-get-named-cookie // 14.2 Get Named Cookie, https://w3c.github.io/webdriver/#dfn-get-named-cookie
@ -712,7 +784,10 @@ Web::WebDriver::Response Client::get_named_cookie(Web::WebDriver::Parameters par
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/cookie/<name>"); dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/cookie/<name>");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().get_named_cookie(move(parameters[1]));
return session->perform_async_action([&](auto& connection) {
return connection.get_named_cookie(move(parameters[1]));
});
} }
// 14.3 Add Cookie, https://w3c.github.io/webdriver/#dfn-adding-a-cookie // 14.3 Add Cookie, https://w3c.github.io/webdriver/#dfn-adding-a-cookie
@ -721,7 +796,10 @@ Web::WebDriver::Response Client::add_cookie(Web::WebDriver::Parameters parameter
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/cookie"); dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/cookie");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().add_cookie(payload);
return session->perform_async_action([&](auto& connection) {
return connection.add_cookie(move(payload));
});
} }
// 14.4 Delete Cookie, https://w3c.github.io/webdriver/#dfn-delete-cookie // 14.4 Delete Cookie, https://w3c.github.io/webdriver/#dfn-delete-cookie
@ -730,7 +808,10 @@ Web::WebDriver::Response Client::delete_cookie(Web::WebDriver::Parameters parame
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling DELETE /session/<session_id>/cookie/<name>"); dbgln_if(WEBDRIVER_DEBUG, "Handling DELETE /session/<session_id>/cookie/<name>");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().delete_cookie(move(parameters[1]));
return session->perform_async_action([&](auto& connection) {
return connection.delete_cookie(move(parameters[1]));
});
} }
// 14.5 Delete All Cookies, https://w3c.github.io/webdriver/#dfn-delete-all-cookies // 14.5 Delete All Cookies, https://w3c.github.io/webdriver/#dfn-delete-all-cookies
@ -739,7 +820,10 @@ Web::WebDriver::Response Client::delete_all_cookies(Web::WebDriver::Parameters p
{ {
dbgln_if(WEBDRIVER_DEBUG, "Handling DELETE /session/<session_id>/cookie"); dbgln_if(WEBDRIVER_DEBUG, "Handling DELETE /session/<session_id>/cookie");
auto session = TRY(find_session_with_id(parameters[0])); auto session = TRY(find_session_with_id(parameters[0]));
return session->web_content_connection().delete_all_cookies();
return session->perform_async_action([&](auto& connection) {
return connection.delete_all_cookies();
});
} }
// 15.7 Perform Actions, https://w3c.github.io/webdriver/#perform-actions // 15.7 Perform Actions, https://w3c.github.io/webdriver/#perform-actions

View file

@ -131,7 +131,9 @@ Web::WebDriver::Response Session::close_window()
ScopeGuard guard { [this] { m_windows.remove(m_current_window_handle); m_current_window_handle = "NoSuchWindowPleaseSelectANewOne"_string; } }; ScopeGuard guard { [this] { m_windows.remove(m_current_window_handle); m_current_window_handle = "NoSuchWindowPleaseSelectANewOne"_string; } };
// 3. Close the current top-level browsing context. // 3. Close the current top-level browsing context.
TRY(web_content_connection().close_window()); TRY(perform_async_action([&](auto& connection) {
return connection.close_window();
}));
// 4. If there are no more open top-level browsing contexts, then close the session. // 4. If there are no more open top-level browsing contexts, then close the session.
if (m_windows.size() == 1) if (m_windows.size() == 1)