diff options
Diffstat (limited to '')
-rw-r--r-- | testing/geckodriver/marionette/src/common.rs | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/testing/geckodriver/marionette/src/common.rs b/testing/geckodriver/marionette/src/common.rs new file mode 100644 index 0000000000..e819757e73 --- /dev/null +++ b/testing/geckodriver/marionette/src/common.rs @@ -0,0 +1,240 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use serde::ser::SerializeMap; +use serde::{de, Deserialize, Deserializer, Serialize, Serializer}; +use serde_json::Value; + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct BoolValue { + value: bool, +} + +impl BoolValue { + pub fn new(val: bool) -> Self { + BoolValue { value: val } + } +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Cookie { + pub name: String, + pub value: String, + #[serde(skip_serializing_if = "Option::is_none")] + pub path: Option<String>, + #[serde(skip_serializing_if = "Option::is_none")] + pub domain: Option<String>, + #[serde(default)] + pub secure: bool, + #[serde(default, rename = "httpOnly")] + pub http_only: bool, + #[serde(skip_serializing_if = "Option::is_none")] + pub expiry: Option<Date>, + #[serde(skip_serializing_if = "Option::is_none", rename = "sameSite")] + pub same_site: Option<String>, +} + +pub fn to_cookie<T, S>(data: T, serializer: S) -> Result<S::Ok, S::Error> +where + S: Serializer, + T: Serialize, +{ + #[derive(Serialize)] + struct Wrapper<T> { + cookie: T, + } + + Wrapper { cookie: data }.serialize(serializer) +} + +pub fn from_cookie<'de, D, T>(deserializer: D) -> Result<T, D::Error> +where + D: Deserializer<'de>, + T: serde::de::DeserializeOwned, + T: std::fmt::Debug, +{ + #[derive(Debug, Deserialize)] + struct Wrapper<T> { + cookie: T, + } + + let w = Wrapper::deserialize(deserializer)?; + Ok(w.cookie) +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Date(pub u64); + +#[derive(Clone, Debug, PartialEq)] +pub enum Frame { + Index(u16), + Element(String), + Parent, +} + +impl Serialize for Frame { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: Serializer, + { + let mut map = serializer.serialize_map(Some(1))?; + match self { + Frame::Index(nth) => map.serialize_entry("id", nth)?, + Frame::Element(el) => map.serialize_entry("element", el)?, + Frame::Parent => map.serialize_entry("id", &Value::Null)?, + } + map.end() + } +} + +impl<'de> Deserialize<'de> for Frame { + fn deserialize<D>(deserializer: D) -> Result<Frame, D::Error> + where + D: Deserializer<'de>, + { + #[derive(Debug, Deserialize)] + #[serde(rename_all = "lowercase")] + struct JsonFrame { + id: Option<u16>, + element: Option<String>, + } + + let json = JsonFrame::deserialize(deserializer)?; + match (json.id, json.element) { + (Some(_id), Some(_element)) => Err(de::Error::custom("conflicting frame identifiers")), + (Some(id), None) => Ok(Frame::Index(id)), + (None, Some(element)) => Ok(Frame::Element(element)), + (None, None) => Ok(Frame::Parent), + } + } +} + +// TODO(nupur): Bug 1567165 - Make WebElement in Marionette a unit struct +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct WebElement { + #[serde(rename = "element-6066-11e4-a52e-4f735466cecf")] + pub element: String, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Timeouts { + #[serde(default, skip_serializing_if = "Option::is_none")] + pub implicit: Option<u64>, + #[serde(default, rename = "pageLoad", skip_serializing_if = "Option::is_none")] + pub page_load: Option<u64>, + #[serde(default, skip_serializing_if = "Option::is_none")] + #[allow(clippy::option_option)] + pub script: Option<Option<u64>>, +} + +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct Window { + pub handle: String, +} + +pub fn to_name<T, S>(data: T, serializer: S) -> Result<S::Ok, S::Error> +where + S: Serializer, + T: Serialize, +{ + #[derive(Serialize)] + struct Wrapper<T> { + name: T, + } + + Wrapper { name: data }.serialize(serializer) +} + +pub fn from_name<'de, D, T>(deserializer: D) -> Result<T, D::Error> +where + D: Deserializer<'de>, + T: serde::de::DeserializeOwned, + T: std::fmt::Debug, +{ + #[derive(Debug, Deserialize)] + struct Wrapper<T> { + name: T, + } + + let w = Wrapper::deserialize(deserializer)?; + Ok(w.name) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::test::{assert_de, assert_ser, assert_ser_de, ELEMENT_KEY}; + use serde_json::json; + + #[test] + fn test_cookie_default_values() { + let data = Cookie { + name: "hello".into(), + value: "world".into(), + path: None, + domain: None, + secure: false, + http_only: false, + expiry: None, + same_site: None, + }; + assert_de(&data, json!({"name":"hello", "value":"world"})); + } + + #[test] + fn test_json_frame_index() { + assert_ser_de(&Frame::Index(1234), json!({"id": 1234})); + } + + #[test] + fn test_json_frame_element() { + assert_ser_de(&Frame::Element("elem".into()), json!({"element": "elem"})); + } + + #[test] + fn test_json_frame_parent() { + assert_ser_de(&Frame::Parent, json!({ "id": null })); + } + + #[test] + fn test_web_element() { + let data = WebElement { + element: "foo".into(), + }; + assert_ser_de(&data, json!({ELEMENT_KEY: "foo"})); + } + + #[test] + fn test_timeouts_with_all_params() { + let data = Timeouts { + implicit: Some(1000), + page_load: Some(200000), + script: Some(Some(60000)), + }; + assert_ser_de( + &data, + json!({"implicit":1000,"pageLoad":200000,"script":60000}), + ); + } + + #[test] + fn test_timeouts_with_missing_params() { + let data = Timeouts { + implicit: Some(1000), + page_load: None, + script: None, + }; + assert_ser_de(&data, json!({"implicit":1000})); + } + + #[test] + fn test_timeouts_setting_script_none() { + let data = Timeouts { + implicit: Some(1000), + page_load: None, + script: Some(None), + }; + assert_ser(&data, json!({"implicit":1000, "script":null})); + } +} |