response.rs (9333B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 use crate::common::{Cookie, CredentialParameters}; 6 use serde::ser::{Serialize, Serializer}; 7 use serde_json::Value; 8 9 #[derive(Debug, PartialEq, Serialize)] 10 #[serde(untagged, remote = "Self")] 11 pub enum WebDriverResponse { 12 NewWindow(NewWindowResponse), 13 CloseWindow(CloseWindowResponse), 14 Cookie(CookieResponse), 15 Cookies(CookiesResponse), 16 DeleteSession, 17 ElementRect(ElementRectResponse), 18 Generic(ValueResponse), 19 WebAuthnAddVirtualAuthenticator(u64), 20 WebAuthnGetCredentials(GetCredentialsResponse), 21 NewSession(NewSessionResponse), 22 Timeouts(TimeoutsResponse), 23 Void, 24 WindowRect(WindowRectResponse), 25 } 26 27 impl 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)] 43 pub struct NewWindowResponse { 44 pub handle: String, 45 #[serde(rename = "type")] 46 pub typ: String, 47 } 48 49 #[derive(Debug, PartialEq, Serialize)] 50 pub struct CloseWindowResponse(pub Vec<String>); 51 52 #[derive(Clone, Debug, PartialEq, Serialize)] 53 pub struct CookieResponse(pub Cookie); 54 55 #[derive(Debug, PartialEq, Serialize)] 56 pub struct CookiesResponse(pub Vec<Cookie>); 57 58 #[derive(Debug, PartialEq, Serialize)] 59 pub struct ElementRectResponse { 60 /// X axis position of the top-left corner of the element relative 61 /// to the current browsing context’s document element in CSS reference 62 /// pixels. 63 pub x: f64, 64 65 /// Y axis position of the top-left corner of the element relative 66 /// to the current browsing context’s document element in CSS reference 67 /// pixels. 68 pub y: f64, 69 70 /// Height of the element’s [bounding rectangle] in CSS reference 71 /// pixels. 72 /// 73 /// [bounding rectangle]: https://drafts.fxtf.org/geometry/#rectangle 74 pub width: f64, 75 76 /// Width of the element’s [bounding rectangle] in CSS reference 77 /// pixels. 78 /// 79 /// [bounding rectangle]: https://drafts.fxtf.org/geometry/#rectangle 80 pub height: f64, 81 } 82 83 #[derive(Debug, PartialEq, Serialize)] 84 pub struct GetCredentialsResponse(pub Vec<CredentialParameters>); 85 86 #[derive(Debug, PartialEq, Serialize)] 87 pub struct NewSessionResponse { 88 #[serde(rename = "sessionId")] 89 pub session_id: String, 90 pub capabilities: Value, 91 } 92 93 impl 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)] 103 pub struct TimeoutsResponse { 104 pub script: Option<u64>, 105 #[serde(rename = "pageLoad")] 106 pub page_load: u64, 107 pub implicit: u64, 108 } 109 110 impl TimeoutsResponse { 111 pub fn new(script: Option<u64>, page_load: u64, implicit: u64) -> TimeoutsResponse { 112 TimeoutsResponse { 113 script, 114 page_load, 115 implicit, 116 } 117 } 118 } 119 120 #[derive(Debug, PartialEq, Serialize)] 121 pub struct ValueResponse(pub Value); 122 123 #[derive(Debug, PartialEq, Serialize)] 124 pub struct WindowRectResponse { 125 /// `WindowProxy`’s [screenX] attribute. 126 /// 127 /// [screenX]: https://drafts.csswg.org/cssom-view/#dom-window-screenx 128 pub x: i32, 129 130 /// `WindowProxy`’s [screenY] attribute. 131 /// 132 /// [screenY]: https://drafts.csswg.org/cssom-view/#dom-window-screeny 133 pub y: i32, 134 135 /// Width of the top-level browsing context’s outer dimensions, including 136 /// any browser chrome and externally drawn window decorations in CSS 137 /// reference pixels. 138 pub width: i32, 139 140 /// Height of the top-level browsing context’s outer dimensions, including 141 /// any browser chrome and externally drawn window decorations in CSS 142 /// reference pixels. 143 pub height: i32, 144 } 145 146 #[cfg(test)] 147 mod tests { 148 use serde_json::{json, Map}; 149 150 use super::*; 151 use crate::common::Date; 152 use crate::test::assert_ser; 153 154 #[test] 155 fn test_json_new_window_response() { 156 let json = json!({"value": {"handle": "42", "type": "window"}}); 157 let response = WebDriverResponse::NewWindow(NewWindowResponse { 158 handle: "42".into(), 159 typ: "window".into(), 160 }); 161 162 assert_ser(&response, json); 163 } 164 165 #[test] 166 fn test_json_close_window_response() { 167 assert_ser( 168 &WebDriverResponse::CloseWindow(CloseWindowResponse(vec!["1234".into()])), 169 json!({"value": ["1234"]}), 170 ); 171 } 172 173 #[test] 174 fn test_json_cookie_response_with_optional() { 175 let json = json!({"value": { 176 "name": "foo", 177 "value": "bar", 178 "path": "/", 179 "domain": "foo.bar", 180 "secure": true, 181 "httpOnly": false, 182 "expiry": 123, 183 "sameSite": "Strict", 184 }}); 185 let response = WebDriverResponse::Cookie(CookieResponse(Cookie { 186 name: "foo".into(), 187 value: "bar".into(), 188 path: Some("/".into()), 189 domain: Some("foo.bar".into()), 190 expiry: Some(Date(123)), 191 secure: true, 192 http_only: false, 193 same_site: Some("Strict".into()), 194 })); 195 196 assert_ser(&response, json); 197 } 198 199 #[test] 200 fn test_json_cookie_response_without_optional() { 201 let json = json!({"value": { 202 "name": "foo", 203 "value": "bar", 204 "path": "/", 205 "domain": null, 206 "secure": true, 207 "httpOnly": false, 208 }}); 209 let response = WebDriverResponse::Cookie(CookieResponse(Cookie { 210 name: "foo".into(), 211 value: "bar".into(), 212 path: Some("/".into()), 213 domain: None, 214 expiry: None, 215 secure: true, 216 http_only: false, 217 same_site: None, 218 })); 219 220 assert_ser(&response, json); 221 } 222 223 #[test] 224 fn test_json_cookies_response() { 225 let json = json!({"value": [{ 226 "name": "name", 227 "value": "value", 228 "path": "/", 229 "domain": null, 230 "secure": true, 231 "httpOnly": false, 232 "sameSite": "None", 233 }]}); 234 let response = WebDriverResponse::Cookies(CookiesResponse(vec![Cookie { 235 name: "name".into(), 236 value: "value".into(), 237 path: Some("/".into()), 238 domain: None, 239 expiry: None, 240 secure: true, 241 http_only: false, 242 same_site: Some("None".into()), 243 }])); 244 245 assert_ser(&response, json); 246 } 247 248 #[test] 249 fn test_json_delete_session_response() { 250 assert_ser(&WebDriverResponse::DeleteSession, json!({ "value": null })); 251 } 252 253 #[test] 254 fn test_json_element_rect_response() { 255 let json = json!({"value": { 256 "x": 0.0, 257 "y": 1.0, 258 "width": 2.0, 259 "height": 3.0, 260 }}); 261 let response = WebDriverResponse::ElementRect(ElementRectResponse { 262 x: 0f64, 263 y: 1f64, 264 width: 2f64, 265 height: 3f64, 266 }); 267 268 assert_ser(&response, json); 269 } 270 271 #[test] 272 fn test_json_generic_value_response() { 273 let response = { 274 let mut value = Map::new(); 275 value.insert( 276 "example".into(), 277 Value::Array(vec![Value::String("test".into())]), 278 ); 279 WebDriverResponse::Generic(ValueResponse(Value::Object(value))) 280 }; 281 assert_ser(&response, json!({"value": {"example": ["test"]}})); 282 } 283 284 #[test] 285 fn test_json_new_session_response() { 286 let response = 287 WebDriverResponse::NewSession(NewSessionResponse::new("id".into(), json!({}))); 288 assert_ser( 289 &response, 290 json!({"value": {"sessionId": "id", "capabilities": {}}}), 291 ); 292 } 293 294 #[test] 295 fn test_json_timeouts_response() { 296 assert_ser( 297 &WebDriverResponse::Timeouts(TimeoutsResponse::new(Some(1), 2, 3)), 298 json!({"value": {"script": 1, "pageLoad": 2, "implicit": 3}}), 299 ); 300 } 301 302 #[test] 303 fn test_json_timeouts_response_with_null_script_timeout() { 304 assert_ser( 305 &WebDriverResponse::Timeouts(TimeoutsResponse::new(None, 2, 3)), 306 json!({"value": {"script": null, "pageLoad": 2, "implicit": 3}}), 307 ); 308 } 309 310 #[test] 311 fn test_json_void_response() { 312 assert_ser(&WebDriverResponse::Void, json!({ "value": null })); 313 } 314 315 #[test] 316 fn test_json_window_rect_response() { 317 let json = json!({"value": { 318 "x": 0, 319 "y": 1, 320 "width": 2, 321 "height": 3, 322 }}); 323 let response = WebDriverResponse::WindowRect(WindowRectResponse { 324 x: 0i32, 325 y: 1i32, 326 width: 2i32, 327 height: 3i32, 328 }); 329 330 assert_ser(&response, json); 331 } 332 }