1use crate::common::{Cookie, Credentials};
6use serde::ser::{Serialize, Serializer};
7use serde_json::Value;
8
9#[derive(Debug, PartialEq, Serialize)]
10#[serde(untagged, remote = "Self")]
11pub enum WebDriverResponse {
12 CloseWindow(CloseWindowResponse),
13 Cookie(CookieResponse),
14 Cookies(CookiesResponse),
15 DeleteSession,
16 ElementRect(ElementRectResponse),
17 Generic(ValueResponse),
18 NewSession(NewSessionResponse),
19 NewWindow(NewWindowResponse),
20 Timeouts(TimeoutsResponse),
21 Void,
22 WebAuthnAddVirtualAuthenticator(u64),
23 WebAuthnGetCredentials(GetCredentialsResponse),
24 WindowRect(WindowRectResponse),
25}
26
27impl Serialize for WebDriverResponse {
28 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
29 where
30 S: Serializer,
31 {
32 #[derive(Serialize)]
33 struct Wrapper<'a> {
34 #[serde(with = "WebDriverResponse")]
35 value: &'a WebDriverResponse,
36 }
37
38 Wrapper { value: self }.serialize(serializer)
39 }
40}
41
42#[derive(Debug, PartialEq, Serialize)]
43pub struct NewWindowResponse {
44 pub handle: String,
45 #[serde(rename = "type")]
46 pub typ: String,
47}
48
49#[derive(Debug, PartialEq, Serialize)]
50pub struct CloseWindowResponse(pub Vec<String>);
51
52#[derive(Clone, Debug, PartialEq, Serialize)]
53pub struct CookieResponse(pub Cookie);
54
55#[derive(Debug, PartialEq, Serialize)]
56pub struct CookiesResponse(pub Vec<Cookie>);
57
58#[derive(Debug, PartialEq, Serialize)]
59pub struct ElementRectResponse {
60 pub x: f64,
64
65 pub y: f64,
69
70 pub width: f64,
75
76 pub height: f64,
81}
82
83#[derive(Debug, PartialEq, Serialize)]
84pub struct GetCredentialsResponse(pub Vec<Credentials>);
85
86#[derive(Debug, PartialEq, Serialize)]
87pub struct NewSessionResponse {
88 #[serde(rename = "sessionId")]
89 pub session_id: String,
90 pub capabilities: Value,
91}
92
93impl NewSessionResponse {
94 pub fn new(session_id: String, capabilities: Value) -> NewSessionResponse {
95 NewSessionResponse {
96 session_id,
97 capabilities,
98 }
99 }
100}
101
102#[derive(Debug, PartialEq, Serialize)]
103pub struct TimeoutsResponse {
104 pub script: Option<u64>,
105 #[serde(rename = "pageLoad")]
106 pub page_load: Option<u64>,
107 pub implicit: Option<u64>,
108}
109
110impl TimeoutsResponse {
111 pub fn new(
112 script: Option<u64>,
113 page_load: Option<u64>,
114 implicit: Option<u64>,
115 ) -> TimeoutsResponse {
116 TimeoutsResponse {
117 script,
118 page_load,
119 implicit,
120 }
121 }
122}
123
124#[derive(Debug, PartialEq, Serialize)]
125pub struct ValueResponse(pub Value);
126
127#[derive(Debug, PartialEq, Serialize)]
128pub struct WindowRectResponse {
129 pub x: i32,
133
134 pub y: i32,
138
139 pub width: i32,
143
144 pub height: i32,
148}
149
150#[cfg(test)]
151mod tests {
152 use serde_json::{json, Map};
153
154 use super::*;
155 use crate::common::Date;
156 use crate::test::assert_ser;
157
158 #[test]
159 fn test_json_new_window_response() {
160 let json = json!({"value": {"handle": "42", "type": "window"}});
161 let response = WebDriverResponse::NewWindow(NewWindowResponse {
162 handle: "42".into(),
163 typ: "window".into(),
164 });
165
166 assert_ser(&response, json);
167 }
168
169 #[test]
170 fn test_json_close_window_response() {
171 assert_ser(
172 &WebDriverResponse::CloseWindow(CloseWindowResponse(vec!["1234".into()])),
173 json!({"value": ["1234"]}),
174 );
175 }
176
177 #[test]
178 fn test_json_cookie_response_with_optional() {
179 let json = json!({"value": {
180 "name": "foo",
181 "value": "bar",
182 "path": "/",
183 "domain": "foo.bar",
184 "secure": true,
185 "httpOnly": false,
186 "expiry": 123,
187 "sameSite": "Strict",
188 }});
189 let response = WebDriverResponse::Cookie(CookieResponse(Cookie {
190 name: "foo".into(),
191 value: "bar".into(),
192 path: Some("/".into()),
193 domain: Some("foo.bar".into()),
194 expiry: Some(Date(123)),
195 secure: true,
196 http_only: false,
197 same_site: Some("Strict".into()),
198 }));
199
200 assert_ser(&response, json);
201 }
202
203 #[test]
204 fn test_json_cookie_response_without_optional() {
205 let json = json!({"value": {
206 "name": "foo",
207 "value": "bar",
208 "path": "/",
209 "domain": null,
210 "secure": true,
211 "httpOnly": false,
212 }});
213 let response = WebDriverResponse::Cookie(CookieResponse(Cookie {
214 name: "foo".into(),
215 value: "bar".into(),
216 path: Some("/".into()),
217 domain: None,
218 expiry: None,
219 secure: true,
220 http_only: false,
221 same_site: None,
222 }));
223
224 assert_ser(&response, json);
225 }
226
227 #[test]
228 fn test_json_cookies_response() {
229 let json = json!({"value": [{
230 "name": "name",
231 "value": "value",
232 "path": "/",
233 "domain": null,
234 "secure": true,
235 "httpOnly": false,
236 "sameSite": "None",
237 }]});
238 let response = WebDriverResponse::Cookies(CookiesResponse(vec![Cookie {
239 name: "name".into(),
240 value: "value".into(),
241 path: Some("/".into()),
242 domain: None,
243 expiry: None,
244 secure: true,
245 http_only: false,
246 same_site: Some("None".into()),
247 }]));
248
249 assert_ser(&response, json);
250 }
251
252 #[test]
253 fn test_json_delete_session_response() {
254 assert_ser(&WebDriverResponse::DeleteSession, json!({ "value": null }));
255 }
256
257 #[test]
258 fn test_json_element_rect_response() {
259 let json = json!({"value": {
260 "x": 0.0,
261 "y": 1.0,
262 "width": 2.0,
263 "height": 3.0,
264 }});
265 let response = WebDriverResponse::ElementRect(ElementRectResponse {
266 x: 0f64,
267 y: 1f64,
268 width: 2f64,
269 height: 3f64,
270 });
271
272 assert_ser(&response, json);
273 }
274
275 #[test]
276 fn test_json_generic_value_response() {
277 let response = {
278 let mut value = Map::new();
279 value.insert(
280 "example".into(),
281 Value::Array(vec![Value::String("test".into())]),
282 );
283 WebDriverResponse::Generic(ValueResponse(Value::Object(value)))
284 };
285 assert_ser(&response, json!({"value": {"example": ["test"]}}));
286 }
287
288 #[test]
289 fn test_json_new_session_response() {
290 let response =
291 WebDriverResponse::NewSession(NewSessionResponse::new("id".into(), json!({})));
292 assert_ser(
293 &response,
294 json!({"value": {"sessionId": "id", "capabilities": {}}}),
295 );
296 }
297
298 #[test]
299 fn test_json_timeouts_response() {
300 assert_ser(
301 &WebDriverResponse::Timeouts(TimeoutsResponse::new(Some(1), Some(2), Some(3))),
302 json!({"value": {"script": 1, "pageLoad": 2, "implicit": 3}}),
303 );
304 }
305
306 #[test]
307 fn test_json_timeouts_response_with_null_timeout() {
308 assert_ser(
309 &WebDriverResponse::Timeouts(TimeoutsResponse::new(None, None, None)),
310 json!({"value": {"script": null, "pageLoad": null, "implicit": null}}),
311 );
312 }
313
314 #[test]
315 fn test_json_void_response() {
316 assert_ser(&WebDriverResponse::Void, json!({ "value": null }));
317 }
318
319 #[test]
320 fn test_json_window_rect_response() {
321 let json = json!({"value": {
322 "x": 0,
323 "y": 1,
324 "width": 2,
325 "height": 3,
326 }});
327 let response = WebDriverResponse::WindowRect(WindowRectResponse {
328 x: 0i32,
329 y: 1i32,
330 width: 2i32,
331 height: 3i32,
332 });
333
334 assert_ser(&response, json);
335 }
336}