зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1564417 - Add first response types to Marionette crate. r=ato
Differential Revision: https://phabricator.services.mozilla.com/D38322 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
1e51ee6ad5
Коммит
1dc247d75c
|
@ -3,6 +3,7 @@ pub mod error;
|
||||||
pub mod common;
|
pub mod common;
|
||||||
pub mod marionette;
|
pub mod marionette;
|
||||||
pub mod message;
|
pub mod message;
|
||||||
|
pub mod result;
|
||||||
pub mod webdriver;
|
pub mod webdriver;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -6,6 +6,7 @@ use std::fmt;
|
||||||
|
|
||||||
use crate::error::MarionetteError;
|
use crate::error::MarionetteError;
|
||||||
use crate::marionette;
|
use crate::marionette;
|
||||||
|
use crate::result::MarionetteResult;
|
||||||
use crate::webdriver;
|
use crate::webdriver;
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
@ -47,7 +48,6 @@ enum MessageDirection {
|
||||||
}
|
}
|
||||||
|
|
||||||
type MessageId = u32;
|
type MessageId = u32;
|
||||||
type Payload = Map<String, Value>;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
struct Request(MessageId, Command);
|
struct Request(MessageId, Command);
|
||||||
|
@ -85,7 +85,7 @@ impl Serialize for Request {
|
||||||
enum Response {
|
enum Response {
|
||||||
Result {
|
Result {
|
||||||
id: MessageId,
|
id: MessageId,
|
||||||
result: Payload,
|
result: MarionetteResult,
|
||||||
},
|
},
|
||||||
Error {
|
Error {
|
||||||
id: MessageId,
|
id: MessageId,
|
||||||
|
@ -172,7 +172,7 @@ impl<'de> Visitor<'de> for MessageVisitor {
|
||||||
.ok_or_else(|| de::Error::invalid_type(Unexpected::Unit, &self))?;
|
.ok_or_else(|| de::Error::invalid_type(Unexpected::Unit, &self))?;
|
||||||
Response::Error { id, error }
|
Response::Error { id, error }
|
||||||
} else {
|
} else {
|
||||||
let result: Payload = seq
|
let result: MarionetteResult = seq
|
||||||
.next_element()?
|
.next_element()?
|
||||||
.ok_or_else(|| de::Error::invalid_length(3, &self))?;
|
.ok_or_else(|| de::Error::invalid_length(3, &self))?;
|
||||||
Response::Result { id, result }
|
Response::Result { id, result }
|
||||||
|
@ -269,9 +269,7 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_outgoing_result() {
|
fn test_outgoing_result() {
|
||||||
let json = json!([1, 42, null, { "value": null }]);
|
let json = json!([1, 42, null, { "value": null }]);
|
||||||
// TODO: payload is currently untyped
|
let result = MarionetteResult::Null;
|
||||||
let mut result = Map::new();
|
|
||||||
result.insert("value".into(), Value::Null);
|
|
||||||
let msg = Message::Outgoing(Response::Result { id: 42, result });
|
let msg = Message::Outgoing(Response::Result { id: 42, result });
|
||||||
|
|
||||||
assert_ser_de(&msg, json);
|
assert_ser_de(&msg, json);
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct WebElement {
|
||||||
|
#[serde(rename = "element-6066-11e4-a52e-4f735466cecf")]
|
||||||
|
element: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
pub struct Timeouts {
|
||||||
|
implicit: u64,
|
||||||
|
#[serde(rename = "pageLoad", alias = "page load")]
|
||||||
|
page_load: u64,
|
||||||
|
script: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum MarionetteResult {
|
||||||
|
#[serde(deserialize_with = "from_value", serialize_with = "to_value")]
|
||||||
|
String(String),
|
||||||
|
Timeouts(Timeouts),
|
||||||
|
#[serde(deserialize_with = "from_value", serialize_with = "to_value")]
|
||||||
|
WebElement(WebElement),
|
||||||
|
#[serde(deserialize_with = "from_value", serialize_with = "to_empty_value")]
|
||||||
|
Null,
|
||||||
|
}
|
||||||
|
|
||||||
|
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 w = Wrapper::deserialize(deserializer)?;
|
||||||
|
Ok(w.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use crate::test::{assert_de, assert_ser_de, ELEMENT_KEY};
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_web_element() {
|
||||||
|
let data = WebElement {
|
||||||
|
element: "foo".into(),
|
||||||
|
};
|
||||||
|
assert_ser_de(&data, json!({"element-6066-11e4-a52e-4f735466cecf": "foo"}));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_timeouts() {
|
||||||
|
let data = Timeouts {
|
||||||
|
implicit: 1000,
|
||||||
|
page_load: 200000,
|
||||||
|
script: Some(60000),
|
||||||
|
};
|
||||||
|
assert_ser_de(
|
||||||
|
&data,
|
||||||
|
json!({"implicit":1000,"pageLoad":200000,"script":60000}),
|
||||||
|
);
|
||||||
|
assert_de(
|
||||||
|
&data,
|
||||||
|
json!({"implicit":1000,"page load":200000,"script":60000}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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_timeouts_response() {
|
||||||
|
let data = Timeouts {
|
||||||
|
implicit: 1000,
|
||||||
|
page_load: 200000,
|
||||||
|
script: 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_null_response() {
|
||||||
|
assert_ser_de(&MarionetteResult::Null, json!({ "value": null }));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,3 +1,5 @@
|
||||||
|
pub static ELEMENT_KEY: &'static str = "element-6066-11e4-a52e-4f735466cecf";
|
||||||
|
|
||||||
pub fn assert_ser_de<T>(data: &T, json: serde_json::Value)
|
pub fn assert_ser_de<T>(data: &T, json: serde_json::Value)
|
||||||
where
|
where
|
||||||
T: std::fmt::Debug,
|
T: std::fmt::Debug,
|
||||||
|
@ -18,3 +20,12 @@ where
|
||||||
{
|
{
|
||||||
assert_eq!(serde_json::to_value(data).unwrap(), json);
|
assert_eq!(serde_json::to_value(data).unwrap(), json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn assert_de<T>(data: &T, json: serde_json::Value)
|
||||||
|
where
|
||||||
|
T: std::fmt::Debug,
|
||||||
|
T: std::cmp::PartialEq,
|
||||||
|
T: serde::de::DeserializeOwned,
|
||||||
|
{
|
||||||
|
assert_eq!(data, &serde_json::from_value::<T>(json).unwrap());
|
||||||
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче