diff --git a/Services/WebContent/WebDriverConnection.cpp b/Services/WebContent/WebDriverConnection.cpp index 4d58d1f61e1..8585c8c4f71 100644 --- a/Services/WebContent/WebDriverConnection.cpp +++ b/Services/WebContent/WebDriverConnection.cpp @@ -570,9 +570,8 @@ Messages::WebDriverClient::CloseWindowResponse WebDriverConnection::close_window // 11.3 Switch to Window, https://w3c.github.io/webdriver/#dfn-switch-to-window Messages::WebDriverClient::SwitchToWindowResponse WebDriverConnection::switch_to_window(String const& handle) { - // 4. If handle is equal to the associated window handle for some top-level browsing context in the - // current session, let context be the that browsing context, and set the current top-level - // browsing context with context. + // 4. If handle is equal to the associated window handle for some top-level browsing context, let context be the that + // browsing context, and set the current top-level browsing context with session and context. // Otherwise, return error with error code no such window. bool found_matching_context = false; diff --git a/Services/WebDriver/Client.cpp b/Services/WebDriver/Client.cpp index 5cad543c3e9..cad6e47a666 100644 --- a/Services/WebDriver/Client.cpp +++ b/Services/WebDriver/Client.cpp @@ -44,8 +44,10 @@ Web::WebDriver::Response Client::new_session(Web::WebDriver::Parameters, JsonVal { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session"); - // FIXME: 1. If the implementation is an endpoint node, and the list of active HTTP sessions is not empty, or otherwise if - // the implementation is unable to start an additional session, return error with error code session not created. + // 1. If the implementation is an endpoint node, and the list of active HTTP sessions is not empty, or otherwise if + // the implementation is unable to start an additional session, return error with error code session not created. + if (Session::session_count(Web::WebDriver::SessionFlags::Http) > 0) + return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::SessionNotCreated, "There is already an active HTTP session"sv); // FIXME: 2. If the remote end is an intermediary node, take implementation-defined steps that either result in returning // an error with error code session not created, or in returning a success with data that is isomorphic to that @@ -96,8 +98,8 @@ Web::WebDriver::Response Client::delete_session(Web::WebDriver::Parameters param { dbgln_if(WEBDRIVER_DEBUG, "Handling DELETE /session/"); - // 1. If the current session is an active session, try to close the session. - if (auto session = Session::find_session(parameters[0], Session::AllowInvalidWindowHandle::Yes); !session.is_error()) + // 1. If session is an active HTTP session, try to close the session with session. + if (auto session = Session::find_session(parameters[0], Web::WebDriver::SessionFlags::Http, Session::AllowInvalidWindowHandle::Yes); !session.is_error()) session.value()->close(); // 2. Return success with data null. @@ -242,7 +244,7 @@ Web::WebDriver::Response Client::close_window(Web::WebDriver::Parameters paramet Web::WebDriver::Response Client::switch_to_window(Web::WebDriver::Parameters parameters, AK::JsonValue payload) { dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session//window"); - auto session = TRY(Session::find_session(parameters[0], Session::AllowInvalidWindowHandle::Yes)); + auto session = TRY(Session::find_session(parameters[0], Web::WebDriver::SessionFlags::Default, Session::AllowInvalidWindowHandle::Yes)); if (!payload.is_object()) return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidArgument, "Payload is not a JSON object"); @@ -262,7 +264,7 @@ Web::WebDriver::Response Client::switch_to_window(Web::WebDriver::Parameters par Web::WebDriver::Response Client::get_window_handles(Web::WebDriver::Parameters parameters, JsonValue) { dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session//window/handles"); - auto session = TRY(Session::find_session(parameters[0], Session::AllowInvalidWindowHandle::Yes)); + auto session = TRY(Session::find_session(parameters[0], Web::WebDriver::SessionFlags::Default, Session::AllowInvalidWindowHandle::Yes)); return session->get_window_handles(); } diff --git a/Services/WebDriver/Session.cpp b/Services/WebDriver/Session.cpp index 02f471c7e61..77a3539a688 100644 --- a/Services/WebDriver/Session.cpp +++ b/Services/WebDriver/Session.cpp @@ -23,6 +23,7 @@ namespace WebDriver { static HashMap> s_sessions; +static HashMap> s_http_sessions; // https://w3c.github.io/webdriver/#dfn-create-a-session ErrorOr> Session::create(NonnullRefPtr client, JsonObject& capabilities, Web::WebDriver::SessionFlags flags) @@ -98,7 +99,9 @@ ErrorOr> Session::create(NonnullRefPtr client, Js // 12. Append session to active sessions. s_sessions.set(session->session_id(), session); - // FIXME: 13. If flags contains "http", append session to active HTTP sessions. + // 13. If flags contains "http", append session to active HTTP sessions. + if (has_flag(flags, Web::WebDriver::SessionFlags::Http)) + s_http_sessions.set(session->session_id(), session); // 14. Set the webdriver-active flag to true. session->web_content_connection().async_set_is_webdriver_active(true); @@ -116,9 +119,11 @@ Session::Session(NonnullRefPtr client, JsonObject const& capabilities, S Session::~Session() = default; -ErrorOr, Web::WebDriver::Error> Session::find_session(StringView session_id, AllowInvalidWindowHandle allow_invalid_window_handle) +ErrorOr, Web::WebDriver::Error> Session::find_session(StringView session_id, Web::WebDriver::SessionFlags session_flags, AllowInvalidWindowHandle allow_invalid_window_handle) { - if (auto session = s_sessions.get(session_id); session.has_value()) { + auto const& sessions = has_flag(session_flags, Web::WebDriver::SessionFlags::Http) ? s_http_sessions : s_sessions; + + if (auto session = sessions.get(session_id); session.has_value()) { if (allow_invalid_window_handle == AllowInvalidWindowHandle::No) TRY(session.value()->ensure_current_window_handle_is_valid()); @@ -128,10 +133,19 @@ ErrorOr, Web::WebDriver::Error> Session::find_session(Str return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSessionId, "Invalid session id"); } +size_t Session::session_count(Web::WebDriver::SessionFlags session_flags) +{ + if (has_flag(session_flags, Web::WebDriver::SessionFlags::Http)) + return s_http_sessions.size(); + return s_sessions.size(); +} + // https://w3c.github.io/webdriver/#dfn-close-the-session void Session::close() { - // FIXME: 1. If session's HTTP flag is set, remove session from active HTTP sessions. + // 1. If session's HTTP flag is set, remove session from active HTTP sessions. + if (has_flag(session_flags(), Web::WebDriver::SessionFlags::Http)) + s_http_sessions.remove(m_session_id); // 2. Remove session from active sessions. s_sessions.remove(m_session_id); @@ -275,9 +289,8 @@ Web::WebDriver::Response Session::close_window() // 11.3 Switch to Window, https://w3c.github.io/webdriver/#dfn-switch-to-window Web::WebDriver::Response Session::switch_to_window(StringView handle) { - // 4. If handle is equal to the associated window handle for some top-level browsing context in the - // current session, let context be the that browsing context, and set the current top-level - // browsing context with context. + // 4. If handle is equal to the associated window handle for some top-level browsing context, let context be the that + // browsing context, and set the current top-level browsing context with session and context. // Otherwise, return error with error code no such window. if (auto it = m_windows.find(handle); it != m_windows.end()) m_current_window_handle = it->key; diff --git a/Services/WebDriver/Session.h b/Services/WebDriver/Session.h index a204312b91f..437d28b87e6 100644 --- a/Services/WebDriver/Session.h +++ b/Services/WebDriver/Session.h @@ -36,7 +36,8 @@ public: No, Yes, }; - static ErrorOr, Web::WebDriver::Error> find_session(StringView session_id, AllowInvalidWindowHandle = AllowInvalidWindowHandle::No); + static ErrorOr, Web::WebDriver::Error> find_session(StringView session_id, Web::WebDriver::SessionFlags = Web::WebDriver::SessionFlags::Default, AllowInvalidWindowHandle = AllowInvalidWindowHandle::No); + static size_t session_count(Web::WebDriver::SessionFlags); struct Window { String handle; @@ -54,6 +55,7 @@ public: void close(); String session_id() const { return m_session_id; } + Web::WebDriver::SessionFlags session_flags() const { return m_session_flags; } String const& current_window_handle() const { return m_current_window_handle; } bool has_window_handle(StringView handle) const { return m_windows.contains(handle); }