common.rs (8334B)
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 serde::ser::{Serialize, Serializer}; 6 use serde::{Deserialize, Deserializer}; 7 use std::collections::HashMap; 8 use std::fmt::{self, Display, Formatter}; 9 10 pub static ELEMENT_KEY: &str = "element-6066-11e4-a52e-4f735466cecf"; 11 pub static FRAME_KEY: &str = "frame-075b-4da1-b6ba-e579c2d3230a"; 12 pub static SHADOW_KEY: &str = "shadow-6066-11e4-a52e-4f735466cecf"; 13 pub static WINDOW_KEY: &str = "window-fcc6-11e5-b4f8-330a88ab9d7f"; 14 15 pub static MAX_SAFE_INTEGER: u64 = 9_007_199_254_740_991; 16 17 pub type Parameters = HashMap<String, String>; 18 19 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] 20 pub struct Cookie { 21 pub name: String, 22 pub value: String, 23 pub path: Option<String>, 24 pub domain: Option<String>, 25 #[serde(default)] 26 pub secure: bool, 27 #[serde(rename = "httpOnly")] 28 pub http_only: bool, 29 #[serde(skip_serializing_if = "Option::is_none")] 30 pub expiry: Option<Date>, 31 #[serde(skip_serializing_if = "Option::is_none", rename = "sameSite")] 32 pub same_site: Option<String>, 33 } 34 35 #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] 36 #[serde(rename_all = "camelCase")] 37 pub struct CredentialParameters { 38 pub credential_id: String, 39 pub is_resident_credential: bool, 40 pub rp_id: String, 41 pub private_key: String, 42 #[serde(default)] 43 pub user_handle: String, 44 pub sign_count: u64, 45 } 46 47 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] 48 pub struct Date(pub u64); 49 50 #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] 51 #[serde(untagged)] 52 pub enum FrameId { 53 Short(u16), 54 #[serde( 55 rename = "element-6066-11e4-a52e-4f735466cecf", 56 serialize_with = "serialize_webelement_id" 57 )] 58 Element(WebElement), 59 Top, 60 } 61 62 // TODO(Henrik): Remove when ToMarionette trait has been fixed (Bug 1481776) 63 fn serialize_webelement_id<S>(element: &WebElement, serializer: S) -> Result<S::Ok, S::Error> 64 where 65 S: Serializer, 66 { 67 element.serialize(serializer) 68 } 69 70 #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] 71 pub enum LocatorStrategy { 72 #[serde(rename = "css selector")] 73 CSSSelector, 74 #[serde(rename = "link text")] 75 LinkText, 76 #[serde(rename = "partial link text")] 77 PartialLinkText, 78 #[serde(rename = "tag name")] 79 TagName, 80 #[serde(rename = "xpath")] 81 XPath, 82 } 83 84 #[derive(Clone, Debug, PartialEq)] 85 pub struct ShadowRoot(pub String); 86 87 // private 88 #[derive(Serialize, Deserialize)] 89 struct ShadowRootObject { 90 #[serde(rename = "shadow-6066-11e4-a52e-4f735466cecf")] 91 id: String, 92 } 93 94 impl Serialize for ShadowRoot { 95 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 96 where 97 S: Serializer, 98 { 99 ShadowRootObject { id: self.0.clone() }.serialize(serializer) 100 } 101 } 102 103 impl<'de> Deserialize<'de> for ShadowRoot { 104 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 105 where 106 D: Deserializer<'de>, 107 { 108 Deserialize::deserialize(deserializer).map(|ShadowRootObject { id }| ShadowRoot(id)) 109 } 110 } 111 112 impl Display for ShadowRoot { 113 fn fmt(&self, f: &mut Formatter) -> fmt::Result { 114 write!(f, "{}", self.0) 115 } 116 } 117 118 #[derive(Clone, Debug, PartialEq)] 119 pub struct WebElement(pub String); 120 121 // private 122 #[derive(Serialize, Deserialize)] 123 struct WebElementObject { 124 #[serde(rename = "element-6066-11e4-a52e-4f735466cecf")] 125 id: String, 126 } 127 128 impl Serialize for WebElement { 129 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 130 where 131 S: Serializer, 132 { 133 WebElementObject { id: self.0.clone() }.serialize(serializer) 134 } 135 } 136 137 impl<'de> Deserialize<'de> for WebElement { 138 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 139 where 140 D: Deserializer<'de>, 141 { 142 Deserialize::deserialize(deserializer).map(|WebElementObject { id }| WebElement(id)) 143 } 144 } 145 146 impl Display for WebElement { 147 fn fmt(&self, f: &mut Formatter) -> fmt::Result { 148 write!(f, "{}", self.0) 149 } 150 } 151 152 #[derive(Clone, Debug, PartialEq)] 153 pub struct WebFrame(pub String); 154 155 // private 156 #[derive(Serialize, Deserialize)] 157 struct WebFrameObject { 158 #[serde(rename = "frame-075b-4da1-b6ba-e579c2d3230a")] 159 id: String, 160 } 161 162 impl Serialize for WebFrame { 163 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 164 where 165 S: Serializer, 166 { 167 WebFrameObject { id: self.0.clone() }.serialize(serializer) 168 } 169 } 170 171 impl<'de> Deserialize<'de> for WebFrame { 172 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 173 where 174 D: Deserializer<'de>, 175 { 176 Deserialize::deserialize(deserializer).map(|WebFrameObject { id }| WebFrame(id)) 177 } 178 } 179 180 #[derive(Clone, Debug, PartialEq)] 181 pub struct WebWindow(pub String); 182 183 // private 184 #[derive(Serialize, Deserialize)] 185 struct WebWindowObject { 186 #[serde(rename = "window-fcc6-11e5-b4f8-330a88ab9d7f")] 187 id: String, 188 } 189 190 impl Serialize for WebWindow { 191 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> 192 where 193 S: Serializer, 194 { 195 WebWindowObject { id: self.0.clone() }.serialize(serializer) 196 } 197 } 198 199 impl<'de> Deserialize<'de> for WebWindow { 200 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> 201 where 202 D: Deserializer<'de>, 203 { 204 Deserialize::deserialize(deserializer).map(|WebWindowObject { id }| WebWindow(id)) 205 } 206 } 207 208 #[cfg(test)] 209 mod tests { 210 use super::*; 211 use crate::test::{assert_ser, assert_ser_de}; 212 use serde_json::{self, json}; 213 214 #[test] 215 fn test_json_date() { 216 assert_ser_de(&Date(1234), json!(1234)); 217 } 218 219 #[test] 220 fn test_json_date_invalid() { 221 assert!(serde_json::from_value::<Date>(json!("2018-01-01")).is_err()); 222 } 223 224 #[test] 225 fn test_json_frame_id_short() { 226 assert_ser_de(&FrameId::Short(1234), json!(1234)); 227 } 228 229 #[test] 230 fn test_json_frame_id_webelement() { 231 assert_ser( 232 &FrameId::Element(WebElement("elem".into())), 233 json!({ELEMENT_KEY: "elem"}), 234 ); 235 } 236 237 #[test] 238 fn test_json_frame_id_invalid() { 239 assert!(serde_json::from_value::<FrameId>(json!(true)).is_err()); 240 } 241 242 #[test] 243 fn test_json_locator_strategy_css_selector() { 244 assert_ser_de(&LocatorStrategy::CSSSelector, json!("css selector")); 245 } 246 247 #[test] 248 fn test_json_locator_strategy_link_text() { 249 assert_ser_de(&LocatorStrategy::LinkText, json!("link text")); 250 } 251 252 #[test] 253 fn test_json_locator_strategy_partial_link_text() { 254 assert_ser_de( 255 &LocatorStrategy::PartialLinkText, 256 json!("partial link text"), 257 ); 258 } 259 260 #[test] 261 fn test_json_locator_strategy_tag_name() { 262 assert_ser_de(&LocatorStrategy::TagName, json!("tag name")); 263 } 264 265 #[test] 266 fn test_json_locator_strategy_xpath() { 267 assert_ser_de(&LocatorStrategy::XPath, json!("xpath")); 268 } 269 270 #[test] 271 fn test_json_locator_strategy_invalid() { 272 assert!(serde_json::from_value::<LocatorStrategy>(json!("foo")).is_err()); 273 } 274 275 #[test] 276 fn test_json_shadowroot() { 277 assert_ser_de(&ShadowRoot("shadow".into()), json!({SHADOW_KEY: "shadow"})); 278 } 279 280 #[test] 281 fn test_json_shadowroot_invalid() { 282 assert!(serde_json::from_value::<ShadowRoot>(json!({"invalid":"shadow"})).is_err()); 283 } 284 285 #[test] 286 fn test_json_webelement() { 287 assert_ser_de(&WebElement("elem".into()), json!({ELEMENT_KEY: "elem"})); 288 } 289 290 #[test] 291 fn test_json_webelement_invalid() { 292 assert!(serde_json::from_value::<WebElement>(json!({"invalid": "elem"})).is_err()); 293 } 294 295 #[test] 296 fn test_json_webframe() { 297 assert_ser_de(&WebFrame("frame".into()), json!({FRAME_KEY: "frame"})); 298 } 299 300 #[test] 301 fn test_json_webframe_invalid() { 302 assert!(serde_json::from_value::<WebFrame>(json!({"invalid": "frame"})).is_err()); 303 } 304 305 #[test] 306 fn test_json_webwindow() { 307 assert_ser_de(&WebWindow("window".into()), json!({WINDOW_KEY: "window"})); 308 } 309 310 #[test] 311 fn test_json_webwindow_invalid() { 312 assert!(serde_json::from_value::<WebWindow>(json!({"invalid": "window"})).is_err()); 313 } 314 }