mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-06-09 09:34:57 +09:00
WebDriver: Properly distinguish HTTP sessions from other sessions
The WebDriver spec now separately tracks an active HTTP session list,
which will contains all non-BiDi WebDriver sessions by default. There
may only be one active HTTP session at a time.
See: 63a397f
This commit is contained in:
parent
de34351ba8
commit
3128d87766
Notes:
github-actions[bot]
2025-02-10 16:35:10 +00:00
Author: https://github.com/trflynn89
Commit: 3128d87766
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3497
4 changed files with 33 additions and 17 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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/<session_id>");
|
||||
|
||||
// 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/<session_id>/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/<session_id>/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();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
namespace WebDriver {
|
||||
|
||||
static HashMap<String, NonnullRefPtr<Session>> s_sessions;
|
||||
static HashMap<String, NonnullRefPtr<Session>> s_http_sessions;
|
||||
|
||||
// https://w3c.github.io/webdriver/#dfn-create-a-session
|
||||
ErrorOr<NonnullRefPtr<Session>> Session::create(NonnullRefPtr<Client> client, JsonObject& capabilities, Web::WebDriver::SessionFlags flags)
|
||||
|
@ -98,7 +99,9 @@ ErrorOr<NonnullRefPtr<Session>> Session::create(NonnullRefPtr<Client> 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> client, JsonObject const& capabilities, S
|
|||
|
||||
Session::~Session() = default;
|
||||
|
||||
ErrorOr<NonnullRefPtr<Session>, Web::WebDriver::Error> Session::find_session(StringView session_id, AllowInvalidWindowHandle allow_invalid_window_handle)
|
||||
ErrorOr<NonnullRefPtr<Session>, 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<NonnullRefPtr<Session>, 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;
|
||||
|
|
|
@ -36,7 +36,8 @@ public:
|
|||
No,
|
||||
Yes,
|
||||
};
|
||||
static ErrorOr<NonnullRefPtr<Session>, Web::WebDriver::Error> find_session(StringView session_id, AllowInvalidWindowHandle = AllowInvalidWindowHandle::No);
|
||||
static ErrorOr<NonnullRefPtr<Session>, 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); }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue