1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 04:17:35 +00:00

WebContent+WebDriver: Move Find Element to WebContent

Note that this does nothing to "fix" how element references are created.
We continue to return the element ID because, otherwise, all other
element WebDriver endpoints would break.

On the bright side, we avoid several IPC round trips now that we perform
the entire 'find' operation in the WebContent process; and we are able
to work directly on DOM nodes.
This commit is contained in:
Timothy Flynn 2022-11-09 15:02:38 -05:00 committed by Linus Groh
parent 15916e5c14
commit 61de50c7fd
6 changed files with 120 additions and 58 deletions

View file

@ -447,61 +447,6 @@ ErrorOr<Vector<Session::LocalElement>, Web::WebDriver::Error> Session::locator_s
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::UnsupportedOperation, "Not implemented: locator strategy XPath");
}
// 12.3.2 Find Element, https://w3c.github.io/webdriver/#dfn-find-element
Web::WebDriver::Response Session::find_element(JsonValue const& payload)
{
if (!payload.is_object())
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload is not a JSON object");
auto const& properties = payload.as_object();
// 1. Let location strategy be the result of getting a property called "using".
if (!properties.has("using"sv))
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "No property called 'using' present");
auto const& maybe_location_strategy = properties.get("using"sv);
if (!maybe_location_strategy.is_string())
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Property 'using' is not a String");
auto location_strategy = maybe_location_strategy.to_string();
// 2. If location strategy is not present as a keyword in the table of location strategies, return error with error code invalid argument.
if (!s_locator_strategies.first_matching([&](LocatorStrategy const& match) { return match.name == location_strategy; }).has_value())
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "No valid location strategy");
// 3. Let selector be the result of getting a property called "value".
// 4. If selector is undefined, return error with error code invalid argument.
if (!properties.has("value"sv))
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "No property called 'value' present");
auto const& maybe_selector = properties.get("value"sv);
if (!maybe_selector.is_string())
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Property 'value' is not a String");
auto selector = maybe_selector.to_string();
// 5. If the current browsing context is no longer open, return error with error code no such window.
TRY(check_for_open_top_level_browsing_context_or_return_error());
// FIXME: 6. Handle any user prompts and return its value if it is an error.
// 7. Let start node be the current browsing contexts document element.
auto maybe_start_node_id = m_browser_connection->get_document_element();
// 8. If start node is null, return error with error code no such element.
if (!maybe_start_node_id.has_value())
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchElement, "document element does not exist");
auto start_node_id = maybe_start_node_id.release_value();
LocalElement start_node = { start_node_id };
// 9. Let result be the result of trying to Find with start node, location strategy, and selector.
auto result = TRY(find(start_node, location_strategy, selector));
// 10. If result is empty, return error with error code no such element. Otherwise, return the first element of result.
if (result.is_empty())
return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchElement, "The requested element does not exist");
return JsonValue(result.at(0));
}
// 12.3.3 Find Elements, https://w3c.github.io/webdriver/#dfn-find-elements
Web::WebDriver::Response Session::find_elements(JsonValue const& payload)
{