summaryrefslogtreecommitdiffstats
path: root/testing/geckodriver/marionette/src/result.rs
diff options
context:
space:
mode:
Diffstat (limited to 'testing/geckodriver/marionette/src/result.rs')
-rw-r--r--testing/geckodriver/marionette/src/result.rs223
1 files changed, 223 insertions, 0 deletions
diff --git a/testing/geckodriver/marionette/src/result.rs b/testing/geckodriver/marionette/src/result.rs
new file mode 100644
index 0000000000..95817c15f0
--- /dev/null
+++ b/testing/geckodriver/marionette/src/result.rs
@@ -0,0 +1,223 @@
+/* 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::de;
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+use serde_json::Value;
+
+use crate::common::{Cookie, Timeouts, WebElement};
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct NewWindow {
+ handle: String,
+ #[serde(rename = "type")]
+ type_hint: String,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct WindowRect {
+ pub x: i32,
+ pub y: i32,
+ pub width: i32,
+ pub height: i32,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct ElementRect {
+ pub x: f64,
+ pub y: f64,
+ pub width: f64,
+ pub height: f64,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+#[serde(untagged)]
+pub enum MarionetteResult {
+ #[serde(deserialize_with = "from_value", serialize_with = "to_value")]
+ Bool(bool),
+ #[serde(deserialize_with = "from_value", serialize_with = "to_empty_value")]
+ Null,
+ NewWindow(NewWindow),
+ WindowRect(WindowRect),
+ ElementRect(ElementRect),
+ #[serde(deserialize_with = "from_value", serialize_with = "to_value")]
+ String(String),
+ Strings(Vec<String>),
+ #[serde(deserialize_with = "from_value", serialize_with = "to_value")]
+ WebElement(WebElement),
+ WebElements(Vec<WebElement>),
+ Cookies(Vec<Cookie>),
+ Timeouts(Timeouts),
+}
+
+fn to_value<T, S>(data: T, serializer: S) -> Result<S::Ok, S::Error>
+where
+ S: Serializer,
+ T: Serialize,
+{
+ #[derive(Serialize)]
+ struct Wrapper<T> {
+ value: T,
+ }
+
+ Wrapper { value: data }.serialize(serializer)
+}
+
+fn to_empty_value<S>(serializer: S) -> Result<S::Ok, S::Error>
+where
+ S: Serializer,
+{
+ #[derive(Serialize)]
+ struct Wrapper {
+ value: Value,
+ }
+
+ Wrapper { value: Value::Null }.serialize(serializer)
+}
+
+fn from_value<'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> {
+ value: T,
+ }
+
+ let v = Value::deserialize(deserializer)?;
+ if v.is_object() {
+ let w = serde_json::from_value::<Wrapper<T>>(v).map_err(de::Error::custom)?;
+ Ok(w.value)
+ } else {
+ Err(de::Error::custom("Cannot be deserialized to struct"))
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::test::{assert_de, assert_ser_de, ELEMENT_KEY};
+ use serde_json::json;
+
+ #[test]
+ fn test_boolean_response() {
+ assert_ser_de(&MarionetteResult::Bool(true), json!({"value": true}));
+ }
+
+ #[test]
+ fn test_cookies_response() {
+ let mut data = Vec::new();
+ data.push(Cookie {
+ name: "foo".into(),
+ value: "bar".into(),
+ path: Some("/common".into()),
+ domain: Some("web-platform.test".into()),
+ secure: false,
+ http_only: false,
+ expiry: None,
+ same_site: Some("Strict".into()),
+ });
+ assert_ser_de(
+ &MarionetteResult::Cookies(data),
+ json!([{"name":"foo","value":"bar","path":"/common","domain":"web-platform.test","secure":false,"httpOnly":false,"sameSite":"Strict"}]),
+ );
+ }
+
+ #[test]
+ fn test_new_window_response() {
+ let data = NewWindow {
+ handle: "6442450945".into(),
+ type_hint: "tab".into(),
+ };
+ let json = json!({"handle": "6442450945", "type": "tab"});
+ assert_ser_de(&MarionetteResult::NewWindow(data), json);
+ }
+
+ #[test]
+ fn test_web_element_response() {
+ let data = WebElement {
+ element: "foo".into(),
+ };
+ assert_ser_de(
+ &MarionetteResult::WebElement(data),
+ json!({"value": {ELEMENT_KEY: "foo"}}),
+ );
+ }
+
+ #[test]
+ fn test_web_elements_response() {
+ let data = vec![
+ WebElement {
+ element: "foo".into(),
+ },
+ WebElement {
+ element: "bar".into(),
+ },
+ ];
+ assert_ser_de(
+ &MarionetteResult::WebElements(data),
+ json!([{ELEMENT_KEY: "foo"}, {ELEMENT_KEY: "bar"}]),
+ );
+ }
+
+ #[test]
+ fn test_timeouts_response() {
+ let data = Timeouts {
+ implicit: Some(1000),
+ page_load: Some(200000),
+ script: Some(Some(60000)),
+ };
+ assert_ser_de(
+ &MarionetteResult::Timeouts(data),
+ json!({"implicit":1000,"pageLoad":200000,"script":60000}),
+ );
+ }
+
+ #[test]
+ fn test_string_response() {
+ assert_ser_de(
+ &MarionetteResult::String("foo".into()),
+ json!({"value": "foo"}),
+ );
+ }
+
+ #[test]
+ fn test_strings_response() {
+ assert_ser_de(
+ &MarionetteResult::Strings(vec!["2147483649".to_string()]),
+ json!(["2147483649"]),
+ );
+ }
+
+ #[test]
+ fn test_null_response() {
+ assert_ser_de(&MarionetteResult::Null, json!({ "value": null }));
+ }
+
+ #[test]
+ fn test_window_rect_response() {
+ let data = WindowRect {
+ x: 100,
+ y: 100,
+ width: 800,
+ height: 600,
+ };
+ let json = json!({"x": 100, "y": 100, "width": 800, "height": 600});
+ assert_ser_de(&MarionetteResult::WindowRect(data), json);
+ }
+
+ #[test]
+ fn test_element_rect_response() {
+ let data = ElementRect {
+ x: 8.0,
+ y: 8.0,
+ width: 148.6666717529297,
+ height: 22.0,
+ };
+ let json = json!({"x": 8, "y": 8, "width": 148.6666717529297, "height": 22});
+ assert_de(&MarionetteResult::ElementRect(data), json);
+ }
+}