Client.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599
  1. /*
  2. * Copyright (c) 2022, Florent Castelli <florent.castelli@gmail.com>
  3. * Copyright (c) 2022, Sam Atkins <atkinssj@serenityos.org>
  4. * Copyright (c) 2022, Tobias Christiansen <tobyase@serenityos.org>
  5. * Copyright (c) 2022, Linus Groh <linusg@serenityos.org>
  6. * Copyright (c) 2022, Tim Flynn <trflynn89@serenityos.org>
  7. *
  8. * SPDX-License-Identifier: BSD-2-Clause
  9. */
  10. #include <AK/Debug.h>
  11. #include <AK/JsonObject.h>
  12. #include <AK/JsonValue.h>
  13. #include <LibWeb/WebDriver/Capabilities.h>
  14. #include <WebDriver/Client.h>
  15. namespace WebDriver {
  16. Atomic<unsigned> Client::s_next_session_id;
  17. NonnullOwnPtrVector<Session> Client::s_sessions;
  18. ErrorOr<NonnullRefPtr<Client>> Client::try_create(NonnullOwnPtr<Core::Stream::BufferedTCPSocket> socket, Core::Object* parent)
  19. {
  20. TRY(socket->set_blocking(true));
  21. return adopt_nonnull_ref_or_enomem(new (nothrow) Client(move(socket), parent));
  22. }
  23. Client::Client(NonnullOwnPtr<Core::Stream::BufferedTCPSocket> socket, Core::Object* parent)
  24. : Web::WebDriver::Client(move(socket), parent)
  25. {
  26. }
  27. Client::~Client() = default;
  28. ErrorOr<Session*, Web::WebDriver::Error> Client::find_session_with_id(StringView session_id)
  29. {
  30. auto session_id_or_error = session_id.to_uint<>();
  31. if (!session_id_or_error.has_value())
  32. return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSessionId, "Invalid session id");
  33. for (auto& session : Client::s_sessions) {
  34. if (session.session_id() == session_id_or_error.value())
  35. return &session;
  36. }
  37. return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSessionId, "Invalid session id");
  38. }
  39. ErrorOr<NonnullOwnPtr<Session>, Web::WebDriver::Error> Client::take_session_with_id(StringView session_id)
  40. {
  41. auto session_id_or_error = session_id.to_uint<>();
  42. if (!session_id_or_error.has_value())
  43. return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSessionId, "Invalid session id");
  44. for (size_t i = 0; i < Client::s_sessions.size(); ++i) {
  45. if (Client::s_sessions[i].session_id() == session_id_or_error.value()) {
  46. return Client::s_sessions.take(i);
  47. }
  48. }
  49. return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::InvalidSessionId, "Invalid session id");
  50. }
  51. void Client::close_session(unsigned session_id)
  52. {
  53. bool found = Client::s_sessions.remove_first_matching([&](auto const& it) {
  54. return it->session_id() == session_id;
  55. });
  56. if (found)
  57. dbgln_if(WEBDRIVER_DEBUG, "Shut down session {}", session_id);
  58. else
  59. dbgln_if(WEBDRIVER_DEBUG, "Unable to shut down session {}: Not found", session_id);
  60. }
  61. // 8.1 New Session, https://w3c.github.io/webdriver/#dfn-new-sessions
  62. // POST /session
  63. Web::WebDriver::Response Client::new_session(Web::WebDriver::Parameters, JsonValue payload)
  64. {
  65. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session");
  66. // FIXME: 1. If the maximum active sessions is equal to the length of the list of active sessions,
  67. // return error with error code session not created.
  68. // FIXME: 2. If the remote end is an intermediary node, take implementation-defined steps that either
  69. // result in returning an error with error code session not created, or in returning a
  70. // success with data that is isomorphic to that returned by remote ends according to the
  71. // rest of this algorithm. If an error is not returned, the intermediary node must retain a
  72. // reference to the session created on the upstream node as the associated session such
  73. // that commands may be forwarded to this associated session on subsequent commands.
  74. // FIXME: 3. If the maximum active sessions is equal to the length of the list of active sessions,
  75. // return error with error code session not created.
  76. // 4. Let capabilities be the result of trying to process capabilities with parameters as an argument.
  77. auto capabilities = TRY(Web::WebDriver::process_capabilities(payload));
  78. // 5. If capabilities’s is null, return error with error code session not created.
  79. if (capabilities.is_null())
  80. return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::SessionNotCreated, "Could not match capabilities"sv);
  81. // 6. Let session id be the result of generating a UUID.
  82. // FIXME: Actually create a UUID.
  83. auto session_id = Client::s_next_session_id++;
  84. // 7. Let session be a new session with the session ID of session id.
  85. NonnullOwnPtr<Session> session = make<Session>(session_id, *this);
  86. auto start_result = session->start();
  87. if (start_result.is_error()) {
  88. return Web::WebDriver::Error::from_code(Web::WebDriver::ErrorCode::SessionNotCreated, String::formatted("Failed to start session: {}", start_result.error().string_literal()));
  89. }
  90. auto& web_content_connection = session->web_content_connection();
  91. // FIXME: 8. Set the current session to session.
  92. // FIXME: 9. Run any WebDriver new session algorithm defined in external specifications,
  93. // with arguments session and capabilities.
  94. // 10. Append session to active sessions.
  95. Client::s_sessions.append(move(session));
  96. // 11. Let body be a JSON Object initialized with:
  97. JsonObject body;
  98. // "sessionId"
  99. // session id
  100. body.set("sessionId", String::number(session_id));
  101. // "capabilities"
  102. // capabilities
  103. body.set("capabilities", move(capabilities));
  104. // FIXME: 12. Initialize the following from capabilities:
  105. // NOTE: See spec for steps
  106. // 13. Set the webdriver-active flag to true.
  107. web_content_connection.async_set_is_webdriver_active(true);
  108. // FIXME: 14. Set the current top-level browsing context for session with the top-level browsing context
  109. // of the UA’s current browsing context.
  110. // FIXME: 15. Set the request queue to a new queue.
  111. // 16. Return success with data body.
  112. return JsonValue { move(body) };
  113. }
  114. // 8.2 Delete Session, https://w3c.github.io/webdriver/#dfn-delete-session
  115. // DELETE /session/{session id}
  116. Web::WebDriver::Response Client::delete_session(Web::WebDriver::Parameters parameters, JsonValue)
  117. {
  118. dbgln_if(WEBDRIVER_DEBUG, "Handling DELETE /session/<session_id>");
  119. // 1. If the current session is an active session, try to close the session.
  120. auto session = TRY(take_session_with_id(parameters[0]));
  121. TRY(session->stop());
  122. // 2. Return success with data null.
  123. return JsonValue {};
  124. }
  125. // 8.3 Status, https://w3c.github.io/webdriver/#dfn-status
  126. // GET /status
  127. Web::WebDriver::Response Client::get_status(Web::WebDriver::Parameters, JsonValue)
  128. {
  129. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /status");
  130. // 1. Let body be a new JSON Object with the following properties:
  131. // "ready"
  132. // The remote end’s readiness state.
  133. // "message"
  134. // An implementation-defined string explaining the remote end’s readiness state.
  135. // FIXME: Report if we are somehow not ready.
  136. JsonObject body;
  137. body.set("ready", true);
  138. body.set("message", "Ready to start some sessions!");
  139. // 2. Return success with data body.
  140. return JsonValue { body };
  141. }
  142. // 9.1 Get Timeouts, https://w3c.github.io/webdriver/#dfn-get-timeouts
  143. // GET /session/{session id}/timeouts
  144. Web::WebDriver::Response Client::get_timeouts(Web::WebDriver::Parameters parameters, JsonValue)
  145. {
  146. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session id>/timeouts");
  147. auto* session = TRY(find_session_with_id(parameters[0]));
  148. return session->web_content_connection().get_timeouts();
  149. }
  150. // 9.2 Set Timeouts, https://w3c.github.io/webdriver/#dfn-set-timeouts
  151. // POST /session/{session id}/timeouts
  152. Web::WebDriver::Response Client::set_timeouts(Web::WebDriver::Parameters parameters, JsonValue payload)
  153. {
  154. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session id>/timeouts");
  155. auto* session = TRY(find_session_with_id(parameters[0]));
  156. return session->web_content_connection().set_timeouts(payload);
  157. }
  158. // 10.1 Navigate To, https://w3c.github.io/webdriver/#dfn-navigate-to
  159. // POST /session/{session id}/url
  160. Web::WebDriver::Response Client::navigate_to(Web::WebDriver::Parameters parameters, JsonValue payload)
  161. {
  162. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/url");
  163. auto* session = TRY(find_session_with_id(parameters[0]));
  164. return session->web_content_connection().navigate_to(payload);
  165. }
  166. // 10.2 Get Current URL, https://w3c.github.io/webdriver/#dfn-get-current-url
  167. // GET /session/{session id}/url
  168. Web::WebDriver::Response Client::get_current_url(Web::WebDriver::Parameters parameters, JsonValue)
  169. {
  170. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/url");
  171. auto* session = TRY(find_session_with_id(parameters[0]));
  172. return session->web_content_connection().get_current_url();
  173. }
  174. // 10.3 Back, https://w3c.github.io/webdriver/#dfn-back
  175. // POST /session/{session id}/back
  176. Web::WebDriver::Response Client::back(Web::WebDriver::Parameters parameters, JsonValue)
  177. {
  178. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/back");
  179. auto* session = TRY(find_session_with_id(parameters[0]));
  180. return session->web_content_connection().back();
  181. }
  182. // 10.4 Forward, https://w3c.github.io/webdriver/#dfn-forward
  183. // POST /session/{session id}/forward
  184. Web::WebDriver::Response Client::forward(Web::WebDriver::Parameters parameters, JsonValue)
  185. {
  186. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/forward");
  187. auto* session = TRY(find_session_with_id(parameters[0]));
  188. return session->web_content_connection().forward();
  189. }
  190. // 10.5 Refresh, https://w3c.github.io/webdriver/#dfn-refresh
  191. // POST /session/{session id}/refresh
  192. Web::WebDriver::Response Client::refresh(Web::WebDriver::Parameters parameters, JsonValue)
  193. {
  194. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/refresh");
  195. auto* session = TRY(find_session_with_id(parameters[0]));
  196. return session->web_content_connection().refresh();
  197. }
  198. // 10.6 Get Title, https://w3c.github.io/webdriver/#dfn-get-title
  199. // GET /session/{session id}/title
  200. Web::WebDriver::Response Client::get_title(Web::WebDriver::Parameters parameters, JsonValue)
  201. {
  202. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/title");
  203. auto* session = TRY(find_session_with_id(parameters[0]));
  204. return session->web_content_connection().get_title();
  205. }
  206. // 11.1 Get Window Handle, https://w3c.github.io/webdriver/#get-window-handle
  207. // GET /session/{session id}/window
  208. Web::WebDriver::Response Client::get_window_handle(Web::WebDriver::Parameters parameters, JsonValue)
  209. {
  210. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/window");
  211. auto* session = TRY(find_session_with_id(parameters[0]));
  212. return session->web_content_connection().get_window_handle();
  213. }
  214. // 11.2 Close Window, https://w3c.github.io/webdriver/#dfn-close-window
  215. // DELETE /session/{session id}/window
  216. Web::WebDriver::Response Client::close_window(Web::WebDriver::Parameters parameters, JsonValue)
  217. {
  218. dbgln_if(WEBDRIVER_DEBUG, "Handling DELETE /session/<session_id>/window");
  219. auto* session = TRY(find_session_with_id(parameters[0]));
  220. auto open_windows = TRY(session->web_content_connection().close_window());
  221. if (open_windows.is_array() && open_windows.as_array().is_empty())
  222. TRY(session->stop());
  223. return open_windows;
  224. }
  225. // 11.4 Get Window Handles, https://w3c.github.io/webdriver/#dfn-get-window-handles
  226. // GET /session/{session id}/window/handles
  227. Web::WebDriver::Response Client::get_window_handles(Web::WebDriver::Parameters parameters, JsonValue)
  228. {
  229. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/window/handles");
  230. auto* session = TRY(find_session_with_id(parameters[0]));
  231. return session->web_content_connection().get_window_handles();
  232. }
  233. // 11.8.1 Get Window Rect, https://w3c.github.io/webdriver/#dfn-get-window-rect
  234. // GET /session/{session id}/window/rect
  235. Web::WebDriver::Response Client::get_window_rect(Web::WebDriver::Parameters parameters, JsonValue)
  236. {
  237. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/window/rect");
  238. auto* session = TRY(find_session_with_id(parameters[0]));
  239. return session->web_content_connection().get_window_rect();
  240. }
  241. // 11.8.2 Set Window Rect, https://w3c.github.io/webdriver/#dfn-set-window-rect
  242. // POST /session/{session id}/window/rect
  243. Web::WebDriver::Response Client::set_window_rect(Web::WebDriver::Parameters parameters, JsonValue payload)
  244. {
  245. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/window/rect");
  246. auto* session = TRY(find_session_with_id(parameters[0]));
  247. return session->web_content_connection().set_window_rect(payload);
  248. }
  249. // 11.8.3 Maximize Window, https://w3c.github.io/webdriver/#dfn-maximize-window
  250. // POST /session/{session id}/window/maximize
  251. Web::WebDriver::Response Client::maximize_window(Web::WebDriver::Parameters parameters, JsonValue)
  252. {
  253. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/window/maximize");
  254. auto* session = TRY(find_session_with_id(parameters[0]));
  255. return session->web_content_connection().maximize_window();
  256. }
  257. // 11.8.4 Minimize Window, https://w3c.github.io/webdriver/#minimize-window
  258. // POST /session/{session id}/window/minimize
  259. Web::WebDriver::Response Client::minimize_window(Web::WebDriver::Parameters parameters, JsonValue)
  260. {
  261. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/window/minimize");
  262. auto* session = TRY(find_session_with_id(parameters[0]));
  263. return session->web_content_connection().minimize_window();
  264. }
  265. // 11.8.5 Fullscreen Window, https://w3c.github.io/webdriver/#dfn-fullscreen-window
  266. // POST /session/{session id}/window/fullscreen
  267. Web::WebDriver::Response Client::fullscreen_window(Web::WebDriver::Parameters parameters, JsonValue)
  268. {
  269. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/window/fullscreen");
  270. auto* session = TRY(find_session_with_id(parameters[0]));
  271. return session->web_content_connection().fullscreen_window();
  272. }
  273. // 12.3.2 Find Element, https://w3c.github.io/webdriver/#dfn-find-element
  274. // POST /session/{session id}/element
  275. Web::WebDriver::Response Client::find_element(Web::WebDriver::Parameters parameters, JsonValue payload)
  276. {
  277. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/element");
  278. auto* session = TRY(find_session_with_id(parameters[0]));
  279. return session->web_content_connection().find_element(payload);
  280. }
  281. // 12.3.3 Find Elements, https://w3c.github.io/webdriver/#dfn-find-elements
  282. // POST /session/{session id}/elements
  283. Web::WebDriver::Response Client::find_elements(Web::WebDriver::Parameters parameters, JsonValue payload)
  284. {
  285. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/elements");
  286. auto* session = TRY(find_session_with_id(parameters[0]));
  287. return session->web_content_connection().find_elements(payload);
  288. }
  289. // 12.3.4 Find Element From Element, https://w3c.github.io/webdriver/#dfn-find-element-from-element
  290. // POST /session/{session id}/element/{element id}/element
  291. Web::WebDriver::Response Client::find_element_from_element(Web::WebDriver::Parameters parameters, JsonValue payload)
  292. {
  293. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/element/<element_id>/element");
  294. auto* session = TRY(find_session_with_id(parameters[0]));
  295. return session->web_content_connection().find_element_from_element(payload, parameters[1]);
  296. }
  297. // 12.3.5 Find Elements From Element, https://w3c.github.io/webdriver/#dfn-find-elements-from-element
  298. // POST /session/{session id}/element/{element id}/elements
  299. Web::WebDriver::Response Client::find_elements_from_element(Web::WebDriver::Parameters parameters, JsonValue payload)
  300. {
  301. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/element/<element_id>/elements");
  302. auto* session = TRY(find_session_with_id(parameters[0]));
  303. return session->web_content_connection().find_elements_from_element(payload, parameters[1]);
  304. }
  305. // 12.3.6 Find Element From Shadow Root, https://w3c.github.io/webdriver/#find-element-from-shadow-root
  306. // POST /session/{session id}/shadow/{shadow id}/element
  307. Web::WebDriver::Response Client::find_element_from_shadow_root(Web::WebDriver::Parameters parameters, JsonValue payload)
  308. {
  309. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/shadow/<shadow_id>/element");
  310. auto* session = TRY(find_session_with_id(parameters[0]));
  311. return session->web_content_connection().find_element_from_shadow_root(payload, parameters[1]);
  312. }
  313. // 12.3.7 Find Elements From Shadow Root, https://w3c.github.io/webdriver/#find-elements-from-shadow-root
  314. // POST /session/{session id}/shadow/{shadow id}/elements
  315. Web::WebDriver::Response Client::find_elements_from_shadow_root(Web::WebDriver::Parameters parameters, JsonValue payload)
  316. {
  317. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/shadow/<shadow_id>/elements");
  318. auto* session = TRY(find_session_with_id(parameters[0]));
  319. return session->web_content_connection().find_elements_from_shadow_root(payload, parameters[1]);
  320. }
  321. // 12.3.8 Get Active Element, https://w3c.github.io/webdriver/#get-active-element
  322. // GET /session/{session id}/element/active
  323. Web::WebDriver::Response Client::get_active_element(Web::WebDriver::Parameters parameters, JsonValue)
  324. {
  325. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/active");
  326. auto* session = TRY(find_session_with_id(parameters[0]));
  327. return session->web_content_connection().get_active_element();
  328. }
  329. // 12.3.9 Get Element Shadow Root, https://w3c.github.io/webdriver/#get-element-shadow-root
  330. // GET /session/{session id}/element/{element id}/shadow
  331. Web::WebDriver::Response Client::get_element_shadow_root(Web::WebDriver::Parameters parameters, JsonValue)
  332. {
  333. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/shadow");
  334. auto* session = TRY(find_session_with_id(parameters[0]));
  335. return session->web_content_connection().get_element_shadow_root(parameters[1]);
  336. }
  337. // 12.4.1 Is Element Selected, https://w3c.github.io/webdriver/#dfn-is-element-selected
  338. // GET /session/{session id}/element/{element id}/selected
  339. Web::WebDriver::Response Client::is_element_selected(Web::WebDriver::Parameters parameters, JsonValue)
  340. {
  341. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/selected");
  342. auto* session = TRY(find_session_with_id(parameters[0]));
  343. return session->web_content_connection().is_element_selected(parameters[1]);
  344. }
  345. // 12.4.2 Get Element Attribute, https://w3c.github.io/webdriver/#dfn-get-element-attribute
  346. // GET /session/{session id}/element/{element id}/attribute/{name}
  347. Web::WebDriver::Response Client::get_element_attribute(Web::WebDriver::Parameters parameters, JsonValue)
  348. {
  349. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/attribute/<name>");
  350. auto* session = TRY(find_session_with_id(parameters[0]));
  351. return session->web_content_connection().get_element_attribute(parameters[1], parameters[2]);
  352. }
  353. // 12.4.3 Get Element Property, https://w3c.github.io/webdriver/#dfn-get-element-property
  354. // GET /session/{session id}/element/{element id}/property/{name}
  355. Web::WebDriver::Response Client::get_element_property(Web::WebDriver::Parameters parameters, JsonValue)
  356. {
  357. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/property/<name>");
  358. auto* session = TRY(find_session_with_id(parameters[0]));
  359. return session->web_content_connection().get_element_property(parameters[1], parameters[2]);
  360. }
  361. // 12.4.4 Get Element CSS Value, https://w3c.github.io/webdriver/#dfn-get-element-css-value
  362. // GET /session/{session id}/element/{element id}/css/{property name}
  363. Web::WebDriver::Response Client::get_element_css_value(Web::WebDriver::Parameters parameters, JsonValue)
  364. {
  365. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/css/<property_name>");
  366. auto* session = TRY(find_session_with_id(parameters[0]));
  367. return session->web_content_connection().get_element_css_value(parameters[1], parameters[2]);
  368. }
  369. // 12.4.5 Get Element Text, https://w3c.github.io/webdriver/#dfn-get-element-text
  370. // GET /session/{session id}/element/{element id}/text
  371. Web::WebDriver::Response Client::get_element_text(Web::WebDriver::Parameters parameters, JsonValue)
  372. {
  373. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/text");
  374. auto* session = TRY(find_session_with_id(parameters[0]));
  375. return session->web_content_connection().get_element_text(parameters[1]);
  376. }
  377. // 12.4.6 Get Element Tag Name, https://w3c.github.io/webdriver/#dfn-get-element-tag-name
  378. // GET /session/{session id}/element/{element id}/name
  379. Web::WebDriver::Response Client::get_element_tag_name(Web::WebDriver::Parameters parameters, JsonValue)
  380. {
  381. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/name");
  382. auto* session = TRY(find_session_with_id(parameters[0]));
  383. return session->web_content_connection().get_element_tag_name(parameters[1]);
  384. }
  385. // 12.4.7 Get Element Rect, https://w3c.github.io/webdriver/#dfn-get-element-rect
  386. // GET /session/{session id}/element/{element id}/rect
  387. Web::WebDriver::Response Client::get_element_rect(Web::WebDriver::Parameters parameters, JsonValue)
  388. {
  389. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/rect");
  390. auto* session = TRY(find_session_with_id(parameters[0]));
  391. return session->web_content_connection().get_element_rect(parameters[1]);
  392. }
  393. // 12.4.8 Is Element Enabled, https://w3c.github.io/webdriver/#dfn-is-element-enabled
  394. // GET /session/{session id}/element/{element id}/enabled
  395. Web::WebDriver::Response Client::is_element_enabled(Web::WebDriver::Parameters parameters, JsonValue)
  396. {
  397. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/enabled");
  398. auto* session = TRY(find_session_with_id(parameters[0]));
  399. return session->web_content_connection().is_element_enabled(parameters[1]);
  400. }
  401. // 13.1 Get Page Source, https://w3c.github.io/webdriver/#dfn-get-page-source
  402. // GET /session/{session id}/source
  403. Web::WebDriver::Response Client::get_source(Web::WebDriver::Parameters parameters, JsonValue)
  404. {
  405. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/source");
  406. auto* session = TRY(find_session_with_id(parameters[0]));
  407. return session->web_content_connection().get_source();
  408. }
  409. // 13.2.1 Execute Script, https://w3c.github.io/webdriver/#dfn-execute-script
  410. // POST /session/{session id}/execute/sync
  411. Web::WebDriver::Response Client::execute_script(Web::WebDriver::Parameters parameters, JsonValue payload)
  412. {
  413. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/execute/sync");
  414. auto* session = TRY(find_session_with_id(parameters[0]));
  415. return session->web_content_connection().execute_script(payload);
  416. }
  417. // 13.2.2 Execute Async Script, https://w3c.github.io/webdriver/#dfn-execute-async-script
  418. // POST /session/{session id}/execute/async
  419. Web::WebDriver::Response Client::execute_async_script(Web::WebDriver::Parameters parameters, JsonValue payload)
  420. {
  421. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/execute/async");
  422. auto* session = TRY(find_session_with_id(parameters[0]));
  423. return session->web_content_connection().execute_async_script(payload);
  424. }
  425. // 14.1 Get All Cookies, https://w3c.github.io/webdriver/#dfn-get-all-cookies
  426. // GET /session/{session id}/cookie
  427. Web::WebDriver::Response Client::get_all_cookies(Web::WebDriver::Parameters parameters, JsonValue)
  428. {
  429. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/cookie");
  430. auto* session = TRY(find_session_with_id(parameters[0]));
  431. return session->web_content_connection().get_all_cookies();
  432. }
  433. // 14.2 Get Named Cookie, https://w3c.github.io/webdriver/#dfn-get-named-cookie
  434. // GET /session/{session id}/cookie/{name}
  435. Web::WebDriver::Response Client::get_named_cookie(Web::WebDriver::Parameters parameters, JsonValue)
  436. {
  437. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/cookie/<name>");
  438. auto* session = TRY(find_session_with_id(parameters[0]));
  439. return session->web_content_connection().get_named_cookie(parameters[1]);
  440. }
  441. // 14.3 Add Cookie, https://w3c.github.io/webdriver/#dfn-adding-a-cookie
  442. // POST /session/{session id}/cookie
  443. Web::WebDriver::Response Client::add_cookie(Web::WebDriver::Parameters parameters, JsonValue payload)
  444. {
  445. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/cookie");
  446. auto* session = TRY(find_session_with_id(parameters[0]));
  447. return session->web_content_connection().add_cookie(payload);
  448. }
  449. // 14.4 Delete Cookie, https://w3c.github.io/webdriver/#dfn-delete-cookie
  450. // DELETE /session/{session id}/cookie/{name}
  451. Web::WebDriver::Response Client::delete_cookie(Web::WebDriver::Parameters parameters, JsonValue)
  452. {
  453. dbgln_if(WEBDRIVER_DEBUG, "Handling DELETE /session/<session_id>/cookie/<name>");
  454. auto* session = TRY(find_session_with_id(parameters[0]));
  455. return session->web_content_connection().delete_cookie(parameters[1]);
  456. }
  457. // 14.5 Delete All Cookies, https://w3c.github.io/webdriver/#dfn-delete-all-cookies
  458. // DELETE /session/{session id}/cookie
  459. Web::WebDriver::Response Client::delete_all_cookies(Web::WebDriver::Parameters parameters, JsonValue)
  460. {
  461. dbgln_if(WEBDRIVER_DEBUG, "Handling DELETE /session/<session_id>/cookie");
  462. auto* session = TRY(find_session_with_id(parameters[0]));
  463. return session->web_content_connection().delete_all_cookies();
  464. }
  465. // 16.1 Dismiss Alert, https://w3c.github.io/webdriver/#dismiss-alert
  466. // POST /session/{session id}/alert/dismiss
  467. Web::WebDriver::Response Client::dismiss_alert(Web::WebDriver::Parameters parameters, JsonValue)
  468. {
  469. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/alert/dismiss");
  470. auto* session = TRY(find_session_with_id(parameters[0]));
  471. return session->web_content_connection().dismiss_alert();
  472. }
  473. // 16.2 Accept Alert, https://w3c.github.io/webdriver/#accept-alert
  474. // POST /session/{session id}/alert/accept
  475. Web::WebDriver::Response Client::accept_alert(Web::WebDriver::Parameters parameters, JsonValue)
  476. {
  477. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/alert/accept");
  478. auto* session = TRY(find_session_with_id(parameters[0]));
  479. return session->web_content_connection().accept_alert();
  480. }
  481. // 16.3 Get Alert Text, https://w3c.github.io/webdriver/#get-alert-text
  482. // GET /session/{session id}/alert/text
  483. Web::WebDriver::Response Client::get_alert_text(Web::WebDriver::Parameters parameters, JsonValue)
  484. {
  485. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/alert/text");
  486. auto* session = TRY(find_session_with_id(parameters[0]));
  487. return session->web_content_connection().get_alert_text();
  488. }
  489. // 16.4 Send Alert Text, https://w3c.github.io/webdriver/#send-alert-text
  490. // POST /session/{session id}/alert/text
  491. Web::WebDriver::Response Client::send_alert_text(Web::WebDriver::Parameters parameters, JsonValue payload)
  492. {
  493. dbgln_if(WEBDRIVER_DEBUG, "Handling POST /session/<session_id>/alert/text");
  494. auto* session = TRY(find_session_with_id(parameters[0]));
  495. return session->web_content_connection().send_alert_text(payload);
  496. }
  497. // 17.1 Take Screenshot, https://w3c.github.io/webdriver/#take-screenshot
  498. // GET /session/{session id}/screenshot
  499. Web::WebDriver::Response Client::take_screenshot(Web::WebDriver::Parameters parameters, JsonValue)
  500. {
  501. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/screenshot");
  502. auto* session = TRY(find_session_with_id(parameters[0]));
  503. return session->web_content_connection().take_screenshot();
  504. }
  505. // 17.2 Take Element Screenshot, https://w3c.github.io/webdriver/#dfn-take-element-screenshot
  506. // GET /session/{session id}/element/{element id}/screenshot
  507. Web::WebDriver::Response Client::take_element_screenshot(Web::WebDriver::Parameters parameters, JsonValue)
  508. {
  509. dbgln_if(WEBDRIVER_DEBUG, "Handling GET /session/<session_id>/element/<element_id>/screenshot");
  510. auto* session = TRY(find_session_with_id(parameters[0]));
  511. return session->web_content_connection().take_element_screenshot(parameters[1]);
  512. }
  513. }