2022-10-12 10:14:59 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2022, Florent Castelli <florent.castelli@gmail.com>
|
2022-10-19 15:46:31 +00:00
|
|
|
* Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
|
2022-10-12 10:14:59 +00:00
|
|
|
*
|
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <AK/NonnullOwnPtrVector.h>
|
|
|
|
#include <LibCore/Object.h>
|
|
|
|
#include <LibCore/Stream.h>
|
|
|
|
#include <LibHTTP/Forward.h>
|
|
|
|
#include <LibHTTP/HttpRequest.h>
|
|
|
|
#include <WebDriver/Session.h>
|
2022-10-20 11:04:39 +00:00
|
|
|
#include <WebDriver/WebDriverError.h>
|
2022-10-12 10:14:59 +00:00
|
|
|
|
|
|
|
namespace WebDriver {
|
|
|
|
|
|
|
|
class Client final : public Core::Object {
|
|
|
|
C_OBJECT(Client);
|
|
|
|
|
|
|
|
public:
|
|
|
|
void start();
|
|
|
|
void close_session(unsigned session_id);
|
|
|
|
|
|
|
|
private:
|
|
|
|
Client(NonnullOwnPtr<Core::Stream::BufferedTCPSocket>, Core::Object* parent);
|
|
|
|
|
|
|
|
ErrorOr<JsonValue> read_body_as_json(HTTP::HttpRequest const&);
|
|
|
|
ErrorOr<bool> handle_request(HTTP::HttpRequest const&, JsonValue const& body);
|
|
|
|
ErrorOr<void> send_response(StringView content, HTTP::HttpRequest const&);
|
2022-10-20 11:04:39 +00:00
|
|
|
ErrorOr<void> send_error_response(WebDriverError const& error, HTTP::HttpRequest const&);
|
2022-10-12 10:14:59 +00:00
|
|
|
void die();
|
|
|
|
void log_response(unsigned code, HTTP::HttpRequest const&);
|
|
|
|
|
2022-10-20 11:04:39 +00:00
|
|
|
using RouteHandler = ErrorOr<JsonValue, WebDriverError> (Client::*)(Vector<StringView> const&, JsonValue const&);
|
2022-10-12 10:14:59 +00:00
|
|
|
struct Route {
|
|
|
|
HTTP::HttpRequest::Method method;
|
|
|
|
Vector<String> path;
|
|
|
|
RouteHandler handler;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct RoutingResult {
|
|
|
|
RouteHandler handler;
|
|
|
|
Vector<StringView> parameters;
|
|
|
|
};
|
|
|
|
|
2022-10-20 11:04:39 +00:00
|
|
|
ErrorOr<RoutingResult, WebDriverError> match_route(HTTP::HttpRequest::Method method, String const& resource);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_new_session(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_delete_session(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_status(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_timeouts(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_set_timeouts(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_navigate_to(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_current_url(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_back(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_forward(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_refresh(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_title(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_window_handle(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_close_window(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_window_handles(Vector<StringView> const&, JsonValue const& payload);
|
2022-11-02 14:19:58 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_window_rect(Vector<StringView> const&, JsonValue const& payload);
|
2022-11-02 13:33:24 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_set_window_rect(Vector<StringView> const&, JsonValue const& payload);
|
2022-11-02 13:44:43 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_maximize_window(Vector<StringView> const&, JsonValue const& payload);
|
2022-11-02 14:01:51 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_minimize_window(Vector<StringView> const&, JsonValue const& payload);
|
2022-10-20 11:04:39 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_find_element(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_find_elements(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_find_element_from_element(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_find_elements_from_element(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_element_attribute(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_element_property(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_element_css_value(Vector<StringView> const&, JsonValue const& payload);
|
2022-11-01 09:12:50 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_element_text(Vector<StringView> const&, JsonValue const& payload);
|
2022-10-20 20:40:32 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_element_tag_name(Vector<StringView> const&, JsonValue const& payload);
|
2022-11-03 16:53:27 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_element_rect(Vector<StringView> const&, JsonValue const& payload);
|
2022-11-03 00:26:06 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_source(Vector<StringView> const&, JsonValue const& payload);
|
2022-11-02 18:11:04 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_execute_script(Vector<StringView> const&, JsonValue const& payload);
|
2022-11-02 18:12:28 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_execute_async_script(Vector<StringView> const&, JsonValue const& payload);
|
2022-10-20 11:04:39 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_all_cookies(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_get_named_cookie(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_add_cookie(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_delete_cookie(Vector<StringView> const&, JsonValue const& payload);
|
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_delete_all_cookies(Vector<StringView> const&, JsonValue const& payload);
|
2022-11-02 16:59:02 +00:00
|
|
|
ErrorOr<JsonValue, WebDriverError> handle_take_screenshot(Vector<StringView> const&, JsonValue const& payload);
|
2022-10-20 11:04:39 +00:00
|
|
|
|
|
|
|
ErrorOr<Session*, WebDriverError> find_session_with_id(StringView session_id);
|
2022-10-12 10:14:59 +00:00
|
|
|
JsonValue make_json_value(JsonValue const&);
|
|
|
|
|
|
|
|
template<typename T>
|
2022-10-20 11:04:39 +00:00
|
|
|
static ErrorOr<T, WebDriverError> unwrap_result(ErrorOr<T, Variant<WebDriverError, Error>> result)
|
2022-10-12 10:14:59 +00:00
|
|
|
{
|
|
|
|
if (result.is_error()) {
|
2022-10-20 11:04:39 +00:00
|
|
|
Variant<WebDriverError, Error> error = result.release_error();
|
|
|
|
if (error.has<WebDriverError>())
|
|
|
|
return error.get<WebDriverError>();
|
2022-10-20 13:00:49 +00:00
|
|
|
return WebDriverError::from_code(ErrorCode::UnsupportedOperation, error.get<Error>().string_literal());
|
2022-10-12 10:14:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return result.release_value();
|
|
|
|
}
|
2022-10-20 11:04:39 +00:00
|
|
|
static ErrorOr<void, WebDriverError> unwrap_result(ErrorOr<void, Variant<WebDriverError, Error>> result)
|
2022-10-12 10:14:59 +00:00
|
|
|
{
|
|
|
|
if (result.is_error()) {
|
2022-10-20 11:04:39 +00:00
|
|
|
Variant<WebDriverError, Error> error = result.release_error();
|
|
|
|
if (error.has<WebDriverError>())
|
|
|
|
return error.get<WebDriverError>();
|
2022-10-20 13:00:49 +00:00
|
|
|
return WebDriverError::from_code(ErrorCode::UnsupportedOperation, error.get<Error>().string_literal());
|
2022-10-12 10:14:59 +00:00
|
|
|
}
|
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
|
|
|
NonnullOwnPtr<Core::Stream::BufferedTCPSocket> m_socket;
|
|
|
|
static Vector<Route> s_routes;
|
|
|
|
String m_prefix = "/";
|
|
|
|
|
|
|
|
static NonnullOwnPtrVector<Session> s_sessions;
|
|
|
|
static Atomic<unsigned> s_next_session_id;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|