From 9879ac0893d084c9bd9d1a33f10844731b04b947 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Mon, 17 Feb 2025 13:58:21 -0500 Subject: [PATCH] LibWeb+WebContent+WebDriver: Port WebDriver to String --- Libraries/LibWeb/WebDriver/Actions.cpp | 32 ++++---- Libraries/LibWeb/WebDriver/Capabilities.cpp | 10 +-- Libraries/LibWeb/WebDriver/Client.cpp | 6 +- Libraries/LibWeb/WebDriver/Contexts.cpp | 10 +-- .../LibWeb/WebDriver/ElementReference.cpp | 56 +++++++------- Libraries/LibWeb/WebDriver/ElementReference.h | 10 +-- Libraries/LibWeb/WebDriver/Error.cpp | 71 +++++++++--------- Libraries/LibWeb/WebDriver/Error.h | 13 ++-- Libraries/LibWeb/WebDriver/ExecuteScript.cpp | 6 +- Libraries/LibWeb/WebDriver/ExecuteScript.h | 5 +- Libraries/LibWeb/WebDriver/InputSource.cpp | 2 +- Libraries/LibWeb/WebDriver/JSON.cpp | 22 +++--- Libraries/LibWeb/WebDriver/Properties.h | 32 ++++---- Libraries/LibWeb/WebDriver/Response.cpp | 4 +- Libraries/LibWeb/WebDriver/Screenshot.cpp | 2 +- .../WebDriver/TimeoutsConfiguration.cpp | 4 +- Libraries/LibWeb/WebDriver/UserPrompt.cpp | 6 +- Services/WebContent/WebDriverConnection.cpp | 73 +++++++++---------- Services/WebContent/WebDriverConnection.h | 6 +- Services/WebDriver/Client.cpp | 8 +- Services/WebDriver/Session.cpp | 6 +- 21 files changed, 194 insertions(+), 190 deletions(-) diff --git a/Libraries/LibWeb/WebDriver/Actions.cpp b/Libraries/LibWeb/WebDriver/Actions.cpp index 21c99396bfe..bed4590e1a3 100644 --- a/Libraries/LibWeb/WebDriver/Actions.cpp +++ b/Libraries/LibWeb/WebDriver/Actions.cpp @@ -106,7 +106,7 @@ static Optional determine_origin(ActionsOptions const& act if (origin->is_object()) { if (actions_options.is_element_origin(origin->as_object())) - return MUST(String::from_byte_string(extract_web_element_reference(origin->as_object()))); + return extract_web_element_reference(origin->as_object()); } return {}; @@ -229,7 +229,7 @@ static ErrorOr process_pointer_parameters(O // 3. If parameters data is not an Object, return error with error code invalid argument. if (!parameters_data->is_object()) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'parameters' is not an Object"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'parameters' is not an Object"sv); // 4. Let pointer type be the result of getting a property named "pointerType" from parameters data. auto pointer_type = TRY(get_optional_property(parameters_data->as_object(), "pointerType"sv)); @@ -241,7 +241,7 @@ static ErrorOr process_pointer_parameters(O auto parsed_pointer_type = pointer_input_source_subtype_from_string(*pointer_type); if (!parsed_pointer_type.has_value()) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'pointerType' must be one of 'mouse', 'pen', or 'touch'"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'pointerType' must be one of 'mouse', 'pen', or 'touch'"sv); // 2. Set the pointerType property of parameters to pointer type. parameters.pointer_type = *parsed_pointer_type; @@ -272,7 +272,7 @@ static ErrorOr process_null_action(String id, Js // 2. If subtype is not "pause", return error with error code invalid argument. if (subtype != ActionObject::Subtype::Pause) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' must be 'pause'"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' must be 'pause'"sv); // 3. Let action be an action object constructed with arguments id, "none", and subtype. ActionObject action { move(id), InputSourceType::None, *subtype }; @@ -294,7 +294,7 @@ static ErrorOr process_key_action(String id, Jso // 2. If subtype is not one of the values "keyUp", "keyDown", or "pause", return an error with error code invalid argument. if (!first_is_one_of(subtype, KeyUp, KeyDown, Pause)) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' must be one of 'keyUp', 'keyDown', or 'pause'"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' must be one of 'keyUp', 'keyDown', or 'pause'"sv); // 3. Let action be an action object constructed with arguments id, "key", and subtype. ActionObject action { move(id), InputSourceType::Key, *subtype }; @@ -317,7 +317,7 @@ static ErrorOr process_key_action(String id, Jso // FIXME: The spec seems undecided on whether grapheme clusters should be supported. Update this step to check // for graphemes if we end up needing to support them. We would also need to update Page's key event // handlers to support multi-code point events. - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'value' must be a single code point"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'value' must be a single code point"sv); } // 7. Set the value property on action to key. @@ -412,7 +412,7 @@ static ErrorOr process_pointer_move_action(JsonObject co // 6. If origin is not equal to "viewport" or "pointer", and actions options is element origin steps given origin // return false, return error with error code invalid argument. if (!origin.has_value()) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'origin' must be 'viewport', 'pointer', or an element origin"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'origin' must be 'viewport', 'pointer', or an element origin"sv); // 7. Set the origin property of action to origin. fields.origin = origin.release_value(); @@ -440,7 +440,7 @@ static ErrorOr process_pointer_action(String id, // 2. If subtype is not one of the values "pause", "pointerUp", "pointerDown", "pointerMove", or "pointerCancel", return an error with error code invalid argument. if (!first_is_one_of(subtype, Pause, PointerUp, PointerDown, PointerMove, PointerCancel)) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' must be one of 'pause', 'pointerUp', 'pointerDown', 'pointerMove', or 'pointerCancel'"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' must be one of 'pause', 'pointerUp', 'pointerDown', 'pointerMove', or 'pointerCancel'"sv); // 3. Let action be an action object constructed with arguments id, "pointer", and subtype. ActionObject action { move(id), InputSourceType::Pointer, *subtype }; @@ -487,7 +487,7 @@ static ErrorOr process_wheel_action(String id, J // 2. If subtype is not the value "pause", or "scroll", return an error with error code invalid argument. if (!first_is_one_of(subtype, Pause, Scroll)) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' must be one of 'pause' or 'scroll'"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' must be one of 'pause' or 'scroll'"sv); // 3. Let action be an action object constructed with arguments id, "wheel", and subtype. ActionObject action { move(id), InputSourceType::Wheel, *subtype }; @@ -514,7 +514,7 @@ static ErrorOr process_wheel_action(String id, J // 10. If origin is not equal to "viewport", or actions options' is element origin steps given origin return false, // return error with error code invalid argument. if (!origin.has_value() || origin == ActionObject::OriginType::Pointer) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'origin' must be 'viewport' or an element origin"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'origin' must be 'viewport' or an element origin"sv); // 11. Set the origin property of action to origin. fields.origin = origin.release_value(); @@ -551,11 +551,11 @@ static ErrorOr, WebDriver::Error> process_input_source_acti // 2. If type is not "key", "pointer", "wheel", or "none", return an error with error code invalid argument. if (!type.has_value()) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' must be one of 'key', 'pointer', 'wheel', or 'none'"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' must be one of 'key', 'pointer', 'wheel', or 'none'"sv); // 3. Let id be the result of getting the property "id" from action sequence. // 4. If id is undefined or is not a String, return error with error code invalid argument. - auto const id = MUST(String::from_byte_string(TRY(get_property(action_sequence, "id"sv)))); + auto const id = TRY(get_property(action_sequence, "id"sv)); // 5. If type is equal to "pointer", let parameters data be the result of getting the property "parameters" from // action sequence. Then let parameters be the result of trying to process pointer parameters with argument @@ -575,7 +575,7 @@ static ErrorOr, WebDriver::Error> process_input_source_acti // return an error with error code invalid argument. if (auto const* pointer_input_source = source.get_pointer(); pointer_input_source && parameters.has_value()) { if (parameters->pointer_type != pointer_input_source->subtype) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Invalid 'pointerType' property"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Invalid 'pointerType' property"sv); } // 8. Let action items be the result of getting a property named "actions" from action sequence. @@ -589,7 +589,7 @@ static ErrorOr, WebDriver::Error> process_input_source_acti TRY(action_items.try_for_each([&](auto const& action_item) -> ErrorOr { // 1. If action item is not an Object return error with error code invalid argument. if (!action_item.is_object()) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'actions' item is not an Object"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'actions' item is not an Object"sv); auto action = TRY([&]() { switch (*type) { @@ -1240,11 +1240,11 @@ static ErrorOr dispatch_pointer_move_action(ActionObject // 5. If x is less than 0 or greater than the width of the viewport in CSS pixels, then return error with error code move target out of bounds. if (coordinates.x() < 0 || coordinates.x() > viewport.width()) - return WebDriver::Error::from_code(WebDriver::ErrorCode::MoveTargetOutOfBounds, ByteString::formatted("Coordinates {} are out of bounds", coordinates)); + return WebDriver::Error::from_code(WebDriver::ErrorCode::MoveTargetOutOfBounds, MUST(String::formatted("Coordinates {} are out of bounds", coordinates))); // 6. If y is less than 0 or greater than the height of the viewport in CSS pixels, then return error with error code move target out of bounds. if (coordinates.y() < 0 || coordinates.y() > viewport.height()) - return WebDriver::Error::from_code(WebDriver::ErrorCode::MoveTargetOutOfBounds, ByteString::formatted("Coordinates {} are out of bounds", coordinates)); + return WebDriver::Error::from_code(WebDriver::ErrorCode::MoveTargetOutOfBounds, MUST(String::formatted("Coordinates {} are out of bounds", coordinates))); // 7. Let duration be equal to action object's duration property if it is not undefined, or tick duration otherwise. [[maybe_unused]] auto duration = action_object.duration.value_or(tick_duration); diff --git a/Libraries/LibWeb/WebDriver/Capabilities.cpp b/Libraries/LibWeb/WebDriver/Capabilities.cpp index 73a675fb97e..b88d180f4a3 100644 --- a/Libraries/LibWeb/WebDriver/Capabilities.cpp +++ b/Libraries/LibWeb/WebDriver/Capabilities.cpp @@ -91,7 +91,7 @@ static ErrorOr validate_capabilities(JsonValue const& capabil else if (name.is_one_of("browserName"sv, "browserVersion"sv, "platformName"sv)) { // If value is not a string return an error with error code invalid argument. Otherwise, let deserialized be set to value. if (!value.is_string()) - return Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("Capability {} must be a string", name)); + return Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("Capability {} must be a string", name))); deserialized = value; } @@ -152,7 +152,7 @@ static ErrorOr validate_capabilities(JsonValue const& capabil // -> The remote end is an endpoint node else { // Return an error with error code invalid argument. - return Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("Unrecognized capability: {}", name)); + return Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("Unrecognized capability: {}", name))); } // d. If deserialized is not null, set a property on result with name name and value deserialized. @@ -195,7 +195,7 @@ static ErrorOr merge_capabilities(JsonObject const& primary, // d. If primary value is not undefined, return an error with error code invalid argument. if (primary_value.has_value()) - return Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("Unable to merge capability {}", name)); + return Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("Unable to merge capability {}", name))); // e. Set a property on result with name name and value value. result.set(name, value); @@ -290,13 +290,13 @@ static JsonValue match_capabilities(JsonObject const& capabilities, SessionFlags else if (name == "browserVersion"sv) { // Compare value to the "browserVersion" entry in matched capabilities using an implementation-defined comparison algorithm. The comparison is to accept a value that places constraints on the version using the "<", "<=", ">", and ">=" operators. // If the two values do not match, return success with data null. - if (!matches_browser_version(value.as_string(), matched_capabilities.get_byte_string(name).value())) + if (!matches_browser_version(value.as_string(), matched_capabilities.get_string(name).value())) return AK::Error::from_string_literal("browserVersion"); } // -> "platformName" else if (name == "platformName"sv) { // If value is not a string equal to the "platformName" entry in matched capabilities, return success with data null. - if (!matches_platform_name(value.as_string(), matched_capabilities.get_byte_string(name).value())) + if (!matches_platform_name(value.as_string(), matched_capabilities.get_string(name).value())) return AK::Error::from_string_literal("platformName"); } // -> "acceptInsecureCerts" diff --git a/Libraries/LibWeb/WebDriver/Client.cpp b/Libraries/LibWeb/WebDriver/Client.cpp index 514d38a6e14..24106c2920a 100644 --- a/Libraries/LibWeb/WebDriver/Client.cpp +++ b/Libraries/LibWeb/WebDriver/Client.cpp @@ -167,7 +167,7 @@ static ErrorOr match_route(HTTP::HttpRequest const& request } } - return Error::from_code(ErrorCode::UnknownCommand, "The command was not recognized."); + return Error::from_code(ErrorCode::UnknownCommand, "The command was not recognized."sv); } static JsonValue make_success_response(JsonValue value) @@ -329,8 +329,8 @@ ErrorOr Client::send_error_response(HTTP::HttpReques auto reason = HTTP::HttpResponse::reason_phrase_for_code(error.http_status); JsonObject error_response; - error_response.set("error"sv, MUST(String::from_byte_string(error.error))); - error_response.set("message"sv, MUST(String::from_byte_string(error.message))); + error_response.set("error"sv, error.error); + error_response.set("message"sv, error.message); error_response.set("stacktrace"sv, ""sv); if (error.data.has_value()) error_response.set("data"sv, *error.data); diff --git a/Libraries/LibWeb/WebDriver/Contexts.cpp b/Libraries/LibWeb/WebDriver/Contexts.cpp index 12cdb82d233..c1654da914b 100644 --- a/Libraries/LibWeb/WebDriver/Contexts.cpp +++ b/Libraries/LibWeb/WebDriver/Contexts.cpp @@ -14,10 +14,10 @@ namespace Web::WebDriver { // https://w3c.github.io/webdriver/#dfn-web-window-identifier -static ByteString const WEB_WINDOW_IDENTIFIER = "window-fcc6-11e5-b4f8-330a88ab9d7f"sv; +static JS::PropertyKey const WEB_WINDOW_IDENTIFIER { "window-fcc6-11e5-b4f8-330a88ab9d7f" }; // https://w3c.github.io/webdriver/#dfn-web-frame-identifier -static ByteString const WEB_FRAME_IDENTIFIER = "frame-075b-4da1-b6ba-e579c2d3230a"sv; +static JS::PropertyKey const WEB_FRAME_IDENTIFIER { "frame-075b-4da1-b6ba-e579c2d3230a" }; // https://w3c.github.io/webdriver/#dfn-windowproxy-reference-object JsonObject window_proxy_reference_object(HTML::WindowProxy const& window) @@ -30,7 +30,7 @@ JsonObject window_proxy_reference_object(HTML::WindowProxy const& window) // Ref: https://html.spec.whatwg.org/multipage/document-sequences.html#bc-traversable auto navigable = window.associated_browsing_context()->active_document()->navigable(); - auto identifier = navigable->is_top_level_traversable() + auto const& identifier = navigable->is_top_level_traversable() ? WEB_WINDOW_IDENTIFIER : WEB_FRAME_IDENTIFIER; @@ -39,7 +39,7 @@ JsonObject window_proxy_reference_object(HTML::WindowProxy const& window) // identifier // Associated window handle of the window’s browsing context. - object.set(identifier, navigable->traversable_navigable()->window_handle()); + object.set(identifier.as_string(), navigable->traversable_navigable()->window_handle()); return object; } @@ -64,7 +64,7 @@ bool represents_a_web_frame(JS::Value value) if (!value.is_object()) return false; - auto result = value.as_object().has_own_property(WEB_FRAME_IDENTIFIER); + auto result = value.as_object().has_own_property(WEB_WINDOW_IDENTIFIER); return !result.is_error() && result.value(); } diff --git a/Libraries/LibWeb/WebDriver/ElementReference.cpp b/Libraries/LibWeb/WebDriver/ElementReference.cpp index bbf667e5e3d..802f25a9a54 100644 --- a/Libraries/LibWeb/WebDriver/ElementReference.cpp +++ b/Libraries/LibWeb/WebDriver/ElementReference.cpp @@ -25,16 +25,18 @@ namespace Web::WebDriver { // https://w3c.github.io/webdriver/#dfn-web-element-identifier -static ByteString const web_element_identifier = "element-6066-11e4-a52e-4f735466cecf"sv; +static String const web_element_identifier = "element-6066-11e4-a52e-4f735466cecf"_string; +static JS::PropertyKey web_element_identifier_key { web_element_identifier.to_byte_string() }; // https://w3c.github.io/webdriver/#dfn-shadow-root-identifier -static ByteString const shadow_root_identifier = "shadow-6066-11e4-a52e-4f735466cecf"sv; +static String const shadow_root_identifier = "shadow-6066-11e4-a52e-4f735466cecf"_string; +static JS::PropertyKey shadow_root_identifier_key { shadow_root_identifier.to_byte_string() }; // https://w3c.github.io/webdriver/#dfn-browsing-context-group-node-map -static HashMap, HashTable> browsing_context_group_node_map; +static HashMap, HashTable> browsing_context_group_node_map; // https://w3c.github.io/webdriver/#dfn-navigable-seen-nodes-map -static HashMap, HashTable> navigable_seen_nodes_map; +static HashMap, HashTable> navigable_seen_nodes_map; // https://w3c.github.io/webdriver/#dfn-get-a-node GC::Ptr get_node(HTML::BrowsingContext const& browsing_context, StringView reference) @@ -62,7 +64,7 @@ GC::Ptr get_node(HTML::BrowsingContext const& browsing_context, } // https://w3c.github.io/webdriver/#dfn-get-or-create-a-node-reference -ByteString get_or_create_a_node_reference(HTML::BrowsingContext const& browsing_context, Web::DOM::Node const& node) +String get_or_create_a_node_reference(HTML::BrowsingContext const& browsing_context, Web::DOM::Node const& node) { // 1. Let browsing context group node map be session's browsing context group node map. // 2. Let browsing context group be browsing context's browsing context group. @@ -73,7 +75,7 @@ ByteString get_or_create_a_node_reference(HTML::BrowsingContext const& browsing_ // 4. Let node id map be browsing context group node map[browsing context group]. auto& node_id_map = browsing_context_group_node_map.ensure(browsing_context_group); - auto node_id = ByteString::number(node.unique_id().value()); + auto node_id = String::number(node.unique_id().value()); // 5. If node id map does not contain node: if (!node_id_map.contains(node_id)) { @@ -111,7 +113,7 @@ bool node_reference_is_known(HTML::BrowsingContext const& browsing_context, Stri } // https://w3c.github.io/webdriver/#dfn-get-or-create-a-web-element-reference -ByteString get_or_create_a_web_element_reference(HTML::BrowsingContext const& browsing_context, Web::DOM::Node const& element) +String get_or_create_a_web_element_reference(HTML::BrowsingContext const& browsing_context, Web::DOM::Node const& element) { // 1. Assert: element implements Element. VERIFY(element.is_element()); @@ -132,7 +134,7 @@ JsonObject web_element_reference_object(HTML::BrowsingContext const& browsing_co // 3. Return a JSON Object initialized with a property with name identifier and value reference. JsonObject object; - object.set(identifier, MUST(String::from_byte_string(reference))); + object.set(identifier, move(reference)); return object; } @@ -153,7 +155,7 @@ bool represents_a_web_element(JS::Value value) if (!value.is_object()) return false; - auto result = value.as_object().has_own_property(web_element_identifier); + auto result = value.as_object().has_own_property(web_element_identifier_key); return !result.is_error() && result.value(); } @@ -162,7 +164,7 @@ ErrorOr, WebDriver::Error> deserialize_web_element(We { // 1. If object has no own property web element identifier, return error with error code invalid argument. if (!object.has_string(web_element_identifier)) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Object is not a web element"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Object is not a web element"sv); // 2. Let reference be the result of getting the web element identifier property from object. auto reference = extract_web_element_reference(object); @@ -178,9 +180,9 @@ ErrorOr, WebDriver::Error> deserialize_web_element(We ErrorOr, WebDriver::Error> deserialize_web_element(Web::HTML::BrowsingContext const& browsing_context, JS::Object const& object) { // 1. If object has no own property web element identifier, return error with error code invalid argument. - auto property = object.get(web_element_identifier); + auto property = object.get(web_element_identifier_key); if (property.is_error() || !property.value().is_string()) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Object is not a web element"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Object is not a web element"sv); // 2. Let reference be the result of getting the web element identifier property from object. auto reference = property.value().as_string().utf8_string(); @@ -192,9 +194,9 @@ ErrorOr, WebDriver::Error> deserialize_web_element(We return element; } -ByteString extract_web_element_reference(JsonObject const& object) +String extract_web_element_reference(JsonObject const& object) { - return object.get_byte_string(web_element_identifier).release_value(); + return object.get_string(web_element_identifier).release_value(); } // https://w3c.github.io/webdriver/#dfn-get-a-webelement-origin @@ -215,18 +217,18 @@ ErrorOr, Web::WebDriver::Error> get_known_element(Web // 1. If not node reference is known with session, session's current browsing context, and reference return error // with error code no such element. if (!node_reference_is_known(browsing_context, reference)) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchElement, ByteString::formatted("Element reference '{}' is not known", reference)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchElement, MUST(String::formatted("Element reference '{}' is not known", reference))); // 2. Let node be the result of get a node with session, session's current browsing context, and reference. auto node = get_node(browsing_context, reference); // 3. If node is not null and node does not implement Element return error with error code no such element. if (node && !node->is_element()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchElement, ByteString::formatted("Could not find element with reference '{}'", reference)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchElement, MUST(String::formatted("Could not find element with reference '{}'", reference))); // 4. If node is null or node is stale return error with error code stale element reference. if (!node || is_element_stale(*node)) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::StaleElementReference, ByteString::formatted("Element reference '{}' is stale", reference)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::StaleElementReference, MUST(String::formatted("Element reference '{}' is stale", reference))); // 5. Return success with data node. return static_cast(*node); @@ -403,7 +405,7 @@ GC::RootVector> pointer_interactable_tree(Web::HTML:: } // https://w3c.github.io/webdriver/#dfn-get-or-create-a-shadow-root-reference -ByteString get_or_create_a_shadow_root_reference(HTML::BrowsingContext const& browsing_context, Web::DOM::ShadowRoot const& shadow_root) +String get_or_create_a_shadow_root_reference(HTML::BrowsingContext const& browsing_context, Web::DOM::ShadowRoot const& shadow_root) { // 1. Assert: element implements ShadowRoot. // 2. Return the result of trying to get or create a node reference with session, session's current browsing context, @@ -422,7 +424,7 @@ JsonObject shadow_root_reference_object(HTML::BrowsingContext const& browsing_co // 3. Return a JSON Object initialized with a property with name identifier and value reference. JsonObject object; - object.set(identifier, MUST(String::from_byte_string(reference))); + object.set(identifier, move(reference)); return object; } @@ -443,7 +445,7 @@ bool represents_a_shadow_root(JS::Value value) if (!value.is_object()) return false; - auto result = value.as_object().has_own_property(shadow_root_identifier); + auto result = value.as_object().has_own_property(shadow_root_identifier_key); return !result.is_error() && result.value(); } @@ -452,10 +454,10 @@ ErrorOr, WebDriver::Error> deserialize_shadow_root { // 1. If object has no own property shadow root identifier, return error with error code invalid argument. if (!object.has_string(shadow_root_identifier)) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Object is not a Shadow Root"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Object is not a Shadow Root"sv); // 2. Let reference be the result of getting the shadow root identifier property from object. - auto reference = object.get_byte_string(shadow_root_identifier).release_value(); + auto const& reference = object.get_string(shadow_root_identifier).release_value(); // 3. Let shadow be the result of trying to get a known shadow root with session and reference. auto shadow = TRY(get_known_shadow_root(browsing_context, reference)); @@ -468,9 +470,9 @@ ErrorOr, WebDriver::Error> deserialize_shadow_root ErrorOr, WebDriver::Error> deserialize_shadow_root(Web::HTML::BrowsingContext const& browsing_context, JS::Object const& object) { // 1. If object has no own property shadow root identifier, return error with error code invalid argument. - auto property = object.get(shadow_root_identifier); + auto property = object.get(shadow_root_identifier_key); if (property.is_error() || !property.value().is_string()) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Object is not a Shadow Root"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Object is not a Shadow Root"sv); // 2. Let reference be the result of getting the shadow root identifier property from object. auto reference = property.value().as_string().utf8_string(); @@ -487,18 +489,18 @@ ErrorOr, Web::WebDriver::Error> get_known_shadow_r { // 1. If not node reference is known with session, session's current browsing context, and reference return error with error code no such shadow root. if (!node_reference_is_known(browsing_context, reference)) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchShadowRoot, ByteString::formatted("Shadow root reference '{}' is not known", reference)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchShadowRoot, MUST(String::formatted("Shadow root reference '{}' is not known", reference))); // 2. Let node be the result of get a node with session, session's current browsing context, and reference. auto node = get_node(browsing_context, reference); // 3. If node is not null and node does not implement ShadowRoot return error with error code no such shadow root. if (node && !node->is_shadow_root()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchShadowRoot, ByteString::formatted("Could not find shadow root with reference '{}'", reference)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchShadowRoot, MUST(String::formatted("Could not find shadow root with reference '{}'", reference))); // 4. If node is null or node is detached return error with error code detached shadow root. if (!node || is_shadow_root_detached(static_cast(*node))) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::DetachedShadowRoot, ByteString::formatted("Element reference '{}' is stale", reference)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::DetachedShadowRoot, MUST(String::formatted("Element reference '{}' is stale", reference))); // 5. Return success with data node. return static_cast(*node); diff --git a/Libraries/LibWeb/WebDriver/ElementReference.h b/Libraries/LibWeb/WebDriver/ElementReference.h index ac0c6c52974..25bf4023439 100644 --- a/Libraries/LibWeb/WebDriver/ElementReference.h +++ b/Libraries/LibWeb/WebDriver/ElementReference.h @@ -6,9 +6,9 @@ #pragma once -#include #include #include +#include #include #include #include @@ -19,16 +19,16 @@ namespace Web::WebDriver { GC::Ptr get_node(HTML::BrowsingContext const&, StringView reference); -ByteString get_or_create_a_node_reference(HTML::BrowsingContext const&, Web::DOM::Node const&); +String get_or_create_a_node_reference(HTML::BrowsingContext const&, Web::DOM::Node const&); bool node_reference_is_known(HTML::BrowsingContext const&, StringView reference); -ByteString get_or_create_a_web_element_reference(HTML::BrowsingContext const&, Web::DOM::Node const& element); +String get_or_create_a_web_element_reference(HTML::BrowsingContext const&, Web::DOM::Node const& element); JsonObject web_element_reference_object(HTML::BrowsingContext const&, Web::DOM::Node const& element); bool represents_a_web_element(JsonValue const&); bool represents_a_web_element(JS::Value); ErrorOr, WebDriver::Error> deserialize_web_element(Web::HTML::BrowsingContext const&, JsonObject const&); ErrorOr, WebDriver::Error> deserialize_web_element(Web::HTML::BrowsingContext const&, JS::Object const&); -ByteString extract_web_element_reference(JsonObject const&); +String extract_web_element_reference(JsonObject const&); ErrorOr, Web::WebDriver::Error> get_web_element_origin(Web::HTML::BrowsingContext const&, StringView origin); ErrorOr, Web::WebDriver::Error> get_known_element(Web::HTML::BrowsingContext const&, StringView reference); @@ -46,7 +46,7 @@ bool is_element_in_view(ReadonlySpan> paint_tree, Web bool is_element_obscured(ReadonlySpan> paint_tree, Web::DOM::Element&); GC::RootVector> pointer_interactable_tree(Web::HTML::BrowsingContext&, Web::DOM::Element&); -ByteString get_or_create_a_shadow_root_reference(HTML::BrowsingContext const&, Web::DOM::ShadowRoot const&); +String get_or_create_a_shadow_root_reference(HTML::BrowsingContext const&, Web::DOM::ShadowRoot const&); JsonObject shadow_root_reference_object(HTML::BrowsingContext const&, Web::DOM::ShadowRoot const&); bool represents_a_shadow_root(JsonValue const&); bool represents_a_shadow_root(JS::Value); diff --git a/Libraries/LibWeb/WebDriver/Error.cpp b/Libraries/LibWeb/WebDriver/Error.cpp index ad585dd357b..f4e347255ff 100644 --- a/Libraries/LibWeb/WebDriver/Error.cpp +++ b/Libraries/LibWeb/WebDriver/Error.cpp @@ -13,43 +13,43 @@ namespace Web::WebDriver { struct ErrorCodeData { ErrorCode error_code; unsigned http_status; - ByteString json_error_code; + String json_error_code; }; // https://w3c.github.io/webdriver/#dfn-error-code static Vector const s_error_code_data = { - { ErrorCode::ElementClickIntercepted, 400, "element click intercepted" }, - { ErrorCode::ElementNotInteractable, 400, "element not interactable" }, - { ErrorCode::InsecureCertificate, 400, "insecure certificate" }, - { ErrorCode::InvalidArgument, 400, "invalid argument" }, - { ErrorCode::InvalidCookieDomain, 400, "invalid cookie domain" }, - { ErrorCode::InvalidElementState, 400, "invalid element state" }, - { ErrorCode::InvalidSelector, 400, "invalid selector" }, - { ErrorCode::InvalidSessionId, 404, "invalid session id" }, - { ErrorCode::JavascriptError, 500, "javascript error" }, - { ErrorCode::MoveTargetOutOfBounds, 500, "move target out of bounds" }, - { ErrorCode::NoSuchAlert, 404, "no such alert" }, - { ErrorCode::NoSuchCookie, 404, "no such cookie" }, - { ErrorCode::NoSuchElement, 404, "no such element" }, - { ErrorCode::NoSuchFrame, 404, "no such frame" }, - { ErrorCode::NoSuchWindow, 404, "no such window" }, - { ErrorCode::NoSuchShadowRoot, 404, "no such shadow root" }, - { ErrorCode::ScriptTimeoutError, 500, "script timeout" }, - { ErrorCode::SessionNotCreated, 500, "session not created" }, - { ErrorCode::StaleElementReference, 404, "stale element reference" }, - { ErrorCode::DetachedShadowRoot, 404, "detached shadow root" }, - { ErrorCode::Timeout, 500, "timeout" }, - { ErrorCode::UnableToSetCookie, 500, "unable to set cookie" }, - { ErrorCode::UnableToCaptureScreen, 500, "unable to capture screen" }, - { ErrorCode::UnexpectedAlertOpen, 500, "unexpected alert open" }, - { ErrorCode::UnknownCommand, 404, "unknown command" }, - { ErrorCode::UnknownError, 500, "unknown error" }, - { ErrorCode::UnknownMethod, 405, "unknown method" }, - { ErrorCode::UnsupportedOperation, 500, "unsupported operation" }, - { ErrorCode::OutOfMemory, 500, "out of memory" }, + { ErrorCode::ElementClickIntercepted, 400, "element click intercepted"_string }, + { ErrorCode::ElementNotInteractable, 400, "element not interactable"_string }, + { ErrorCode::InsecureCertificate, 400, "insecure certificate"_string }, + { ErrorCode::InvalidArgument, 400, "invalid argument"_string }, + { ErrorCode::InvalidCookieDomain, 400, "invalid cookie domain"_string }, + { ErrorCode::InvalidElementState, 400, "invalid element state"_string }, + { ErrorCode::InvalidSelector, 400, "invalid selector"_string }, + { ErrorCode::InvalidSessionId, 404, "invalid session id"_string }, + { ErrorCode::JavascriptError, 500, "javascript error"_string }, + { ErrorCode::MoveTargetOutOfBounds, 500, "move target out of bounds"_string }, + { ErrorCode::NoSuchAlert, 404, "no such alert"_string }, + { ErrorCode::NoSuchCookie, 404, "no such cookie"_string }, + { ErrorCode::NoSuchElement, 404, "no such element"_string }, + { ErrorCode::NoSuchFrame, 404, "no such frame"_string }, + { ErrorCode::NoSuchWindow, 404, "no such window"_string }, + { ErrorCode::NoSuchShadowRoot, 404, "no such shadow root"_string }, + { ErrorCode::ScriptTimeoutError, 500, "script timeout"_string }, + { ErrorCode::SessionNotCreated, 500, "session not created"_string }, + { ErrorCode::StaleElementReference, 404, "stale element reference"_string }, + { ErrorCode::DetachedShadowRoot, 404, "detached shadow root"_string }, + { ErrorCode::Timeout, 500, "timeout"_string }, + { ErrorCode::UnableToSetCookie, 500, "unable to set cookie"_string }, + { ErrorCode::UnableToCaptureScreen, 500, "unable to capture screen"_string }, + { ErrorCode::UnexpectedAlertOpen, 500, "unexpected alert open"_string }, + { ErrorCode::UnknownCommand, 404, "unknown command"_string }, + { ErrorCode::UnknownError, 500, "unknown error"_string }, + { ErrorCode::UnknownMethod, 405, "unknown method"_string }, + { ErrorCode::UnsupportedOperation, 500, "unsupported operation"_string }, + { ErrorCode::OutOfMemory, 500, "out of memory"_string }, }; -Error Error::from_code(ErrorCode code, ByteString message, Optional data) +Error Error::from_code(ErrorCode code, String message, Optional data) { auto const& error_code_data = s_error_code_data[to_underlying(code)]; @@ -61,13 +61,18 @@ Error Error::from_code(ErrorCode code, ByteString message, Optional d }; } +Error Error::from_code(ErrorCode code, StringView message, Optional data) +{ + return from_code(code, String::from_utf8_without_validation(message.bytes()), move(data)); +} + Error::Error(AK::Error const& error) { VERIFY(error.code() == ENOMEM); - *this = from_code(ErrorCode::OutOfMemory, {}, {}); + *this = from_code(ErrorCode::OutOfMemory, String {}, {}); } -Error::Error(unsigned http_status_, ByteString error_, ByteString message_, Optional data_) +Error::Error(unsigned http_status_, String error_, String message_, Optional data_) : http_status(http_status_) , error(move(error_)) , message(move(message_)) diff --git a/Libraries/LibWeb/WebDriver/Error.h b/Libraries/LibWeb/WebDriver/Error.h index 31b216ad0e7..ed8c3720008 100644 --- a/Libraries/LibWeb/WebDriver/Error.h +++ b/Libraries/LibWeb/WebDriver/Error.h @@ -7,8 +7,8 @@ #pragma once -#include #include +#include namespace Web::WebDriver { @@ -50,13 +50,14 @@ enum class ErrorCode { // https://w3c.github.io/webdriver/#errors struct Error { unsigned http_status; - ByteString error; - ByteString message; + String error; + String message; Optional data; - static Error from_code(ErrorCode, ByteString message, Optional data = {}); + static Error from_code(ErrorCode, String message, Optional data = {}); + static Error from_code(ErrorCode, StringView message, Optional data = {}); - Error(unsigned http_status, ByteString error, ByteString message, Optional data); + Error(unsigned http_status, String error, String message, Optional data); Error(AK::Error const&); }; @@ -66,6 +67,6 @@ template<> struct AK::Formatter : Formatter { ErrorOr format(FormatBuilder& builder, Web::WebDriver::Error const& error) { - return Formatter::format(builder, ByteString::formatted("Error {}, {}: {}", error.http_status, error.error, error.message)); + return Formatter::format(builder, MUST(String::formatted("Error {}, {}: {}", error.http_status, error.error, error.message))); } }; diff --git a/Libraries/LibWeb/WebDriver/ExecuteScript.cpp b/Libraries/LibWeb/WebDriver/ExecuteScript.cpp index 95b39c0986a..a25e56c8ebd 100644 --- a/Libraries/LibWeb/WebDriver/ExecuteScript.cpp +++ b/Libraries/LibWeb/WebDriver/ExecuteScript.cpp @@ -22,7 +22,7 @@ namespace Web::WebDriver { // https://w3c.github.io/webdriver/#dfn-execute-a-function-body -static JS::ThrowCompletionOr execute_a_function_body(HTML::BrowsingContext const& browsing_context, ByteString const& body, ReadonlySpan parameters) +static JS::ThrowCompletionOr execute_a_function_body(HTML::BrowsingContext const& browsing_context, StringView body, ReadonlySpan parameters) { // 1. Let window be the associated window of the current browsing context’s active document. auto window = browsing_context.active_document()->window(); @@ -84,7 +84,7 @@ static JS::ThrowCompletionOr execute_a_function_body(HTML::BrowsingCo return completion; } -void execute_script(HTML::BrowsingContext const& browsing_context, ByteString body, GC::RootVector arguments, Optional const& timeout_ms, GC::Ref on_complete) +void execute_script(HTML::BrowsingContext const& browsing_context, String body, GC::RootVector arguments, Optional const& timeout_ms, GC::Ref on_complete) { auto const* document = browsing_context.active_document(); auto& realm = document->realm(); @@ -142,7 +142,7 @@ void execute_script(HTML::BrowsingContext const& browsing_context, ByteString bo } // https://w3c.github.io/webdriver/#execute-async-script -void execute_async_script(HTML::BrowsingContext const& browsing_context, ByteString body, GC::RootVector arguments, Optional const& timeout_ms, GC::Ref on_complete) +void execute_async_script(HTML::BrowsingContext const& browsing_context, String body, GC::RootVector arguments, Optional const& timeout_ms, GC::Ref on_complete) { auto const* document = browsing_context.active_document(); auto& realm = document->realm(); diff --git a/Libraries/LibWeb/WebDriver/ExecuteScript.h b/Libraries/LibWeb/WebDriver/ExecuteScript.h index f6c35998953..94c60ba1445 100644 --- a/Libraries/LibWeb/WebDriver/ExecuteScript.h +++ b/Libraries/LibWeb/WebDriver/ExecuteScript.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include #include #include @@ -23,7 +24,7 @@ struct ExecutionResult { using OnScriptComplete = GC::Function; -void execute_script(HTML::BrowsingContext const&, ByteString body, GC::RootVector arguments, Optional const& timeout_ms, GC::Ref on_complete); -void execute_async_script(HTML::BrowsingContext const&, ByteString body, GC::RootVector arguments, Optional const& timeout_ms, GC::Ref on_complete); +void execute_script(HTML::BrowsingContext const&, String body, GC::RootVector arguments, Optional const& timeout_ms, GC::Ref on_complete); +void execute_async_script(HTML::BrowsingContext const&, String body, GC::RootVector arguments, Optional const& timeout_ms, GC::Ref on_complete); } diff --git a/Libraries/LibWeb/WebDriver/InputSource.cpp b/Libraries/LibWeb/WebDriver/InputSource.cpp index 5506b988b01..ca162814dfa 100644 --- a/Libraries/LibWeb/WebDriver/InputSource.cpp +++ b/Libraries/LibWeb/WebDriver/InputSource.cpp @@ -176,7 +176,7 @@ ErrorOr get_or_create_input_source(InputState& i // FIXME: Spec issue: It does not make sense to check if "source is a pointer input source". This would errantly // prevent the ability to perform two pointer actions in a row. // https://github.com/w3c/webdriver/issues/1810 - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' does not match existing input source type"); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, "Property 'type' does not match existing input source type"sv); } // 3. If source is undefined, set source to the result of trying to create an input source with input state and type. diff --git a/Libraries/LibWeb/WebDriver/JSON.cpp b/Libraries/LibWeb/WebDriver/JSON.cpp index fde387030ad..c21f9d13555 100644 --- a/Libraries/LibWeb/WebDriver/JSON.cpp +++ b/Libraries/LibWeb/WebDriver/JSON.cpp @@ -30,14 +30,14 @@ namespace Web::WebDriver { -#define TRY_OR_JS_ERROR(expression) \ - ({ \ - auto&& _temporary_result = (expression); \ - if (_temporary_result.is_error()) [[unlikely]] \ - return WebDriver::Error::from_code(ErrorCode::JavascriptError, "Script returned an error"); \ - static_assert(!::AK::Detail::IsLvalueReference, \ - "Do not return a reference from a fallible expression"); \ - _temporary_result.release_value(); \ +#define TRY_OR_JS_ERROR(expression) \ + ({ \ + auto&& _temporary_result = (expression); \ + if (_temporary_result.is_error()) [[unlikely]] \ + return WebDriver::Error::from_code(ErrorCode::JavascriptError, "Script returned an error"sv); \ + static_assert(!::AK::Detail::IsLvalueReference, \ + "Do not return a reference from a fallible expression"); \ + _temporary_result.release_value(); \ }) using SeenMap = HashTable>; @@ -120,7 +120,7 @@ static ErrorOr clone_an_object(HTML::BrowsingConte // script to be run and that script throws an error, return error with error code javascript error. auto source_property_value = value.get(name); if (source_property_value.is_error()) { - error = WebDriver::Error::from_code(ErrorCode::JavascriptError, "Script returned an error"); + error = WebDriver::Error::from_code(ErrorCode::JavascriptError, "Script returned an error"sv); return JS::normal_completion({}); } @@ -183,7 +183,7 @@ static Response internal_json_clone(HTML::BrowsingContext const& browsing_contex if (value.is_number()) return JsonValue { value.as_double() }; if (value.is_string()) - return JsonValue { value.as_string().byte_string() }; + return JsonValue { value.as_string().utf8_string() }; // AD-HOC: BigInt and Symbol not mentioned anywhere in the WebDriver spec, as it references ES5. // It assumes that all primitives are handled above, and the value is an object for the remaining steps. @@ -257,7 +257,7 @@ static Response internal_json_clone(HTML::BrowsingContext const& browsing_contex if (!to_json_result.is_string()) return WebDriver::Error::from_code(ErrorCode::JavascriptError, "toJSON did not return a String"sv); - return JsonValue { to_json_result.as_string().byte_string() }; + return JsonValue { to_json_result.as_string().utf8_string() }; } // -> Otherwise diff --git a/Libraries/LibWeb/WebDriver/Properties.h b/Libraries/LibWeb/WebDriver/Properties.h index 80a1a2806a1..e22fa7d473d 100644 --- a/Libraries/LibWeb/WebDriver/Properties.h +++ b/Libraries/LibWeb/WebDriver/Properties.h @@ -6,22 +6,22 @@ #pragma once -#include #include #include #include +#include #include #include namespace Web::WebDriver { -template +template static ErrorOr get_property(JsonObject const& payload, StringView key) { auto property = payload.get(key); if (!property.has_value()) - return WebDriver::Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("No property called '{}' present", key)); + return WebDriver::Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("No property called '{}' present", key))); auto is_safe_number = [](T value) { if constexpr (sizeof(T) >= 8) { @@ -37,29 +37,29 @@ static ErrorOr get_property(JsonObject const& pa return true; }; - if constexpr (IsSame) { + if constexpr (IsSame) { if (!property->is_string()) - return WebDriver::Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' is not a String", key)); - return property->as_string().to_byte_string(); + return WebDriver::Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("Property '{}' is not a String", key))); + return property->as_string(); } else if constexpr (IsSame) { if (!property->is_bool()) - return WebDriver::Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' is not a Boolean", key)); + return WebDriver::Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("Property '{}' is not a Boolean", key))); return property->as_bool(); } else if constexpr (IsIntegral) { if (auto maybe_number = property->get_integer(); maybe_number.has_value() && is_safe_number(*maybe_number)) return *maybe_number; - return WebDriver::Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' is not an Integer", key)); + return WebDriver::Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("Property '{}' is not an Integer", key))); } else if constexpr (IsSame) { if (auto maybe_number = property->get_double_with_precision_loss(); maybe_number.has_value() && is_safe_number(*maybe_number)) return *maybe_number; - return WebDriver::Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' is not a Number", key)); + return WebDriver::Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("Property '{}' is not a Number", key))); } else if constexpr (IsSame) { if (!property->is_array()) - return WebDriver::Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' is not an Array", key)); + return WebDriver::Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("Property '{}' is not an Array", key))); return &property->as_array(); } else if constexpr (IsSame) { if (!property->is_object()) - return WebDriver::Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' is not an Object", key)); + return WebDriver::Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("Property '{}' is not an Object", key))); return &property->as_object(); } else { static_assert(DependentFalse, "get_property invoked with unknown property type"); @@ -67,15 +67,15 @@ static ErrorOr get_property(JsonObject const& pa } } -template +template static ErrorOr get_property(JsonValue const& payload, StringView key) { if (!payload.is_object()) - return WebDriver::Error::from_code(ErrorCode::InvalidArgument, "Payload is not a JSON object"); + return WebDriver::Error::from_code(ErrorCode::InvalidArgument, "Payload is not a JSON object"sv); return get_property(payload.as_object(), key); } -template +template static ErrorOr, WebDriver::Error> get_optional_property(JsonObject const& object, StringView key) { if (!object.has(key)) @@ -89,9 +89,9 @@ static ErrorOr get_property_with_limits(JsonObje auto value = TRY(get_property(object, key)); if (min.has_value() && value < *min) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' must not be less than {}", key, *min)); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Property '{}' must not be less than {}", key, *min))); if (max.has_value() && value > *max) - return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' must not be greater than {}", key, *max)); + return WebDriver::Error::from_code(WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Property '{}' must not be greater than {}", key, *max))); return value; } diff --git a/Libraries/LibWeb/WebDriver/Response.cpp b/Libraries/LibWeb/WebDriver/Response.cpp index 0e8cba136c0..692a363fabf 100644 --- a/Libraries/LibWeb/WebDriver/Response.cpp +++ b/Libraries/LibWeb/WebDriver/Response.cpp @@ -58,8 +58,8 @@ ErrorOr IPC::decode(Decoder& decoder) case ResponseType::Error: { auto http_status = TRY(decoder.decode()); - auto error = TRY(decoder.decode()); - auto message = TRY(decoder.decode()); + auto error = TRY(decoder.decode()); + auto message = TRY(decoder.decode()); auto data = TRY(decoder.decode>()); return Web::WebDriver::Error { http_status, move(error), move(message), move(data) }; diff --git a/Libraries/LibWeb/WebDriver/Screenshot.cpp b/Libraries/LibWeb/WebDriver/Screenshot.cpp index 58d991069c3..fb451cec201 100644 --- a/Libraries/LibWeb/WebDriver/Screenshot.cpp +++ b/Libraries/LibWeb/WebDriver/Screenshot.cpp @@ -85,7 +85,7 @@ Response encode_canvas_element(HTML::HTMLCanvasElement& canvas) auto encoded_string = MUST(data_url.substring_from_byte_offset(*index + 1)); // 7. Return success with data encoded string. - return JsonValue { encoded_string.to_byte_string() }; + return JsonValue { move(encoded_string) }; } } diff --git a/Libraries/LibWeb/WebDriver/TimeoutsConfiguration.cpp b/Libraries/LibWeb/WebDriver/TimeoutsConfiguration.cpp index 8c6516c1ae1..3238256f86f 100644 --- a/Libraries/LibWeb/WebDriver/TimeoutsConfiguration.cpp +++ b/Libraries/LibWeb/WebDriver/TimeoutsConfiguration.cpp @@ -46,7 +46,7 @@ ErrorOr json_deserialize_as_a_timeouts_configuration_into(JsonValue { // 1. Set timeouts to the result of converting a JSON-derived JavaScript value to an Infra value with timeouts. if (!timeouts.is_object()) - return Error::from_code(ErrorCode::InvalidArgument, "Payload is not a JSON object"); + return Error::from_code(ErrorCode::InvalidArgument, "Payload is not a JSON object"sv); // 3. For each key → value in timeouts: TRY(timeouts.as_object().try_for_each_member([&](auto const& key, JsonValue const& value) -> ErrorOr { @@ -62,7 +62,7 @@ ErrorOr json_deserialize_as_a_timeouts_configuration_into(JsonValue auto duration = value.get_integer(); if (!duration.has_value() || *duration > JS::MAX_ARRAY_LIKE_INDEX) - return Error::from_code(ErrorCode::InvalidArgument, "Invalid timeout value"); + return Error::from_code(ErrorCode::InvalidArgument, "Invalid timeout value"sv); parsed_value = static_cast(*duration); } diff --git a/Libraries/LibWeb/WebDriver/UserPrompt.cpp b/Libraries/LibWeb/WebDriver/UserPrompt.cpp index fb2fbd1feec..c1d9f362ca9 100644 --- a/Libraries/LibWeb/WebDriver/UserPrompt.cpp +++ b/Libraries/LibWeb/WebDriver/UserPrompt.cpp @@ -71,7 +71,7 @@ static constexpr PromptType prompt_type_from_string(StringView prompt_type) PromptHandlerConfiguration PromptHandlerConfiguration::deserialize(JsonValue const& configuration) { - auto handler = prompt_handler_from_string(*configuration.as_object().get_byte_string("handler"sv)); + auto handler = prompt_handler_from_string(*configuration.as_object().get_string("handler"sv)); auto notify = *configuration.as_object().get_bool("notify"sv) ? PromptHandlerConfiguration::Notify::Yes @@ -138,7 +138,7 @@ Response deserialize_as_an_unhandled_prompt_behavior(JsonValue value) TRY(value.as_object().try_for_each_member([&](String const& prompt_type, JsonValue const& handler_value) -> ErrorOr { // 1. If is string value is false and valid prompt types does not contain prompt type return error with error code invalid argument. if (!is_string_value && !valid_prompt_types.contains_slow(prompt_type)) - return WebDriver::Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("'{}' is not a valid prompt type", prompt_type)); + return WebDriver::Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("'{}' is not a valid prompt type", prompt_type))); // 2. If known prompt handlers does not contain an entry with handler key handler return error with error code invalid argument. if (!handler_value.is_string()) @@ -147,7 +147,7 @@ Response deserialize_as_an_unhandled_prompt_behavior(JsonValue value) StringView handler = handler_value.as_string(); if (!known_prompt_handlers.contains_slow(handler)) - return WebDriver::Error::from_code(ErrorCode::InvalidArgument, ByteString::formatted("'{}' is not a known prompt handler", handler)); + return WebDriver::Error::from_code(ErrorCode::InvalidArgument, MUST(String::formatted("'{}' is not a known prompt handler", handler))); // 3. Let notify be false. bool notify = false; diff --git a/Services/WebContent/WebDriverConnection.cpp b/Services/WebContent/WebDriverConnection.cpp index 69c9f151d14..f46a35f5da4 100644 --- a/Services/WebContent/WebDriverConnection.cpp +++ b/Services/WebContent/WebDriverConnection.cpp @@ -282,15 +282,13 @@ Messages::WebDriverClient::SetTimeoutsResponse WebDriverConnection::set_timeouts // 10.1 Navigate To, https://w3c.github.io/webdriver/#navigate-to Messages::WebDriverClient::NavigateToResponse WebDriverConnection::navigate_to(JsonValue const& payload) { - dbgln_if(WEBDRIVER_DEBUG, "WebDriverConnection::navigate_to {}", payload); - // 1. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_current_top_level_browsing_context_is_open()); // 2. Let url be the result of getting the property url from the parameters argument. if (!payload.is_object() || !payload.as_object().has_string("url"sv)) return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload doesn't have a string `url`"sv); - auto url = URL::Parser::basic_parse(payload.as_object().get_byte_string("url"sv).value()); + auto url = URL::Parser::basic_parse(payload.as_object().get_string("url"sv).value()); // FIXME: 3. If url is not an absolute URL or is not an absolute URL with fragment or not a local scheme, return error with error code invalid argument. @@ -335,8 +333,6 @@ Messages::WebDriverClient::NavigateToResponse WebDriverConnection::navigate_to(J // 10.2 Get Current URL, https://w3c.github.io/webdriver/#get-current-url Messages::WebDriverClient::GetCurrentUrlResponse WebDriverConnection::get_current_url() { - dbgln_if(WEBDRIVER_DEBUG, "WebDriverConnection::get_current_url"); - // 1. If the current top-level browsing context is no longer open, return error with error code no such window. TRY(ensure_current_top_level_browsing_context_is_open()); @@ -589,7 +585,7 @@ Messages::WebDriverClient::SwitchToWindowResponse WebDriverConnection::switch_to } if (!found_matching_context) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchWindow, "Window not found"); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchWindow, "Window not found"sv); // 5. Update any implementation-specific state that would result from the user selecting the current // browsing context for interaction, without altering OS-level focus. @@ -610,7 +606,7 @@ Messages::WebDriverClient::NewWindowResponse WebDriverConnection::new_window(Jso handle_any_user_prompts([this, payload = move(const_cast(payload))]() { // 4. Let type hint be the result of getting the property "type" from the parameters argument. if (!payload.is_object()) { - async_driver_execution_complete(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"sv)); return; } @@ -688,7 +684,7 @@ Messages::WebDriverClient::SwitchToFrameResponse WebDriverConnection::switch_to_ auto id_value = id.get_integer(); if (!id_value.has_value()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Frame ID {} is invalid", id)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Frame ID {} is invalid", id))); // 2. 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()); @@ -704,7 +700,7 @@ Messages::WebDriverClient::SwitchToFrameResponse WebDriverConnection::switch_to_ auto property = window->get(id); if (property.is_error() || !property.value().is_object() || !is(property.value().as_object())) { - async_driver_execution_complete(Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchFrame, ByteString::formatted("Frame ID {} not found", id))); + async_driver_execution_complete(Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchFrame, MUST(String::formatted("Frame ID {} not found", id)))); return; } @@ -802,7 +798,7 @@ Messages::WebDriverClient::GetWindowRectResponse WebDriverConnection::get_window Messages::WebDriverClient::SetWindowRectResponse WebDriverConnection::set_window_rect(JsonValue const& payload) { if (!payload.is_object()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload is not a JSON object"); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload is not a JSON object"sv); auto const& properties = payload.as_object(); @@ -812,11 +808,11 @@ Messages::WebDriverClient::SetWindowRectResponse WebDriverConnection::set_window auto value = property.get_double_with_precision_loss(); if (!value.has_value()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' is not a Number", name)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Property '{}' is not a Number", name))); if (*value < min) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' value {} exceeds the minimum allowed value {}", name, *value, min)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Property '{}' value {} exceeds the minimum allowed value {}", name, *value, min))); if (*value > max) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Property '{}' value {} exceeds the maximum allowed value {}", name, *value, max)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Property '{}' value {} exceeds the maximum allowed value {}", name, *value, max))); return value; }; @@ -990,7 +986,7 @@ Messages::WebDriverClient::FindElementResponse WebDriverConnection::find_element // 2. If location strategy is not present as a keyword in the table of location strategies, return error with error // code invalid argument. if (!location_strategy.has_value()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Location strategy '{}' is invalid", location_strategy_string)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Location strategy '{}' is invalid", location_strategy_string))); // 3. Let selector be the result of getting a property named "value" from parameters. // 4. If selector is undefined, return error with error code invalid argument. @@ -1032,7 +1028,7 @@ Messages::WebDriverClient::FindElementsResponse WebDriverConnection::find_elemen // 2. If location strategy is not present as a keyword in the table of location strategies, return error with error // code invalid argument. if (!location_strategy.has_value()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Location strategy '{}' is invalid", location_strategy_string)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Location strategy '{}' is invalid", location_strategy_string))); // 3. Let selector be the result of getting a property named "value" from parameters. // 4. If selector is undefined, return error with error code invalid argument. @@ -1072,7 +1068,7 @@ Messages::WebDriverClient::FindElementFromElementResponse WebDriverConnection::f // 2. If location strategy is not present as a keyword in the table of location strategies, return error with error code invalid argument. if (!location_strategy.has_value()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Location strategy '{}' is invalid", location_strategy_string)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Location strategy '{}' is invalid", location_strategy_string))); // 3. Let selector be the result of getting a property named "value" from parameters. // 4. If selector is undefined, return error with error code invalid argument. @@ -1107,7 +1103,7 @@ Messages::WebDriverClient::FindElementsFromElementResponse WebDriverConnection:: // 2. If location strategy is not present as a keyword in the table of location strategies, return error with error code invalid argument. if (!location_strategy.has_value()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Location strategy '{}' is invalid", location_strategy_string)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Location strategy '{}' is invalid", location_strategy_string))); // 3. Let selector be the result of getting a property named "value" from parameters. // 4. If selector is undefined, return error with error code invalid argument. @@ -1141,7 +1137,7 @@ Messages::WebDriverClient::FindElementFromShadowRootResponse WebDriverConnection // 2. If location strategy is not present as a keyword in the table of location strategies, return error with error code invalid argument. if (!location_strategy.has_value()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Location strategy '{}' is invalid", location_strategy_string)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Location strategy '{}' is invalid", location_strategy_string))); // 3. Let selector be the result of getting a property called "value". // 4. If selector is undefined, return error with error code invalid argument. @@ -1176,7 +1172,7 @@ Messages::WebDriverClient::FindElementsFromShadowRootResponse WebDriverConnectio // 2. If location strategy is not present as a keyword in the table of location strategies, return error with error code invalid argument. if (!location_strategy.has_value()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("Location strategy '{}' is invalid", location_strategy_string)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("Location strategy '{}' is invalid", location_strategy_string))); // 3. Let selector be the result of getting a property called "value". // 4. If selector is undefined, return error with error code invalid argument. @@ -1242,7 +1238,7 @@ Messages::WebDriverClient::GetElementShadowRootResponse WebDriverConnection::get // 5. If shadow root is null, return error with error code no such shadow root. if (!shadow_root) { - 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))); + async_driver_execution_complete(Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchShadowRoot, MUST(String::formatted("Element with ID '{}' does not have a shadow root", element_id)))); return; } @@ -1697,8 +1693,7 @@ Web::WebDriver::Response WebDriverConnection::element_click_impl(String const& e pointer_move_action.pointer_move_fields().position = { 0, 0 }; // 10. Set a property origin to element on pointer move action. - auto origin = Web::WebDriver::get_or_create_a_web_element_reference(current_browsing_context(), *element); - pointer_move_action.pointer_move_fields().origin = MUST(String::from_byte_string(origin)); + pointer_move_action.pointer_move_fields().origin = Web::WebDriver::get_or_create_a_web_element_reference(current_browsing_context(), *element); // 11. Let pointer down action be an action object constructed with arguments input id, "pointer", and "pointerDown". Web::WebDriver::ActionObject pointer_down_action { input_id, Web::WebDriver::InputSourceType::Pointer, Web::WebDriver::ActionObject::Subtype::PointerDown }; @@ -1858,7 +1853,7 @@ Messages::WebDriverClient::ElementSendKeysResponse WebDriverConnection::element_ return JsonValue {}; } -Web::WebDriver::Response WebDriverConnection::element_send_keys_impl(String const& element_id, ByteString const& text) +Web::WebDriver::Response WebDriverConnection::element_send_keys_impl(String const& element_id, String const& text) { // 5. 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)); @@ -1895,7 +1890,7 @@ Web::WebDriver::Response WebDriverConnection::element_send_keys_impl(String cons auto& input_element = static_cast(*element); // 1. Let files be the result of splitting text on the newline (\n) character. - auto files = text.split('\n'); + auto files = MUST(text.split('\n')); // 2. If files is of 0 length, return an error with error code invalid argument. if (files.is_empty()) @@ -1922,9 +1917,9 @@ Web::WebDriver::Response WebDriverConnection::element_send_keys_impl(String cons selected_files.ensure_capacity(files.size()); for (auto const& path : files) { - auto selected_file = create_selected_file(path); + auto selected_file = create_selected_file(path.bytes_as_string_view()); if (selected_file.is_error()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, ByteString::formatted("'{}' does not exist", path)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, MUST(String::formatted("'{}' does not exist", path))); selected_files.unchecked_append(selected_file.release_value()); } @@ -1956,7 +1951,7 @@ Web::WebDriver::Response WebDriverConnection::element_send_keys_impl(String cons return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::ElementNotInteractable, "Element is immutable"sv); // 3. Set a property value to text on element. - MUST(input_element.set_value(MUST(String::from_byte_string(text)))); + MUST(input_element.set_value(text)); // FIXME: 4. If element is suffering from bad input return an error with error code invalid argument. @@ -2124,7 +2119,7 @@ void WebDriverConnection::handle_script_response(Web::WebDriver::ExecutionResult // 10. If promise is still pending and timer's timeout fired flag is set, return error with error code script // timeout. case JS::Promise::State::Pending: - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::ScriptTimeoutError, "Script timed out"); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::ScriptTimeoutError, "Script timed out"sv); // 11. If promise is fulfilled with value v, let result be JSON clone with session and v, and return success // with data result. @@ -2135,7 +2130,7 @@ void WebDriverConnection::handle_script_response(Web::WebDriver::ExecutionResult // with error code javascript error and data result. case JS::Promise::State::Rejected: { auto reason = TRY(Web::WebDriver::json_clone(current_browsing_context(), result.value)); - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::JavascriptError, "Script returned an error", move(reason)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::JavascriptError, "Script returned an error"sv, move(reason)); } } @@ -2192,7 +2187,7 @@ Messages::WebDriverClient::GetNamedCookieResponse WebDriverConnection::get_named } // 4. Otherwise, return error with error code no such cookie. - async_driver_execution_complete(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, MUST(String::formatted("Cookie '{}' not found", name)))); }); return JsonValue {}; @@ -2235,13 +2230,13 @@ Web::WebDriver::Response WebDriverConnection::add_cookie_impl(JsonObject const& // 7. Create a cookie in the cookie store associated with the active document’s address using cookie name name, cookie value value, and an attribute-value list of the following cookie concepts listed in the table for cookie conversion from data: Web::Cookie::ParsedCookie cookie {}; - cookie.name = MUST(String::from_byte_string(TRY(Web::WebDriver::get_property(data, "name"sv)))); - cookie.value = MUST(String::from_byte_string(TRY(Web::WebDriver::get_property(data, "value"sv)))); + cookie.name = TRY(Web::WebDriver::get_property(data, "name"sv)); + cookie.value = TRY(Web::WebDriver::get_property(data, "value"sv)); // Cookie path // The value if the entry exists, otherwise "/". if (data.has("path"sv)) - cookie.path = MUST(String::from_byte_string(TRY(Web::WebDriver::get_property(data, "path"sv)))); + cookie.path = TRY(Web::WebDriver::get_property(data, "path"sv)); else cookie.path = "/"_string; @@ -2249,7 +2244,7 @@ Web::WebDriver::Response WebDriverConnection::add_cookie_impl(JsonObject const& // The value if the entry exists, otherwise the current browsing context’s active document’s URL domain. // NOTE: The otherwise case is handled by the CookieJar if (data.has("domain"sv)) { - cookie.domain = MUST(String::from_byte_string(TRY(Web::WebDriver::get_property(data, "domain"sv)))); + cookie.domain = TRY(Web::WebDriver::get_property(data, "domain"sv)); // FIXME: Spec issue: We must return InvalidCookieDomain for invalid domains, rather than InvalidArgument. // https://github.com/w3c/webdriver/issues/1570 @@ -2504,7 +2499,7 @@ Messages::WebDriverClient::SendAlertTextResponse WebDriverConnection::send_alert } // 6. Perform user agent dependent steps to set the value of current user prompt’s text field to text. - current_browsing_context().page().client().page_did_request_set_prompt_text(TRY(String::from_byte_string(text))); + current_browsing_context().page().client().page_did_request_set_prompt_text(text); // 7. Return success with data null. return JsonValue {}; @@ -2932,7 +2927,7 @@ public: ElementLocator( Web::HTML::BrowsingContext const& browsing_context, Web::WebDriver::LocationStrategy location_strategy, - ByteString selector, + String selector, WebDriverConnection::GetStartNode get_start_node, WebDriverConnection::OnFindComplete on_complete, GC::Ref timer) @@ -2970,7 +2965,7 @@ private: // 2. If a DOMException, SyntaxError, XPathException, or other error occurs during the execution of the element // location strategy, return error invalid selector. if (maybe_elements.is_error()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSelector, ByteString::formatted("The location strategy could not finish: {}", maybe_elements.error().message)); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSelector, MUST(String::formatted("The location strategy could not finish: {}", maybe_elements.error().message))); if (auto elements = maybe_elements.release_value(); elements->length() > 0) { // 8. Let result be an empty List. @@ -3001,7 +2996,7 @@ private: GC::Ref m_browsing_context; Web::WebDriver::LocationStrategy m_location_strategy; - ByteString m_selector; + String m_selector; WebDriverConnection::GetStartNode m_get_start_node; WebDriverConnection::OnFindComplete m_on_complete; @@ -3012,7 +3007,7 @@ private: GC_DEFINE_ALLOCATOR(ElementLocator); // https://w3c.github.io/webdriver/#dfn-find -void WebDriverConnection::find(Web::WebDriver::LocationStrategy location_strategy, ByteString selector, GetStartNode get_start_node, OnFindComplete on_complete) +void WebDriverConnection::find(Web::WebDriver::LocationStrategy location_strategy, String selector, GetStartNode get_start_node, OnFindComplete on_complete) { auto& realm = current_browsing_context().active_document()->realm(); diff --git a/Services/WebContent/WebDriverConnection.h b/Services/WebContent/WebDriverConnection.h index b333f8b50c0..4624aa38cba 100644 --- a/Services/WebContent/WebDriverConnection.h +++ b/Services/WebContent/WebDriverConnection.h @@ -123,7 +123,7 @@ private: 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, String const& text); Web::WebDriver::Response add_cookie_impl(JsonObject const&); Web::WebDriver::PromptHandlerConfiguration get_the_prompt_handler(Web::WebDriver::PromptType type) const; @@ -142,10 +142,10 @@ private: using GetStartNode = GC::Ref, Web::WebDriver::Error>()>>; using OnFindComplete = GC::Ref>; - void find(Web::WebDriver::LocationStrategy, ByteString, GetStartNode, OnFindComplete); + void find(Web::WebDriver::LocationStrategy, String, GetStartNode, OnFindComplete); struct ScriptArguments { - ByteString script; + String script; GC::RootVector arguments; }; ErrorOr extract_the_script_arguments_from_a_request(JS::VM&, JsonValue const& payload); diff --git a/Services/WebDriver/Client.cpp b/Services/WebDriver/Client.cpp index 7bfa075011d..54e1a71132e 100644 --- a/Services/WebDriver/Client.cpp +++ b/Services/WebDriver/Client.cpp @@ -68,7 +68,7 @@ Web::WebDriver::Response Client::new_session(Web::WebDriver::Parameters, JsonVal // 6. Let session be the result of create a session, with capabilities, and flags. auto maybe_session = Session::create(*this, capabilities.as_object(), flags); if (maybe_session.is_error()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::SessionNotCreated, ByteString::formatted("Failed to start session: {}", maybe_session.error())); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::SessionNotCreated, MUST(String::formatted("Failed to start session: {}", maybe_session.error()))); auto session = maybe_session.release_value(); @@ -258,14 +258,14 @@ Web::WebDriver::Response Client::switch_to_window(Web::WebDriver::Parameters par auto session = TRY(Session::find_session(parameters[0], Web::WebDriver::SessionFlags::Default, Session::AllowInvalidWindowHandle::Yes)); if (!payload.is_object()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload is not a JSON object"); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload is not a JSON object"sv); // 1. Let handle be the result of getting the property "handle" from the parameters argument. auto handle = payload.as_object().get("handle"sv); // 2. If handle is undefined, return error with error code invalid argument. if (!handle.has_value()) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "No property called 'handle' present"); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "No property called 'handle' present"sv); return session->switch_to_window(handle->as_string()); } @@ -300,7 +300,7 @@ Web::WebDriver::Response Client::new_window(Web::WebDriver::Parameters parameter }); if (timeout_fired) - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::Timeout, "Timed out waiting for window handle"); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::Timeout, "Timed out waiting for window handle"sv); return handle; } diff --git a/Services/WebDriver/Session.cpp b/Services/WebDriver/Session.cpp index 66b25f8a208..9f02b8ff0ea 100644 --- a/Services/WebDriver/Session.cpp +++ b/Services/WebDriver/Session.cpp @@ -73,7 +73,7 @@ ErrorOr> Session::create(NonnullRefPtr client, Js // 1. Let strategy be the result of getting property "pageLoadStrategy" from capabilities. If strategy is a // string, set the session's page loading strategy to strategy. Otherwise, set the page loading strategy to // normal and set a property of capabilities with name "pageLoadStrategy" and value "normal". - if (auto strategy = capabilities.get_byte_string("pageLoadStrategy"sv); strategy.has_value()) { + if (auto strategy = capabilities.get_string("pageLoadStrategy"sv); strategy.has_value()) { session->m_page_load_strategy = Web::WebDriver::page_load_strategy_from_string(*strategy); session->web_content_connection().async_set_page_load_strategy(session->m_page_load_strategy); } else { @@ -139,7 +139,7 @@ ErrorOr, Web::WebDriver::Error> Session::find_session(Str return *session.release_value(); } - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSessionId, "Invalid session id"); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSessionId, "Invalid session id"sv); } size_t Session::session_count(Web::WebDriver::SessionFlags session_flags) @@ -306,7 +306,7 @@ Web::WebDriver::Response Session::switch_to_window(StringView handle) if (auto it = m_windows.find(handle); it != m_windows.end()) m_current_window_handle = it->key; else - return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchWindow, "Window not found"); + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::NoSuchWindow, "Window not found"sv); // 5. Update any implementation-specific state that would result from the user selecting the current // browsing context for interaction, without altering OS-level focus.