Client.cpp 25 KB

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