/*
 * Copyright (C) 2017 Igalia S.L.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "Session.h"

#include "CommandResult.h"
#include "SessionHost.h"
#include "WebDriverAtoms.h"
#include <wtf/CryptographicallyRandomNumber.h>
#include <wtf/FileSystem.h>
#include <wtf/HashSet.h>
#include <wtf/HexNumber.h>
#include <wtf/NeverDestroyed.h>
#include <wtf/text/MakeString.h>

namespace WebDriver {

// https://w3c.github.io/webdriver/webdriver-spec.html#dfn-session-script-timeout
static const double defaultScriptTimeout = 30000;
// https://w3c.github.io/webdriver/webdriver-spec.html#dfn-session-page-load-timeout
static const double defaultPageLoadTimeout = 300000;
// https://w3c.github.io/webdriver/webdriver-spec.html#dfn-session-implicit-wait-timeout
static const double defaultImplicitWaitTimeout = 0;

const String& Session::webElementIdentifier()
{
    // The web element identifier is a constant defined by the spec in Section 11 Elements.
    // https://www.w3.org/TR/webdriver/#elements
    static NeverDestroyed<String> webElementID { "element-6066-11e4-a52e-4f735466cecf"_s };
    return webElementID;
}

const String& Session::shadowRootIdentifier()
{
    // The shadow root identifier is constant defined by the spec.
    static NeverDestroyed<String> shadowRootID { "shadow-6066-11e4-a52e-4f735466cecf"_s };
    return shadowRootID;
}

Session::Session(std::unique_ptr<SessionHost>&& host)
    : m_host(WTFMove(host))
    , m_scriptTimeout(defaultScriptTimeout)
    , m_pageLoadTimeout(defaultPageLoadTimeout)
    , m_implicitWaitTimeout(defaultImplicitWaitTimeout)
{
    if (capabilities().timeouts)
        setTimeouts(capabilities().timeouts.value(), [](CommandResult&&) { });
}

Session::~Session()
{
}

const String& Session::id() const
{
    return m_host->sessionID();
}

const Capabilities& Session::capabilities() const
{
    return m_host->capabilities();
}

bool Session::isConnected() const
{
    return m_host->isConnected();
}

static std::optional<String> firstWindowHandleInResult(JSON::Value& result)
{
    auto handles = result.asArray();
    if (handles && handles->length()) {
        auto handle = handles->get(0)->asString();
        if (!!handle)
            return handle;
    }
    return std::nullopt;
}

void Session::closeAllToplevelBrowsingContexts(const String& toplevelBrowsingContext, Function<void (CommandResult&&)>&& completionHandler)
{
    closeTopLevelBrowsingContext(toplevelBrowsingContext, [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        if (auto handle = firstWindowHandleInResult(*result.result())) {
            closeAllToplevelBrowsingContexts(handle.value(), WTFMove(completionHandler));
            return;
        }
        completionHandler(CommandResult::success());
    });
}

void Session::close(Function<void (CommandResult&&)>&& completionHandler)
{
    m_toplevelBrowsingContext = std::nullopt;
    m_currentBrowsingContext = std::nullopt;
    m_currentParentBrowsingContext = std::nullopt;
    getWindowHandles([this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        if (auto handle = firstWindowHandleInResult(*result.result())) {
            closeAllToplevelBrowsingContexts(handle.value(), WTFMove(completionHandler));
            return;
        }
        completionHandler(CommandResult::success());
    });
}

void Session::getTimeouts(Function<void (CommandResult&&)>&& completionHandler)
{
    auto parameters = JSON::Object::create();
    if (m_scriptTimeout == std::numeric_limits<double>::infinity())
        parameters->setValue("script"_s, JSON::Value::null());
    else
        parameters->setDouble("script"_s, m_scriptTimeout);
    parameters->setDouble("pageLoad"_s, m_pageLoadTimeout);
    parameters->setDouble("implicit"_s, m_implicitWaitTimeout);
    completionHandler(CommandResult::success(WTFMove(parameters)));
}

void Session::setTimeouts(const Timeouts& timeouts, Function<void (CommandResult&&)>&& completionHandler)
{
    if (timeouts.script)
        m_scriptTimeout = timeouts.script.value();
    if (timeouts.pageLoad)
        m_pageLoadTimeout = timeouts.pageLoad.value();
    if (timeouts.implicit)
        m_implicitWaitTimeout = timeouts.implicit.value();
    completionHandler(CommandResult::success());
}

void Session::switchToTopLevelBrowsingContext(const String& toplevelBrowsingContext)
{
    m_toplevelBrowsingContext = toplevelBrowsingContext;
    m_currentBrowsingContext = String();
    m_currentParentBrowsingContext = String();
}

void Session::switchToBrowsingContext(const String& browsingContext, Function<void(CommandResult&&)>&& completionHandler)
{
    m_currentBrowsingContext = browsingContext;
    if (browsingContext.isEmpty()) {
        m_currentParentBrowsingContext = String();
        completionHandler(CommandResult::success());
        return;
    }

    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
    m_host->sendCommandToBackend("resolveParentFrameHandle"_s, WTFMove(parameters), [this, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (!response.isError && response.responseObject)
            m_currentParentBrowsingContext = response.responseObject->getString("result"_s);
        completionHandler(CommandResult::success());
    });
}

std::optional<String> Session::pageLoadStrategyString() const
{
    if (!capabilities().pageLoadStrategy)
        return std::nullopt;

    switch (capabilities().pageLoadStrategy.value()) {
    case PageLoadStrategy::None:
        return String("None"_s);
    case PageLoadStrategy::Normal:
        return String("Normal"_s);
    case PageLoadStrategy::Eager:
        return String("Eager"_s);
    }

    return std::nullopt;
}

void Session::createTopLevelBrowsingContext(Function<void (CommandResult&&)>&& completionHandler)
{
    ASSERT(!m_toplevelBrowsingContext);
    m_host->sendCommandToBackend("createBrowsingContext"_s, nullptr, [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
        if (response.isError || !response.responseObject) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }

        auto handle = response.responseObject->getString("handle"_s);
        if (!handle) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        switchToTopLevelBrowsingContext(handle);
        completionHandler(CommandResult::success());
    });
}

void Session::handleUserPrompts(Function<void (CommandResult&&)>&& completionHandler)
{
    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    m_host->sendCommandToBackend("isShowingJavaScriptDialog"_s, WTFMove(parameters), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
        if (response.isError || !response.responseObject) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }

        auto isShowingJavaScriptDialog = response.responseObject->getBoolean("result"_s);
        if (!isShowingJavaScriptDialog) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        if (!isShowingJavaScriptDialog.value()) {
            completionHandler(CommandResult::success());
            return;
        }

        handleUnexpectedAlertOpen(WTFMove(completionHandler));
    });
}

void Session::handleUnexpectedAlertOpen(Function<void (CommandResult&&)>&& completionHandler)
{
    switch (capabilities().unhandledPromptBehavior.value_or(UnhandledPromptBehavior::DismissAndNotify)) {
    case UnhandledPromptBehavior::Dismiss:
        dismissAlert(WTFMove(completionHandler));
        break;
    case UnhandledPromptBehavior::Accept:
        acceptAlert(WTFMove(completionHandler));
        break;
    case UnhandledPromptBehavior::DismissAndNotify:
        dismissAndNotifyAlert(WTFMove(completionHandler));
        break;
    case UnhandledPromptBehavior::AcceptAndNotify:
        acceptAndNotifyAlert(WTFMove(completionHandler));
        break;
    case UnhandledPromptBehavior::Ignore:
        reportUnexpectedAlertOpen(WTFMove(completionHandler));
        break;
    }
}

void Session::dismissAndNotifyAlert(Function<void (CommandResult&&)>&& completionHandler)
{
    reportUnexpectedAlertOpen([this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        dismissAlert([errorResult = WTFMove(result), completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
            if (result.isError()) {
                completionHandler(WTFMove(result));
                return;
            }
            completionHandler(WTFMove(errorResult));
        });
    });
}

void Session::acceptAndNotifyAlert(Function<void (CommandResult&&)>&& completionHandler)
{
    reportUnexpectedAlertOpen([this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        acceptAlert([errorResult = WTFMove(result), completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
            if (result.isError()) {
                completionHandler(WTFMove(result));
                return;
            }
            completionHandler(WTFMove(errorResult));
        });
    });
}

void Session::reportUnexpectedAlertOpen(Function<void (CommandResult&&)>&& completionHandler)
{
    getAlertText([completionHandler = WTFMove(completionHandler)](CommandResult&& result) {
        std::optional<String> alertText;
        if (!result.isError()) {
            auto valueString = result.result()->asString();
            if (!!valueString)
                alertText = valueString;
        }
        auto errorResult = CommandResult::fail(CommandResult::ErrorCode::UnexpectedAlertOpen);
        if (alertText) {
            auto additonalData = JSON::Object::create();
            additonalData->setString("text"_s, alertText.value());
            errorResult.setAdditionalErrorData(WTFMove(additonalData));
        }
        completionHandler(WTFMove(errorResult));
    });
}

void Session::go(const String& url, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, url, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        auto parameters = JSON::Object::create();
        parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
        parameters->setString("url"_s, url);
        parameters->setDouble("pageLoadTimeout"_s, m_pageLoadTimeout);
        if (auto pageLoadStrategy = pageLoadStrategyString())
            parameters->setString("pageLoadStrategy"_s, pageLoadStrategy.value());
        m_host->sendCommandToBackend("navigateBrowsingContext"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
            if (response.isError) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }
            switchToBrowsingContext({ }, WTFMove(completionHandler));
        });
    });
}

void Session::getCurrentURL(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        auto parameters = JSON::Object::create();
        parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
        m_host->sendCommandToBackend("getBrowsingContext"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto browsingContext = response.responseObject->getObject("context"_s);
            if (!browsingContext) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto url = browsingContext->getString("url"_s);
            if (!url) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(JSON::Value::create(url)));
        });
    });
}

void Session::back(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
        parameters->setDouble("pageLoadTimeout"_s, m_pageLoadTimeout);
        if (auto pageLoadStrategy = pageLoadStrategyString())
            parameters->setString("pageLoadStrategy"_s, pageLoadStrategy.value());
        m_host->sendCommandToBackend("goBackInBrowsingContext"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
            if (response.isError) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }
            switchToBrowsingContext({ }, WTFMove(completionHandler));
        });
    });
}

void Session::forward(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
        parameters->setDouble("pageLoadTimeout"_s, m_pageLoadTimeout);
        if (auto pageLoadStrategy = pageLoadStrategyString())
            parameters->setString("pageLoadStrategy"_s, pageLoadStrategy.value());
        m_host->sendCommandToBackend("goForwardInBrowsingContext"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
            if (response.isError) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }
            switchToBrowsingContext({ }, WTFMove(completionHandler));
        });
    });
}

void Session::refresh(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
        parameters->setDouble("pageLoadTimeout"_s, m_pageLoadTimeout);
        if (auto pageLoadStrategy = pageLoadStrategyString())
            parameters->setString("pageLoadStrategy"_s, pageLoadStrategy.value());
        m_host->sendCommandToBackend("reloadBrowsingContext"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
            if (response.isError) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }
            switchToBrowsingContext({ }, WTFMove(completionHandler));
        });
    });
}

void Session::getTitle(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        parameters->setString("function"_s, "function() { return document.title; }"_s);
        parameters->setArray("arguments"_s, JSON::Array::create());
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(WTFMove(resultValue)));
        });
    });
}

void Session::getWindowHandle(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    auto parameters = JSON::Object::create();
    parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
    m_host->sendCommandToBackend("getBrowsingContext"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError || !response.responseObject) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }

        auto browsingContext = response.responseObject->getObject("context"_s);
        if (!browsingContext) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        auto handle = browsingContext->getString("handle"_s);
        if (!handle) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        completionHandler(CommandResult::success(JSON::Value::create(handle)));
    });
}

void Session::closeTopLevelBrowsingContext(const String& toplevelBrowsingContext, Function<void (CommandResult&&)>&& completionHandler)
{
    auto parameters = JSON::Object::create();
    parameters->setString("handle"_s, toplevelBrowsingContext);
    m_host->sendCommandToBackend("closeBrowsingContext"_s, WTFMove(parameters), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
        if (!m_host->isConnected()) {
            // Closing the browsing context made the browser quit.
            completionHandler(CommandResult::success(JSON::Array::create()));
            return;
        }
        if (response.isError) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }

        getWindowHandles([this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) {
            if (!m_host->isConnected()) {
                // Closing the browsing context made the browser quit.
                completionHandler(CommandResult::success(JSON::Array::create()));
                return;
            }
            completionHandler(WTFMove(result));
        });
    });
}

void Session::closeWindow(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto toplevelBrowsingContext = std::exchange(m_toplevelBrowsingContext, std::nullopt);
        m_currentBrowsingContext = std::nullopt;
        m_currentParentBrowsingContext = std::nullopt;
        closeTopLevelBrowsingContext(toplevelBrowsingContext.value(), WTFMove(completionHandler));
    });
}

void Session::switchToBrowsingContext(const String& toplevelBrowsingContext, const String& browsingContext, Function<void(CommandResult&&)>&& completionHandler)
{
    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, toplevelBrowsingContext);
    parameters->setString("frameHandle"_s, browsingContext);
    m_host->sendCommandToBackend("switchToBrowsingContext"_s, WTFMove(parameters), [completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }
        completionHandler(CommandResult::success());
    });
}

void Session::switchToWindow(const String& windowHandle, Function<void(CommandResult&&)>&& completionHandler)
{
    switchToBrowsingContext(windowHandle, { }, [this, protectedThis = Ref { *this }, windowHandle, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        switchToTopLevelBrowsingContext(windowHandle);
        completionHandler(CommandResult::success());
    });
}

void Session::getWindowHandles(Function<void (CommandResult&&)>&& completionHandler)
{
    m_host->sendCommandToBackend("getBrowsingContexts"_s, JSON::Object::create(), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError || !response.responseObject) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }

        auto browsingContextArray = response.responseObject->getArray("contexts"_s);
        if (!browsingContextArray) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        auto windowHandles = JSON::Array::create();
        for (unsigned i = 0; i < browsingContextArray->length(); ++i) {
            auto browsingContext = browsingContextArray->get(i)->asObject();
            if (!browsingContext) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto handle = browsingContext->getString("handle"_s);
            if (!handle) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            windowHandles->pushString(handle);
        }
        completionHandler(CommandResult::success(WTFMove(windowHandles)));
    });
}

void Session::newWindow(std::optional<String> typeHint, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, typeHint, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        RefPtr<JSON::Object> parameters;
        if (typeHint) {
            parameters = JSON::Object::create();
            parameters->setString("presentationHint"_s, typeHint.value() == "window"_s ? "Window"_s : "Tab"_s);
        }
        m_host->sendCommandToBackend("createBrowsingContext"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto handle = response.responseObject->getString("handle"_s);
            if (!handle) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto presentation = response.responseObject->getString("presentation"_s);
            if (!presentation) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto result = JSON::Object::create();
            result->setString("handle"_s, handle);
            result->setString("type"_s, presentation == "Window"_s ? "window"_s : "tab"_s);
            completionHandler(CommandResult::success(WTFMove(result)));
        });
    });
}

void Session::switchToFrame(RefPtr<JSON::Value>&& frameID, Function<void (CommandResult&&)>&& completionHandler)
{
    if (frameID->isNull()) {
        if (!m_toplevelBrowsingContext) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
            return;
        }
        switchToBrowsingContext({ }, WTFMove(completionHandler));
        return;
    }

    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, frameID = WTFMove(frameID), completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());

        if (auto frameIndex = frameID->asInteger()) {
            ASSERT(*frameIndex >= 0 && *frameIndex < std::numeric_limits<unsigned short>::max());
            parameters->setInteger("ordinal"_s, *frameIndex);
        } else {
            String frameElementID = extractElementID(*frameID);
            ASSERT(!frameElementID.isEmpty());
            parameters->setString("nodeHandle"_s, frameElementID);
        }

        m_host->sendCommandToBackend("resolveChildFrameHandle"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto frameHandle = response.responseObject->getString("result"_s);
            if (!frameHandle) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            switchToBrowsingContext(m_toplevelBrowsingContext.value(), frameHandle, [this, protectedThis, frameHandle, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
                if (result.isError()) {
                    completionHandler(WTFMove(result));
                    return;
                }
                switchToBrowsingContext(frameHandle, WTFMove(completionHandler));
            });
        });
    });
}

void Session::switchToParentFrame(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentParentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        switchToBrowsingContext(m_toplevelBrowsingContext.value(), m_currentParentBrowsingContext.value(), [this, protectedThis, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
            if (result.isError()) {
                if (result.errorCode() == CommandResult::ErrorCode::NoSuchFrame)
                    completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
                else
                    completionHandler(WTFMove(result));
                return;
            }

            switchToBrowsingContext(m_currentParentBrowsingContext.value(), WTFMove(completionHandler));
        });
    });
}

void Session::getToplevelBrowsingContextRect(Function<void (CommandResult&&)>&& completionHandler)
{
    auto parameters = JSON::Object::create();
    parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
    m_host->sendCommandToBackend("getBrowsingContext"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError || !response.responseObject) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }

        auto browsingContext = response.responseObject->getObject("context"_s);
        if (!browsingContext) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        auto windowOrigin = browsingContext->getObject("windowOrigin"_s);
        if (!windowOrigin) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        auto x = windowOrigin->getDouble("x"_s);
        if (!x) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        auto y = windowOrigin->getDouble("y"_s);
        if (!y) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        auto windowSize = browsingContext->getObject("windowSize"_s);
        if (!windowSize) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        auto width = windowSize->getDouble("width"_s);
        if (!width) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        auto height = windowSize->getDouble("height"_s);
        if (!height) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        auto windowRect = JSON::Object::create();
        windowRect->setDouble("x"_s, *x);
        windowRect->setDouble("y"_s, *y);
        windowRect->setDouble("width"_s, *width);
        windowRect->setDouble("height"_s, *height);
        completionHandler(CommandResult::success(WTFMove(windowRect)));
    });
}

void Session::getWindowRect(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        getToplevelBrowsingContextRect(WTFMove(completionHandler));
    });
}

void Session::setWindowRect(std::optional<double> x, std::optional<double> y, std::optional<double> width, std::optional<double> height, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, x, y, width, height, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        auto parameters = JSON::Object::create();
        parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
        if (x && y) {
            auto windowOrigin = JSON::Object::create();
            windowOrigin->setDouble("x"_s, x.value());
            windowOrigin->setDouble("y"_s, y.value());
            parameters->setObject("origin"_s, WTFMove(windowOrigin));
        }
        if (width && height) {
            auto windowSize = JSON::Object::create();
            windowSize->setDouble("width"_s, width.value());
            windowSize->setDouble("height"_s, height.value());
            parameters->setObject("size"_s, WTFMove(windowSize));
        }
        m_host->sendCommandToBackend("setWindowFrameOfBrowsingContext"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)] (SessionHost::CommandResponse&& response) mutable {
            if (response.isError) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }
            getToplevelBrowsingContextRect(WTFMove(completionHandler));
        });
    });
}

void Session::maximizeWindow(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        auto parameters = JSON::Object::create();
        parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
        m_host->sendCommandToBackend("maximizeWindowOfBrowsingContext"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)] (SessionHost::CommandResponse&& response) mutable {
            if (response.isError) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }
            getToplevelBrowsingContextRect(WTFMove(completionHandler));
        });
    });
}

void Session::minimizeWindow(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        auto parameters = JSON::Object::create();
        parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
        m_host->sendCommandToBackend("hideWindowOfBrowsingContext"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)] (SessionHost::CommandResponse&& response) mutable {
            if (response.isError) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }
            getToplevelBrowsingContextRect(WTFMove(completionHandler));
        });
    });
}

void Session::fullscreenWindow(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        parameters->setString("function"_s, StringImpl::createWithoutCopying(EnterFullscreenJavaScript));
        parameters->setArray("arguments"_s, JSON::Array::create());
        parameters->setBoolean("expectsImplicitCallbackArgument"_s, true);
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            getToplevelBrowsingContextRect(WTFMove(completionHandler));
        });
    });
}

RefPtr<JSON::Object> Session::createElement(RefPtr<JSON::Value>&& value)
{
    if (!value)
        return nullptr;

    auto valueObject = value->asObject();
    if (!valueObject)
        return nullptr;

    auto elementID = valueObject->getString(makeString("session-node-"_s, id()));
    if (!elementID)
        return nullptr;

    auto elementObject = JSON::Object::create();
    elementObject->setString(webElementIdentifier(), elementID);
    return elementObject;
}

Ref<JSON::Object> Session::createElement(const String& elementID)
{
    auto elementObject = JSON::Object::create();
    elementObject->setString(makeString("session-node-"_s, id()), elementID);
    return elementObject;
}

RefPtr<JSON::Object> Session::createShadowRoot(RefPtr<JSON::Value>&& value)
{
    if (!value)
        return nullptr;

    auto valueObject = value->asObject();
    if (!valueObject)
        return nullptr;

    auto elementID = valueObject->getString(makeString("session-node-"_s, id()));
    if (!elementID)
        return nullptr;

    auto elementObject = JSON::Object::create();
    elementObject->setString(shadowRootIdentifier(), elementID);
    return elementObject;
}

RefPtr<JSON::Object> Session::extractElement(JSON::Value& value)
{
    String elementID = extractElementID(value);
    return !elementID.isEmpty() ? createElement(elementID).ptr() : nullptr;
}

String Session::extractElementID(JSON::Value& value)
{
    auto valueObject = value.asObject();
    if (!valueObject)
        return emptyString();

    auto elementID = valueObject->getString(webElementIdentifier());
    if (!elementID)
        return emptyString();

    return elementID;
}

void Session::computeElementLayout(const String& elementID, OptionSet<ElementLayoutOption> options, Function<void (std::optional<Rect>&&, std::optional<Point>&&, bool, RefPtr<JSON::Object>&&)>&& completionHandler)
{
    ASSERT(m_toplevelBrowsingContext.value());

    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    parameters->setString("frameHandle"_s, m_currentBrowsingContext.value_or(emptyString()));
    parameters->setString("nodeHandle"_s, elementID);
    parameters->setBoolean("scrollIntoViewIfNeeded"_s, options.contains(ElementLayoutOption::ScrollIntoViewIfNeeded));
    parameters->setString("coordinateSystem"_s, options.contains(ElementLayoutOption::UseViewportCoordinates) ? "LayoutViewport"_s : "Page"_s);
    m_host->sendCommandToBackend("computeElementLayout"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
        if (response.isError || !response.responseObject) {
            completionHandler(std::nullopt, std::nullopt, false, WTFMove(response.responseObject));
            return;
        }

        auto rectObject = response.responseObject->getObject("rect"_s);
        if (!rectObject) {
            completionHandler(std::nullopt, std::nullopt, false, nullptr);
            return;
        }

        std::optional<int> elementX;
        std::optional<int> elementY;
        auto elementPosition = rectObject->getObject("origin"_s);
        if (elementPosition) {
            elementX = elementPosition->getInteger("x"_s);
            elementY = elementPosition->getInteger("y"_s);
        }
        if (!elementX || !elementY) {
            completionHandler(std::nullopt, std::nullopt, false, nullptr);
            return;
        }

        std::optional<int> elementWidth;
        std::optional<int> elementHeight;
        auto elementSize = rectObject->getObject("size"_s);
        if (elementSize) {
            elementWidth = elementSize->getInteger("width"_s);
            elementHeight = elementSize->getInteger("height"_s);
        }
        if (!elementWidth || !elementHeight) {
            completionHandler(std::nullopt, std::nullopt, false, nullptr);
            return;
        }

        Rect rect = { { elementX.value(), elementY.value() }, { elementWidth.value(), elementHeight.value() } };

        auto isObscured = response.responseObject->getBoolean("isObscured"_s);
        if (!isObscured) {
            completionHandler(std::nullopt, std::nullopt, false, nullptr);
            return;
        }

        auto inViewCenterPointObject = response.responseObject->getObject("inViewCenterPoint"_s);
        if (!inViewCenterPointObject) {
            completionHandler(rect, std::nullopt, *isObscured, nullptr);
            return;
        }

        auto inViewCenterPointX = inViewCenterPointObject->getInteger("x"_s);
        auto inViewCenterPointY = inViewCenterPointObject->getInteger("y"_s);
        if (!inViewCenterPointX || !inViewCenterPointY) {
            completionHandler(std::nullopt, std::nullopt, *isObscured, nullptr);
            return;
        }

        Point inViewCenterPoint = { *inViewCenterPointX, *inViewCenterPointY };
        completionHandler(rect, inViewCenterPoint, *isObscured, nullptr);
    });
}

void Session::findElements(const String& strategy, const String& selector, FindElementsMode mode, const String& rootElementID, ElementIsShadowRoot isShadowRoot, Function<void(CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, strategy, selector, mode, rootElementID, isShadowRoot, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto arguments = JSON::Array::create();
        arguments->pushString(JSON::Value::create(strategy)->toJSONString());
        if (rootElementID.isEmpty())
            arguments->pushString(JSON::Value::null()->toJSONString());
        else
            arguments->pushString(createElement(rootElementID)->toJSONString());
        arguments->pushString(JSON::Value::create(selector)->toJSONString());
        arguments->pushString(JSON::Value::create(mode == FindElementsMode::Single)->toJSONString());
        arguments->pushString(JSON::Value::create(m_implicitWaitTimeout)->toJSONString());

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        parameters->setString("function"_s, StringImpl::createWithoutCopying(FindNodesJavaScript));
        parameters->setArray("arguments"_s, WTFMove(arguments));
        parameters->setBoolean("expectsImplicitCallbackArgument"_s, true);
        // If there's an implicit wait, use one second more as callback timeout.
        if (m_implicitWaitTimeout)
            parameters->setDouble("callbackTimeout"_s, m_implicitWaitTimeout + 1000);

        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [this, protectedThis, mode, isShadowRoot, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                auto result = CommandResult::fail(WTFMove(response.responseObject));
                if (isShadowRoot == ElementIsShadowRoot::Yes && result.errorCode() == CommandResult::ErrorCode::StaleElementReference) {
                    completionHandler(CommandResult::fail(CommandResult::ErrorCode::DetachedShadowRoot));
                    return;
                }
                completionHandler(WTFMove(result));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }


            switch (mode) {
            case FindElementsMode::Single: {
                auto elementObject = createElement(WTFMove(resultValue));
                if (!elementObject) {
                    completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchElement));
                    return;
                }
                completionHandler(CommandResult::success(WTFMove(elementObject)));
                break;
            }
            case FindElementsMode::Multiple: {
                auto elementsArray = resultValue->asArray();
                if (!elementsArray) {
                    completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchElement));
                    return;
                }

                auto elementObjectsArray = JSON::Array::create();
                unsigned elementsArrayLength = elementsArray->length();
                for (unsigned i = 0; i < elementsArrayLength; ++i) {
                    if (auto elementObject = createElement(elementsArray->get(i)))
                        elementObjectsArray->pushObject(elementObject.releaseNonNull());
                }
                completionHandler(CommandResult::success(WTFMove(elementObjectsArray)));
                break;
            }
            }
        });
    });
}

void Session::getActiveElement(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        parameters->setString("function"_s, "function() { return document.activeElement; }"_s);
        parameters->setArray("arguments"_s, JSON::Array::create());
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto elementObject = createElement(WTFMove(resultValue));
            if (!elementObject) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchElement));
                return;
            }
            completionHandler(CommandResult::success(WTFMove(elementObject)));
        });
    });
}

void Session::getElementShadowRoot(const String& elementID, Function<void(CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        auto arguments = JSON::Array::create();
        arguments->pushString(createElement(elementID)->toJSONString());

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        parameters->setString("function"_s, "function(element) { return element.shadowRoot; }"_s);
        parameters->setArray("arguments"_s, WTFMove(arguments));
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto elementObject = createShadowRoot(WTFMove(resultValue));
            if (!elementObject) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchShadowRoot));
                return;
            }
            completionHandler(CommandResult::success(WTFMove(elementObject)));
        });
    });
}

void Session::isElementSelected(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto arguments = JSON::Array::create();
        arguments->pushString(createElement(elementID)->toJSONString());
        arguments->pushString(JSON::Value::create(makeString("selected"_s))->toJSONString());

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        parameters->setString("function"_s, StringImpl::createWithoutCopying(ElementAttributeJavaScript));
        parameters->setArray("arguments"_s, WTFMove(arguments));
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            if (resultValue->isNull()) {
                completionHandler(CommandResult::success(JSON::Value::create(false)));
                return;
            }

            auto booleanResult = resultValue->asString();
            if (!booleanResult || booleanResult != "true"_s) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(JSON::Value::create(true)));
        });
    });
}

void Session::getElementText(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto arguments = JSON::Array::create();
        arguments->pushString(createElement(elementID)->toJSONString());

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        // FIXME: Add an atom to properly implement this instead of just using innerText.
        parameters->setString("function"_s, StringImpl::createWithoutCopying(ElementTextJavaScript));
        parameters->setArray("arguments"_s, WTFMove(arguments));
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(WTFMove(resultValue)));
        });
    });
}

void Session::getElementTagName(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto arguments = JSON::Array::create();
        arguments->pushString(createElement(elementID)->toJSONString());

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        parameters->setString("function"_s, "function(element) { return element.tagName.toLowerCase() }"_s);
        parameters->setArray("arguments"_s, WTFMove(arguments));
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(WTFMove(resultValue)));
        });
    });
}

void Session::getElementRect(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        computeElementLayout(elementID, { }, [protectedThis, completionHandler = WTFMove(completionHandler)](std::optional<Rect>&& rect, std::optional<Point>&&, bool, RefPtr<JSON::Object>&& error) {
            if (!rect || error) {
                completionHandler(CommandResult::fail(WTFMove(error)));
                return;
            }
            auto rectObject = JSON::Object::create();
            rectObject->setInteger("x"_s, rect.value().origin.x);
            rectObject->setInteger("y"_s, rect.value().origin.y);
            rectObject->setInteger("width"_s, rect.value().size.width);
            rectObject->setInteger("height"_s, rect.value().size.height);
            completionHandler(CommandResult::success(WTFMove(rectObject)));
        });
    });
}

void Session::isElementEnabled(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto arguments = JSON::Array::create();
        arguments->pushString(createElement(elementID)->toJSONString());

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        parameters->setString("function"_s, StringImpl::createWithoutCopying(ElementEnabledJavaScript));
        parameters->setArray("arguments"_s, WTFMove(arguments));
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(WTFMove(resultValue)));
        });
    });
}

void Session::getComputedRole(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        parameters->setString("frameHandle"_s, m_currentBrowsingContext.value_or(emptyString()));
        parameters->setString("nodeHandle"_s, elementID);
        m_host->sendCommandToBackend("getComputedRole"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("role"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::create(valueString);
            completionHandler(CommandResult::success(WTFMove(resultValue)));
        });
    });
}

void Session::getComputedLabel(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        parameters->setString("frameHandle"_s, m_currentBrowsingContext.value_or(emptyString()));
        parameters->setString("nodeHandle"_s, elementID);
        m_host->sendCommandToBackend("getComputedLabel"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("label"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::create(valueString);
            completionHandler(CommandResult::success(WTFMove(resultValue)));
        });
    });
}

void Session::isElementDisplayed(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto arguments = JSON::Array::create();
        arguments->pushString(createElement(elementID)->toJSONString());

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        parameters->setString("function"_s, StringImpl::createWithoutCopying(ElementDisplayedJavaScript));
        parameters->setArray("arguments"_s, WTFMove(arguments));
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(WTFMove(resultValue)));
        });
    });
}

void Session::getElementAttribute(const String& elementID, const String& attribute, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, attribute, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto arguments = JSON::Array::create();
        arguments->pushString(createElement(elementID)->toJSONString());
        arguments->pushString(JSON::Value::create(attribute)->toJSONString());

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        parameters->setString("function"_s, StringImpl::createWithoutCopying(ElementAttributeJavaScript));
        parameters->setArray("arguments"_s, WTFMove(arguments));
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(WTFMove(resultValue)));
        });
    });
}

void Session::getElementProperty(const String& elementID, const String& property, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, property, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto arguments = JSON::Array::create();
        arguments->pushString(createElement(elementID)->toJSONString());

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        parameters->setString("function"_s, makeString("function(element) { return element."_s, property, "; }"_s));
        parameters->setArray("arguments"_s, WTFMove(arguments));
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(WTFMove(resultValue)));
        });
    });
}

void Session::getElementCSSValue(const String& elementID, const String& cssProperty, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, cssProperty, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto arguments = JSON::Array::create();
        arguments->pushString(createElement(elementID)->toJSONString());

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        parameters->setString("function"_s, makeString("function(element) { return document.defaultView.getComputedStyle(element).getPropertyValue('"_s, cssProperty, "'); }"_s));
        parameters->setArray("arguments"_s, WTFMove(arguments));
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(WTFMove(resultValue)));
        });
    });
}

void Session::waitForNavigationToComplete(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::success());
        return;
    }

    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    if (m_currentBrowsingContext)
        parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
    parameters->setDouble("pageLoadTimeout"_s, m_pageLoadTimeout);
    if (auto pageLoadStrategy = pageLoadStrategyString())
        parameters->setString("pageLoadStrategy"_s, pageLoadStrategy.value());
    m_host->sendCommandToBackend("waitForNavigationToComplete"_s, WTFMove(parameters), [this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError) {
            auto result = CommandResult::fail(WTFMove(response.responseObject));
            switch (result.errorCode()) {
            case CommandResult::ErrorCode::NoSuchWindow:
                // Window was closed, reset the top level browsing context and ignore the error.
                m_toplevelBrowsingContext = std::nullopt;
                m_currentBrowsingContext = std::nullopt;
                m_currentParentBrowsingContext = std::nullopt;
                break;
            case CommandResult::ErrorCode::NoSuchFrame:
                // Navigation destroyed the current frame, reset the current browsing context and ignore the error.
                m_currentBrowsingContext = std::nullopt;
                break;
            default:
                completionHandler(WTFMove(result));
                return;
            }
        }
        completionHandler(CommandResult::success());
    });
}

void Session::elementIsFileUpload(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    auto arguments = JSON::Array::create();
    arguments->pushString(createElement(elementID)->toJSONString());

    static constexpr auto isFileUploadScript =
        "function(element) {"
        "    if (element.tagName.toLowerCase() === 'input' && element.type === 'file')"
        "        return { 'fileUpload': true, 'multiple': element.hasAttribute('multiple') };"
        "    return { 'fileUpload': false };"
        "}"_s;

    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    if (m_currentBrowsingContext)
        parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
    parameters->setString("function"_s, isFileUploadScript);
    parameters->setArray("arguments"_s, WTFMove(arguments));
    m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError || !response.responseObject) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }

        auto valueString = response.responseObject->getString("result"_s);
        if (!valueString) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        auto resultValue = JSON::Value::parseJSON(valueString);
        if (!resultValue) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        completionHandler(CommandResult::success(WTFMove(resultValue)));
    });
}

std::optional<Session::FileUploadType> Session::parseElementIsFileUploadResult(const RefPtr<JSON::Value>& resultValue)
{
    if (!resultValue)
        return std::nullopt;

    auto result = resultValue->asObject();
    if (!result)
        return std::nullopt;

    auto isFileUpload = result->getBoolean("fileUpload"_s);
    if (!isFileUpload || !*isFileUpload)
        return std::nullopt;

    auto multiple = result->getBoolean("multiple"_s);
    if (!multiple || !*multiple)
        return FileUploadType::Single;

    return FileUploadType::Multiple;
}

void Session::selectOptionElement(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    parameters->setString("frameHandle"_s, m_currentBrowsingContext.value_or(emptyString()));
    parameters->setString("nodeHandle"_s, elementID);
    m_host->sendCommandToBackend("selectOptionElement"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }
        completionHandler(CommandResult::success());
    });
}

void Session::elementClick(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        elementIsFileUpload(elementID, [this, protectedThis, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
            if (result.isError()) {
                completionHandler(WTFMove(result));
                return;
            }

            if (parseElementIsFileUploadResult(result.result())) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::InvalidArgument));
                return;
            }
            OptionSet<ElementLayoutOption> options = { ElementLayoutOption::ScrollIntoViewIfNeeded, ElementLayoutOption::UseViewportCoordinates };
            computeElementLayout(elementID, options, [this, protectedThis, elementID, completionHandler = WTFMove(completionHandler)](std::optional<Rect>&& rect, std::optional<Point>&& inViewCenter, bool isObscured, RefPtr<JSON::Object>&& error) mutable {
                if (!rect || error) {
                    completionHandler(CommandResult::fail(WTFMove(error)));
                    return;
                }
                if (isObscured) {
                    completionHandler(CommandResult::fail(CommandResult::ErrorCode::ElementClickIntercepted));
                    return;
                }
                if (!inViewCenter) {
                    completionHandler(CommandResult::fail(CommandResult::ErrorCode::ElementNotInteractable));
                    return;
                }

                getElementTagName(elementID, [this, elementID, inViewCenter = WTFMove(inViewCenter), completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
                    bool isOptionElement = false;
                    if (!result.isError()) {
                        auto tagName = result.result()->asString();
                        if (!!tagName)
                            isOptionElement = tagName == "option"_s;
                    }

                    Function<void (CommandResult&&)> continueAfterClickFunction = [this, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
                        if (result.isError()) {
                            completionHandler(WTFMove(result));
                            return;
                        }

                        waitForNavigationToComplete(WTFMove(completionHandler));
                    };
                    if (isOptionElement)
                        selectOptionElement(elementID, WTFMove(continueAfterClickFunction));
                    else
                        performMouseInteraction(inViewCenter.value().x, inViewCenter.value().y, MouseButton::Left, MouseInteraction::SingleClick, WTFMove(continueAfterClickFunction));
                });
            });
        });
    });
}

void Session::elementIsEditable(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    auto arguments = JSON::Array::create();
    arguments->pushString(createElement(elementID)->toJSONString());

    static constexpr auto isEditableScript =
        "function(element) {"
        "    if (element.disabled || element.readOnly)"
        "        return false;"
        "    var tagName = element.tagName.toLowerCase();"
        "    if (tagName === 'textarea' || element.isContentEditable)"
        "        return true;"
        "    if (tagName != 'input')"
        "        return false;"
        "    switch (element.type) {"
        "    case 'color': case 'date': case 'datetime-local': case 'email': case 'file': case 'month': case 'number': "
        "    case 'password': case 'range': case 'search': case 'tel': case 'text': case 'time': case 'url': case 'week':"
        "        return true;"
        "    }"
        "    return false;"
        "}"_s;

    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    if (m_currentBrowsingContext)
        parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
    parameters->setString("function"_s, isEditableScript);
    parameters->setArray("arguments"_s, WTFMove(arguments));
    m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError || !response.responseObject) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }

        auto valueString = response.responseObject->getString("result"_s);
        if (!valueString) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        auto resultValue = JSON::Value::parseJSON(valueString);
        if (!resultValue) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        completionHandler(CommandResult::success(WTFMove(resultValue)));
    });
}

void Session::elementClear(const String& elementID, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        elementIsEditable(elementID, [this, protectedThis, elementID, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
            if (result.isError()) {
                completionHandler(WTFMove(result));
                return;
            }

            auto isEditable = result.result()->asBoolean();
            if (!isEditable || !*isEditable) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::InvalidElementState));
                return;
            }

            OptionSet<ElementLayoutOption> options = { ElementLayoutOption::ScrollIntoViewIfNeeded };
            computeElementLayout(elementID, options, [this, protectedThis, elementID, completionHandler = WTFMove(completionHandler)](std::optional<Rect>&& rect, std::optional<Point>&& inViewCenter, bool, RefPtr<JSON::Object>&& error) mutable {
                if (!rect || error) {
                    completionHandler(CommandResult::fail(WTFMove(error)));
                    return;
                }
                if (!inViewCenter) {
                    completionHandler(CommandResult::fail(CommandResult::ErrorCode::ElementNotInteractable));
                    return;
                }
                auto arguments = JSON::Array::create();
                arguments->pushString(createElement(elementID)->toJSONString());

                auto parameters = JSON::Object::create();
                parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
                if (m_currentBrowsingContext)
                    parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
                parameters->setString("function"_s, StringImpl::createWithoutCopying(FormElementClearJavaScript));
                parameters->setArray("arguments"_s, WTFMove(arguments));
                m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
                    if (response.isError) {
                        completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                        return;
                    }
                    completionHandler(CommandResult::success());
                });
            });
        });
    });
}

void Session::setInputFileUploadFiles(const String& elementID, const String& text, bool multiple, Function<void (CommandResult&&)>&& completionHandler)
{
    Vector<String> files = text.split('\n');
    if (files.isEmpty()) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::InvalidArgument));
        return;
    }

    if (!multiple && files.size() != 1) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::InvalidArgument));
        return;
    }

    auto filenames = JSON::Array::create();
    for (const auto& file : files) {
        if (!FileSystem::fileExists(file)) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::InvalidArgument));
            return;
        }
        filenames->pushString(file);
    }

    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    parameters->setString("frameHandle"_s, m_currentBrowsingContext.value_or(emptyString()));
    parameters->setString("nodeHandle"_s, elementID);
    parameters->setArray("filenames"_s, WTFMove(filenames));
    m_host->sendCommandToBackend("setFilesForInputFileUpload"_s, WTFMove(parameters), [protectedThis = Ref { *this }, elementID, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
        if (response.isError) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }

        completionHandler(CommandResult::success());
    });
}

String Session::virtualKeyForKey(UChar key, KeyModifier& modifier)
{
    // §17.4.2 Keyboard Actions.
    // https://www.w3.org/TR/webdriver/#keyboard-actions
    modifier = KeyModifier::None;
    switch (key) {
    case 0xE001U:
        return "Cancel"_s;
    case 0xE002U:
        return "Help"_s;
    case 0xE003U:
        return "Backspace"_s;
    case 0xE004U:
        return "Tab"_s;
    case 0xE005U:
        return "Clear"_s;
    case 0xE006U:
        return "Return"_s;
    case 0xE007U:
        return "Enter"_s;
    case 0xE008U:
        modifier = KeyModifier::Shift;
        return "Shift"_s;
    case 0xE050U:
        modifier = KeyModifier::Shift;
        return "ShiftRight"_s;
    case 0xE009U:
        modifier = KeyModifier::Control;
        return "Control"_s;
    case 0xE051U:
        modifier = KeyModifier::Control;
        return "ControlRight"_s;
    case 0xE00AU:
        modifier = KeyModifier::Alternate;
        return "Alternate"_s;
    case 0xE052U:
        modifier = KeyModifier::Alternate;
        return "AlternateRight"_s;
    case 0xE00BU:
        return "Pause"_s;
    case 0xE00CU:
        return "Escape"_s;
    case 0xE00DU:
        return "Space"_s;
    case 0xE00EU:
        return "PageUp"_s;
    case 0xE054U:
        return "PageUpRight"_s;
    case 0xE00FU:
        return "PageDown"_s;
    case 0xE055U:
        return "PageDownRight"_s;
    case 0xE010U:
        return "End"_s;
    case 0xE056U:
        return "EndRight"_s;
    case 0xE011U:
        return "Home"_s;
    case 0xE057U:
        return "HomeRight"_s;
    case 0xE012U:
        return "LeftArrow"_s;
    case 0xE058U:
        return "LeftArrowRight"_s;
    case 0xE013U:
        return "UpArrow"_s;
    case 0xE059U:
        return "UpArrowRight"_s;
    case 0xE014U:
        return "RightArrow"_s;
    case 0xE05AU:
        return "RightArrowRight"_s;
    case 0xE015U:
        return "DownArrow"_s;
    case 0xE05BU:
        return "DownArrowRight"_s;
    case 0xE016U:
        return "Insert"_s;
    case 0xE05CU:
        return "InsertRight"_s;
    case 0xE017U:
        return "Delete"_s;
    case 0xE05DU:
        return "DeleteRight"_s;
    case 0xE018U:
        return "Semicolon"_s;
    case 0xE019U:
        return "Equals"_s;
    case 0xE01AU:
        return "NumberPad0"_s;
    case 0xE01BU:
        return "NumberPad1"_s;
    case 0xE01CU:
        return "NumberPad2"_s;
    case 0xE01DU:
        return "NumberPad3"_s;
    case 0xE01EU:
        return "NumberPad4"_s;
    case 0xE01FU:
        return "NumberPad5"_s;
    case 0xE020U:
        return "NumberPad6"_s;
    case 0xE021U:
        return "NumberPad7"_s;
    case 0xE022U:
        return "NumberPad8"_s;
    case 0xE023U:
        return "NumberPad9"_s;
    case 0xE024U:
        return "NumberPadMultiply"_s;
    case 0xE025U:
        return "NumberPadAdd"_s;
    case 0xE026U:
        return "NumberPadSeparator"_s;
    case 0xE027U:
        return "NumberPadSubtract"_s;
    case 0xE028U:
        return "NumberPadDecimal"_s;
    case 0xE029U:
        return "NumberPadDivide"_s;
    case 0xE031U:
        return "Function1"_s;
    case 0xE032U:
        return "Function2"_s;
    case 0xE033U:
        return "Function3"_s;
    case 0xE034U:
        return "Function4"_s;
    case 0xE035U:
        return "Function5"_s;
    case 0xE036U:
        return "Function6"_s;
    case 0xE037U:
        return "Function7"_s;
    case 0xE038U:
        return "Function8"_s;
    case 0xE039U:
        return "Function9"_s;
    case 0xE03AU:
        return "Function10"_s;
    case 0xE03BU:
        return "Function11"_s;
    case 0xE03CU:
        return "Function12"_s;
    case 0xE03DU:
        modifier = KeyModifier::Meta;
        return "Meta"_s;
    case 0xE053U:
        modifier = KeyModifier::Meta;
        return "MetaRight"_s;
    default:
        break;
    }
    return String();
}

void Session::elementSendKeys(const String& elementID, const String& text, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, text, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        elementIsFileUpload(elementID, [this, protectedThis, elementID, text, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
            if (result.isError()) {
                completionHandler(WTFMove(result));
                return;
            }

            auto fileUploadType = parseElementIsFileUploadResult(result.result());
            if (!fileUploadType || capabilities().strictFileInteractability.value_or(false)) {
                // FIXME: move this to an atom.
                static constexpr auto focusScript =
                    "function focus(element) {"
                    "    let doc = element.ownerDocument || element;"
                    "    let prevActiveElement = doc.activeElement;"
                    "    let elementRootNode = element.getRootNode();"
                    "    if (elementRootNode.activeElement !== element && prevActiveElement)"
                    "        prevActiveElement.blur();"
                    "    element.focus();"
                    "    let tagName = element.tagName.toUpperCase();"
                    "    if (tagName === 'BODY' || element === document.documentElement)"
                    "        return;"
                    "    let isTextElement = tagName === 'TEXTAREA' || (tagName === 'INPUT' && element.type === 'text');"
                    "    if (isTextElement && element.selectionEnd == 0)"
                    "        element.setSelectionRange(element.value.length, element.value.length);"
                    "    if (elementRootNode.activeElement !== element)"
                    "        throw {name: 'ElementNotInteractable', message: 'Element is not focusable.'};"
                    "}"_s;

                auto arguments = JSON::Array::create();
                arguments->pushString(createElement(elementID)->toJSONString());
                auto parameters = JSON::Object::create();
                parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
                if (m_currentBrowsingContext)
                    parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
                parameters->setString("function"_s, focusScript);
                parameters->setArray("arguments"_s, WTFMove(arguments));
                m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [this, protectedThis, fileUploadType, elementID, text, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
                    if (response.isError || !response.responseObject) {
                        completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                        return;
                    }

                    if (fileUploadType) {
                        setInputFileUploadFiles(elementID, text, fileUploadType.value() == FileUploadType::Multiple, WTFMove(completionHandler));
                        return;
                    }

                    unsigned stickyModifiers = 0;
                    auto textLength = text.length();
                    Vector<KeyboardInteraction> interactions;
                    interactions.reserveInitialCapacity(textLength);
                    for (unsigned i = 0; i < textLength; ++i) {
                        auto key = text[i];
                        KeyboardInteraction interaction;
                        KeyModifier modifier;
                        auto virtualKey = virtualKeyForKey(key, modifier);
                        if (!virtualKey.isNull()) {
                            interaction.key = virtualKey;
                            if (modifier != KeyModifier::None) {
                                stickyModifiers ^= modifier;
                                if (stickyModifiers & modifier)
                                    interaction.type = KeyboardInteractionType::KeyPress;
                                else
                                    interaction.type = KeyboardInteractionType::KeyRelease;
                            }
                        } else
                            interaction.text = span(key);
                        interactions.append(WTFMove(interaction));
                    }

                    // Reset sticky modifiers if needed.
                    if (stickyModifiers) {
                        if (stickyModifiers & KeyModifier::Shift)
                            interactions.append({ KeyboardInteractionType::KeyRelease, std::nullopt, std::optional<String>("Shift"_s) });
                        if (stickyModifiers & KeyModifier::Control)
                            interactions.append({ KeyboardInteractionType::KeyRelease, std::nullopt, std::optional<String>("Control"_s) });
                        if (stickyModifiers & KeyModifier::Alternate)
                            interactions.append({ KeyboardInteractionType::KeyRelease, std::nullopt, std::optional<String>("Alternate"_s) });
                        if (stickyModifiers & KeyModifier::Meta)
                            interactions.append({ KeyboardInteractionType::KeyRelease, std::nullopt, std::optional<String>("Meta"_s) });
                    }

                    performKeyboardInteractions(WTFMove(interactions), WTFMove(completionHandler));
                });
            } else {
                setInputFileUploadFiles(elementID, text, fileUploadType.value() == FileUploadType::Multiple, WTFMove(completionHandler));
                return;
            }
        });
    });
}

void Session::getPageSource(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        parameters->setString("function"_s, "function() { return document.documentElement.outerHTML; }"_s);
        parameters->setArray("arguments"_s, JSON::Array::create());
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(WTFMove(resultValue)));
        });
    });
}

Ref<JSON::Value> Session::handleScriptResult(Ref<JSON::Value>&& resultValue)
{
    if (auto resultArray = resultValue->asArray()) {
        auto returnValueArray = JSON::Array::create();
        unsigned resultArrayLength = resultArray->length();
        for (unsigned i = 0; i < resultArrayLength; ++i)
            returnValueArray->pushValue(handleScriptResult(resultArray->get(i)));
        return returnValueArray;
    }

    if (auto element = createElement(resultValue.copyRef()))
        return element.releaseNonNull();

    if (auto resultObject = resultValue->asObject()) {
        auto returnValueObject = JSON::Object::create();
        auto end = resultObject->end();
        for (auto it = resultObject->begin(); it != end; ++it)
            returnValueObject->setValue(it->key, handleScriptResult(WTFMove(it->value)));
        return returnValueObject;
    }

    return WTFMove(resultValue);
}

void Session::executeScript(const String& script, RefPtr<JSON::Array>&& argumentsArray, ExecuteScriptMode mode, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, script, argumentsArray = WTFMove(argumentsArray), mode, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto arguments = JSON::Array::create();
        unsigned argumentsLength = argumentsArray->length();
        for (unsigned i = 0; i < argumentsLength; ++i) {
            auto argument = argumentsArray->get(i);
            if (auto element = extractElement(argument))
                arguments->pushString(element->toJSONString());
            else
                arguments->pushString(argument->toJSONString());
        }

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        parameters->setString("function"_s, makeString("function(){\n"_s, script, "\n}"_s));
        parameters->setArray("arguments"_s, WTFMove(arguments));
        if (mode == ExecuteScriptMode::Async)
            parameters->setBoolean("expectsImplicitCallbackArgument"_s, true);
        if (m_scriptTimeout != std::numeric_limits<double>::infinity())
            parameters->setDouble("callbackTimeout"_s, m_scriptTimeout);
        m_host->sendCommandToBackend("evaluateJavaScriptFunction"_s, WTFMove(parameters), [this, protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
            if (response.isError || !response.responseObject) {
                auto result = CommandResult::fail(WTFMove(response.responseObject));
                if (result.errorCode() == CommandResult::ErrorCode::UnexpectedAlertOpen)
                    completionHandler(CommandResult::success());
                else
                    completionHandler(WTFMove(result));
                return;
            }

            auto valueString = response.responseObject->getString("result"_s);
            if (!valueString) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto resultValue = JSON::Value::parseJSON(valueString);
            if (!resultValue) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(handleScriptResult(resultValue.releaseNonNull())));
        });
    });
}

static String mouseButtonForAutomation(MouseButton button)
{
    switch (button) {
    case MouseButton::None:
        return "None"_s;
    case MouseButton::Left:
        return "Left"_s;
    case MouseButton::Middle:
        return "Middle"_s;
    case MouseButton::Right:
        return "Right"_s;
    }

    RELEASE_ASSERT_NOT_REACHED();
}

void Session::performMouseInteraction(int x, int y, MouseButton button, MouseInteraction interaction, Function<void (CommandResult&&)>&& completionHandler)
{
    auto parameters = JSON::Object::create();
    parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
    auto position = JSON::Object::create();
    position->setInteger("x"_s, x);
    position->setInteger("y"_s, y);
    parameters->setObject("position"_s, WTFMove(position));
    parameters->setString("button"_s, mouseButtonForAutomation(button));
    switch (interaction) {
    case MouseInteraction::Move:
        parameters->setString("interaction"_s, "Move"_s);
        break;
    case MouseInteraction::Down:
        parameters->setString("interaction"_s, "Down"_s);
        break;
    case MouseInteraction::Up:
        parameters->setString("interaction"_s, "Up"_s);
        break;
    case MouseInteraction::SingleClick:
        parameters->setString("interaction"_s, "SingleClick"_s);
        break;
    case MouseInteraction::DoubleClick:
        parameters->setString("interaction"_s, "DoubleClick"_s);
        break;
    }
    parameters->setArray("modifiers"_s, JSON::Array::create());
    m_host->sendCommandToBackend("performMouseInteraction"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }
        completionHandler(CommandResult::success());
    });
}

void Session::performKeyboardInteractions(Vector<KeyboardInteraction>&& interactions, Function<void (CommandResult&&)>&& completionHandler)
{
    auto parameters = JSON::Object::create();
    parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
    auto interactionsArray = JSON::Array::create();
    for (const auto& interaction : interactions) {
        auto interactionObject = JSON::Object::create();
        switch (interaction.type) {
        case KeyboardInteractionType::KeyPress:
            interactionObject->setString("type"_s, "KeyPress"_s);
            break;
        case KeyboardInteractionType::KeyRelease:
            interactionObject->setString("type"_s, "KeyRelease"_s);
            break;
        case KeyboardInteractionType::InsertByKey:
            interactionObject->setString("type"_s, "InsertByKey"_s);
            break;
        }
        if (interaction.key)
            interactionObject->setString("key"_s, interaction.key.value());
        if (interaction.text)
            interactionObject->setString("text"_s, interaction.text.value());
        interactionsArray->pushObject(WTFMove(interactionObject));
    }
    parameters->setArray("interactions"_s, WTFMove(interactionsArray));
    m_host->sendCommandToBackend("performKeyboardInteractions"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }
        completionHandler(CommandResult::success());
    });
}

static std::optional<Session::Cookie> parseAutomationCookie(const JSON::Object& cookieObject)
{
    Session::Cookie cookie;

    cookie.name = cookieObject.getString("name"_s);
    if (!cookie.name)
        return std::nullopt;

    cookie.value = cookieObject.getString("value"_s);
    if (!cookie.value)
        return std::nullopt;

    auto path = cookieObject.getString("path"_s);
    if (!!path)
        cookie.path = path;

    auto domain = cookieObject.getString("domain"_s);
    if (!!domain)
        cookie.domain = domain;

    auto secure = cookieObject.getBoolean("secure"_s);
    if (secure)
        cookie.secure = *secure;

    auto httpOnly = cookieObject.getBoolean("httpOnly"_s);
    if (httpOnly)
        cookie.httpOnly = *httpOnly;

    auto session = cookieObject.getBoolean("session"_s);
    if (!session || !*session) {
        if (auto expiry = cookieObject.getDouble("expires"_s))
            cookie.expiry = *expiry;
    }

    auto sameSite = cookieObject.getString("sameSite"_s);
    if (!!sameSite)
        cookie.sameSite = sameSite;

    return cookie;
}

static Ref<JSON::Object> builtAutomationCookie(const Session::Cookie& cookie)
{
    auto cookieObject = JSON::Object::create();
    cookieObject->setString("name"_s, cookie.name);
    cookieObject->setString("value"_s, cookie.value);
    cookieObject->setString("path"_s, cookie.path.value_or("/"_s));
    cookieObject->setString("domain"_s, cookie.domain.value_or(emptyString()));
    cookieObject->setBoolean("secure"_s, cookie.secure.value_or(false));
    cookieObject->setBoolean("httpOnly"_s, cookie.httpOnly.value_or(false));
    cookieObject->setBoolean("session"_s, !cookie.expiry);
    cookieObject->setDouble("expires"_s, cookie.expiry.value_or(0));
    cookieObject->setString("sameSite"_s, cookie.sameSite.value_or("None"_s));
    return cookieObject;
}

static Ref<JSON::Object> serializeCookie(const Session::Cookie& cookie)
{
    auto cookieObject = JSON::Object::create();
    cookieObject->setString("name"_s, cookie.name);
    cookieObject->setString("value"_s, cookie.value);
    if (cookie.path)
        cookieObject->setString("path"_s, cookie.path.value());
    if (cookie.domain)
        cookieObject->setString("domain"_s, cookie.domain.value());
    if (cookie.secure)
        cookieObject->setBoolean("secure"_s, cookie.secure.value());
    if (cookie.httpOnly)
        cookieObject->setBoolean("httpOnly"_s, cookie.httpOnly.value());
    if (cookie.expiry)
        cookieObject->setInteger("expiry"_s, cookie.expiry.value());
    if (cookie.sameSite)
        cookieObject->setString("sameSite"_s, cookie.sameSite.value());
    return cookieObject;
}

void Session::getAllCookies(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        m_host->sendCommandToBackend("getAllCookies"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto cookiesArray = response.responseObject->getArray("cookies"_s);
            if (!cookiesArray) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            auto cookies = JSON::Array::create();
            for (unsigned i = 0; i < cookiesArray->length(); ++i) {
                auto cookieObject = cookiesArray->get(i)->asObject();
                if (!cookieObject) {
                    completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                    return;
                }

                auto cookie = parseAutomationCookie(*cookieObject);
                if (!cookie) {
                    completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                    return;
                }
                cookies->pushObject(serializeCookie(cookie.value()));
            }
            completionHandler(CommandResult::success(WTFMove(cookies)));
        });
    });
}

void Session::getNamedCookie(const String& name, Function<void (CommandResult&&)>&& completionHandler)
{
    getAllCookies([name, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        auto cookiesArray = result.result()->asArray();
        for (unsigned i = 0; i < cookiesArray->length(); ++i) {
            auto cookieObject = cookiesArray->get(i)->asObject();
            auto cookieName = cookieObject->getString("name"_s);
            if (cookieName == name) {
                completionHandler(CommandResult::success(WTFMove(cookieObject)));
                return;
            }
        }
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchCookie));
    });
}

void Session::addCookie(const Cookie& cookie, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, cookie = builtAutomationCookie(cookie), completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        parameters->setObject("cookie"_s, WTFMove(cookie));
        m_host->sendCommandToBackend("addSingleCookie"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }
            completionHandler(CommandResult::success());
        });
    });
}

void Session::deleteCookie(const String& name, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, name, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        parameters->setString("cookieName"_s, name);
        m_host->sendCommandToBackend("deleteSingleCookie"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }
            completionHandler(CommandResult::success());
        });
    });
}

void Session::deleteAllCookies(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
        m_host->sendCommandToBackend("deleteAllCookies"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
            if (response.isError) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }
            completionHandler(CommandResult::success());
        });
    });
}

InputSource& Session::getOrCreateInputSource(const String& id, InputSource::Type type, std::optional<PointerType> pointerType)
{
    auto addResult = m_activeInputSources.add(id, InputSource());
    if (addResult.isNewEntry)
        addResult.iterator->value = { type, pointerType };
    return addResult.iterator->value;
}

Session::InputSourceState& Session::inputSourceState(const String& id)
{
    return m_inputStateTable.ensure(id, [] { return InputSourceState(); }).iterator->value;
}

static ASCIILiteral automationSourceType(const InputSource& inputSource)
{
    switch (inputSource.type) {
    case InputSource::Type::None:
        return "Null"_s;
    case InputSource::Type::Pointer:
        switch (inputSource.pointerType.value_or(PointerType::Mouse)) {
        case PointerType::Mouse:
            return "Mouse"_s;
        case PointerType::Touch:
            return "Touch"_s;
        case PointerType::Pen:
            return "Pen"_s;
        }
        break;
    case InputSource::Type::Key:
        return "Keyboard"_s;
    case InputSource::Type::Wheel:
        return "Wheel"_s;
    }
    RELEASE_ASSERT_NOT_REACHED();
}

static ASCIILiteral automationOriginType(PointerOrigin::Type type)
{
    switch (type) {
    case PointerOrigin::Type::Viewport:
        return "Viewport"_s;
    case PointerOrigin::Type::Pointer:
        return "Pointer"_s;
    case PointerOrigin::Type::Element:
        return "Element"_s;
    }
    RELEASE_ASSERT_NOT_REACHED();
}

void Session::performActions(Vector<Vector<Action>>&& actionsByTick, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_currentBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, actionsByTick = WTFMove(actionsByTick), completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }

        // First check if we have actions and whether we need to resolve any pointer move element origin.
        unsigned actionsCount = 0;
        for (const auto& tick : actionsByTick)
            actionsCount += tick.size();
        if (!actionsCount) {
            completionHandler(CommandResult::success());
            return;
        }

        auto parameters = JSON::Object::create();
        parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());

        HashSet<String> inputSourcesSet;
        auto steps = JSON::Array::create();
        for (const auto& tick : actionsByTick) {
            auto states = JSON::Array::create();
            for (const auto& action : tick) {
                inputSourcesSet.add(action.id);
                auto state = JSON::Object::create();
                auto& currentState = inputSourceState(action.id);
                state->setString("sourceId"_s, action.id);
                switch (action.type) {
                case Action::Type::None:
                    if (action.duration)
                        state->setDouble("duration"_s, action.duration.value());
                    break;
                case Action::Type::Pointer: {
                    switch (action.subtype) {
                    case Action::Subtype::PointerUp:
                        currentState.pressedButton = std::nullopt;
                        break;
                    case Action::Subtype::PointerDown:
                        currentState.pressedButton = action.button.value();
                        break;
                    case Action::Subtype::PointerMove: {
                        state->setString("origin"_s, automationOriginType(action.origin->type));
                        auto location = JSON::Object::create();
                        location->setInteger("x"_s, action.x.value());
                        location->setInteger("y"_s, action.y.value());
                        state->setObject("location"_s, WTFMove(location));
                        if (action.origin->type == PointerOrigin::Type::Element)
                            state->setString("nodeHandle"_s, action.origin->elementID.value());
                        FALLTHROUGH;
                    }
                    case Action::Subtype::Pause:
                        if (action.duration)
                            state->setDouble("duration"_s, action.duration.value());
                        break;
                    case Action::Subtype::PointerCancel:
                        currentState.pressedButton = std::nullopt;
                        break;
                    case Action::Subtype::KeyUp:
                    case Action::Subtype::KeyDown:
                    case Action::Subtype::Scroll:
                        ASSERT_NOT_REACHED();
                    }
                    if (currentState.pressedButton)
                        state->setString("pressedButton"_s, mouseButtonForAutomation(currentState.pressedButton.value()));
                    break;
                }
                case Action::Type::Key:
                    switch (action.subtype) {
                    case Action::Subtype::KeyUp: {
                        KeyModifier modifier;
                        auto virtualKey = virtualKeyForKey(action.key.value()[0], modifier);
                        if (!virtualKey.isNull())
                            currentState.pressedVirtualKeys.remove(virtualKey);
                        else
                            currentState.pressedKey = std::nullopt;
                        break;
                    }
                    case Action::Subtype::KeyDown: {
                        KeyModifier modifier;
                        auto virtualKey = virtualKeyForKey(action.key.value()[0], modifier);
                        if (!virtualKey.isNull())
                            currentState.pressedVirtualKeys.add(virtualKey);
                        else
                            currentState.pressedKey = action.key.value();
                        break;
                    }
                    case Action::Subtype::Pause:
                        if (action.duration)
                            state->setDouble("duration"_s, action.duration.value());
                        break;
                    case Action::Subtype::PointerUp:
                    case Action::Subtype::PointerDown:
                    case Action::Subtype::PointerMove:
                    case Action::Subtype::PointerCancel:
                    case Action::Subtype::Scroll:
                        ASSERT_NOT_REACHED();
                    }
                    if (currentState.pressedKey)
                        state->setString("pressedCharKey"_s, currentState.pressedKey.value());
                    if (!currentState.pressedVirtualKeys.isEmpty()) {
                        // FIXME: support parsing and tracking multiple virtual keys.
                        Ref<JSON::Array> virtualKeys = JSON::Array::create();
                        for (const auto& virtualKey : currentState.pressedVirtualKeys)
                            virtualKeys->pushString(virtualKey);
                        state->setArray("pressedVirtualKeys"_s, WTFMove(virtualKeys));
                    }
                    break;
                case Action::Type::Wheel:
                    switch (action.subtype) {
                    case Action::Subtype::Scroll: {
                        state->setString("origin"_s, automationOriginType(action.origin->type));
                        auto location = JSON::Object::create();
                        location->setInteger("x"_s, action.x.value());
                        location->setInteger("y"_s, action.y.value());
                        state->setObject("location"_s, WTFMove(location));

                        auto delta = JSON::Object::create();
                        delta->setInteger("width"_s, action.deltaX.value());
                        delta->setInteger("height"_s, action.deltaY.value());
                        state->setObject("delta"_s, WTFMove(delta));

                        if (action.origin->type == PointerOrigin::Type::Element)
                            state->setString("nodeHandle"_s, action.origin->elementID.value());
                        FALLTHROUGH;
                    }
                    case Action::Subtype::Pause:
                        if (action.duration)
                            state->setDouble("duration"_s, action.duration.value());
                        break;
                    case Action::Subtype::PointerUp:
                    case Action::Subtype::PointerDown:
                    case Action::Subtype::PointerMove:
                    case Action::Subtype::PointerCancel:
                    case Action::Subtype::KeyUp:
                    case Action::Subtype::KeyDown:
                        ASSERT_NOT_REACHED();
                    }
                }
                states->pushObject(WTFMove(state));
            }
            auto stepStates = JSON::Object::create();
            stepStates->setArray("states"_s, WTFMove(states));
            steps->pushObject(WTFMove(stepStates));
        }

        parameters->setArray("steps"_s, WTFMove(steps));

        auto inputSources = JSON::Array::create();
        for (const auto& id : inputSourcesSet) {
            const auto& inputSource = m_activeInputSources.get(id);
            auto inputSourceObject = JSON::Object::create();
            inputSourceObject->setString("sourceId"_s, id);
            inputSourceObject->setString("sourceType"_s, automationSourceType(inputSource));
            inputSources->pushObject(WTFMove(inputSourceObject));
        }
        parameters->setArray("inputSources"_s, WTFMove(inputSources));

        m_host->sendCommandToBackend("performInteractionSequence"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)] (SessionHost::CommandResponse&& response) {
            if (response.isError) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }
            completionHandler(CommandResult::success());
        });
    });
}

void Session::releaseActions(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    m_activeInputSources.clear();
    m_inputStateTable.clear();

    auto parameters = JSON::Object::create();
    parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
    m_host->sendCommandToBackend("cancelInteractionSequence"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }
        completionHandler(CommandResult::success());
    });
}

void Session::dismissAlert(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    m_host->sendCommandToBackend("dismissCurrentJavaScriptDialog"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }
        completionHandler(CommandResult::success());
    });
}

void Session::acceptAlert(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    m_host->sendCommandToBackend("acceptCurrentJavaScriptDialog"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }
        completionHandler(CommandResult::success());
    });
}

void Session::getAlertText(Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    m_host->sendCommandToBackend("messageOfCurrentJavaScriptDialog"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError || !response.responseObject) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }

        auto valueString = response.responseObject->getString("message"_s);
        if (!valueString) {
            completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
            return;
        }

        completionHandler(CommandResult::success(JSON::Value::create(valueString)));
    });
}

void Session::sendAlertText(const String& text, Function<void (CommandResult&&)>&& completionHandler)
{
    if (!m_toplevelBrowsingContext) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    auto parameters = JSON::Object::create();
    parameters->setString("browsingContextHandle"_s, m_toplevelBrowsingContext.value());
    parameters->setString("userInput"_s, text);
    m_host->sendCommandToBackend("setUserInputForCurrentJavaScriptPrompt"_s, WTFMove(parameters), [protectedThis = Ref { *this }, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) {
        if (response.isError) {
            completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
            return;
        }
        completionHandler(CommandResult::success());
    });
}

void Session::takeScreenshot(std::optional<String> elementID, std::optional<bool> scrollIntoView, Function<void (CommandResult&&)>&& completionHandler)
{
    if ((elementID && !m_currentBrowsingContext) || (!elementID && !m_toplevelBrowsingContext)) {
        completionHandler(CommandResult::fail(CommandResult::ErrorCode::NoSuchWindow));
        return;
    }

    handleUserPrompts([this, protectedThis = Ref { *this }, elementID, scrollIntoView, completionHandler = WTFMove(completionHandler)](CommandResult&& result) mutable {
        if (result.isError()) {
            completionHandler(WTFMove(result));
            return;
        }
        auto parameters = JSON::Object::create();
        parameters->setString("handle"_s, m_toplevelBrowsingContext.value());
        if (m_currentBrowsingContext)
            parameters->setString("frameHandle"_s, m_currentBrowsingContext.value());
        if (elementID)
            parameters->setString("nodeHandle"_s, elementID.value());
        parameters->setBoolean("clipToViewport"_s, true);
        if (scrollIntoView.value_or(false))
            parameters->setBoolean("scrollIntoViewIfNeeded"_s, true);
        m_host->sendCommandToBackend("takeScreenshot"_s, WTFMove(parameters), [protectedThis, completionHandler = WTFMove(completionHandler)](SessionHost::CommandResponse&& response) mutable {
            if (response.isError || !response.responseObject) {
                completionHandler(CommandResult::fail(WTFMove(response.responseObject)));
                return;
            }

            auto data = response.responseObject->getString("data"_s);
            if (!data) {
                completionHandler(CommandResult::fail(CommandResult::ErrorCode::UnknownError));
                return;
            }

            completionHandler(CommandResult::success(JSON::Value::create(data)));
        });
    });
}

} // namespace WebDriver
