LibWeb: Remove "serenity:" prefix from custom WebDriver capabilities

We currently define our custom WebDriver capabilities with a dictionary
of the form:

    "serenity:ladybird": {
        "headless": true
    }

This patch flattens the configuration, such that each Ladybird option
will be its own capability. This matches how Firefox configures their
own options with geckodriver. So we now have:

    "ladybird:headless": true
This commit is contained in:
Timothy Flynn 2025-02-07 12:11:38 -05:00 committed by Tim Flynn
commit 88eda159af
Notes: github-actions[bot] 2025-02-10 16:34:59 +00:00

View file

@ -65,25 +65,19 @@ void set_default_interface_mode(InterfaceMode interface_mode)
default_interface_mode = interface_mode; default_interface_mode = interface_mode;
} }
static Response deserialize_as_ladybird_options(JsonValue value) static Response deserialize_as_ladybird_capability(StringView name, JsonValue value)
{ {
if (!value.is_object()) if (name == "ladybird:headless"sv) {
return Error::from_code(ErrorCode::InvalidArgument, "Extension capability serenity:ladybird must be an object"sv); if (!value.is_bool())
return Error::from_code(ErrorCode::InvalidArgument, "Extension capability ladybird:headless must be a boolean"sv);
auto const& object = value.as_object(); }
if (auto headless = object.get("headless"sv); headless.has_value() && !headless->is_bool())
return Error::from_code(ErrorCode::InvalidArgument, "Extension capability serenity:ladybird/headless must be a boolean"sv);
return value; return value;
} }
static JsonObject default_ladybird_options() static void set_default_ladybird_capabilities(JsonObject& options)
{ {
JsonObject options; options.set("ladybird:headless"sv, default_interface_mode == InterfaceMode::Headless);
options.set("headless"sv, default_interface_mode == InterfaceMode::Headless);
return options;
} }
// https://w3c.github.io/webdriver/#dfn-validate-capabilities // https://w3c.github.io/webdriver/#dfn-validate-capabilities
@ -177,9 +171,8 @@ static ErrorOr<JsonObject, Error> validate_capabilities(JsonValue const& capabil
else if (name.contains(':')) { else if (name.contains(':')) {
// If name is known to the implementation, let deserialized be the result of trying to deserialize value in // If name is known to the implementation, let deserialized be the result of trying to deserialize value in
// an implementation-specific way. Otherwise, let deserialized be set to value. // an implementation-specific way. Otherwise, let deserialized be set to value.
if (name == "serenity:ladybird"sv) { if (name.starts_with("ladybird:"sv))
deserialized = TRY(deserialize_as_ladybird_options(value)); deserialized = TRY(deserialize_as_ladybird_capability(name, value));
}
} }
// -> The remote end is an endpoint node // -> The remote end is an endpoint node
@ -303,8 +296,9 @@ static JsonValue match_capabilities(JsonObject const& capabilities, SessionFlags
matched_capabilities.set("strictFileInteractability"sv, false); matched_capabilities.set("strictFileInteractability"sv, false);
} }
// 3. Optionally add extension capabilities as entries to matched capabilities. The values of these may be elided, and there is no requirement that all extension capabilities be added. // 3. Optionally add extension capabilities as entries to matched capabilities. The values of these may be elided,
matched_capabilities.set("serenity:ladybird"sv, default_ladybird_options()); // and there is no requirement that all extension capabilities be added.
set_default_ladybird_capabilities(matched_capabilities);
// 3. For each name and value corresponding to capabilities's own properties: // 3. For each name and value corresponding to capabilities's own properties:
auto result = capabilities.try_for_each_member([&](auto const& name, auto const& value) -> ErrorOr<void> { auto result = capabilities.try_for_each_member([&](auto const& name, auto const& value) -> ErrorOr<void> {
@ -466,13 +460,8 @@ Response process_capabilities(JsonValue const& parameters, SessionFlags flags)
LadybirdOptions::LadybirdOptions(JsonObject const& capabilities) LadybirdOptions::LadybirdOptions(JsonObject const& capabilities)
{ {
auto options = capabilities.get_object("serenity:ladybird"sv); if (auto headless = capabilities.get_bool("ladybird:headless"sv); headless.has_value())
if (!options.has_value()) this->headless = *headless;
return;
auto headless = options->get_bool("headless"sv);
if (headless.has_value())
this->headless = headless.value();
} }
} }