|
Packit |
f0b94e |
use command::Parameters;
|
|
Packit |
f0b94e |
use common::{Nullable, WebElement};
|
|
Packit |
f0b94e |
use error::{WebDriverResult, WebDriverError, ErrorStatus};
|
|
Packit |
f0b94e |
use rustc_serialize::json::{ToJson, Json};
|
|
Packit |
f0b94e |
use unicode_segmentation::UnicodeSegmentation;
|
|
Packit |
f0b94e |
use std::collections::BTreeMap;
|
|
Packit |
f0b94e |
use std::default::Default;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub struct ActionSequence {
|
|
Packit |
f0b94e |
pub id: Nullable<String>,
|
|
Packit |
f0b94e |
pub actions: ActionsType
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for ActionSequence {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<ActionSequence> {
|
|
Packit |
f0b94e |
let data = try_opt!(body.as_object(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Actions chain was not an object");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let type_name = try_opt!(try_opt!(data.get("type"),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Missing type parameter").as_string(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter ;type' was not a string");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let id = match data.get("id") {
|
|
Packit |
f0b94e |
Some(x) => Some(try_opt!(x.as_string(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'id' was not a string").to_owned()),
|
|
Packit |
f0b94e |
None => None
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// Note that unlike the spec we get the pointer parameters in ActionsType::from_json
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let actions = match type_name {
|
|
Packit |
f0b94e |
"none" | "key" | "pointer" => try!(ActionsType::from_json(&body)),
|
|
Packit |
f0b94e |
_ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Invalid action type"))
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
Ok(ActionSequence {
|
|
Packit |
f0b94e |
id: id.into(),
|
|
Packit |
f0b94e |
actions: actions
|
|
Packit |
f0b94e |
})
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for ActionSequence {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
let mut data: BTreeMap<String, Json> = BTreeMap::new();
|
|
Packit |
f0b94e |
data.insert("id".into(), self.id.to_json());
|
|
Packit |
f0b94e |
let (action_type, actions) = match self.actions {
|
|
Packit |
f0b94e |
ActionsType::Null(ref actions) => {
|
|
Packit |
f0b94e |
("none",
|
|
Packit |
f0b94e |
actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>())
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
ActionsType::Key(ref actions) => {
|
|
Packit |
f0b94e |
("key",
|
|
Packit |
f0b94e |
actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>())
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
ActionsType::Pointer(ref parameters, ref actions) => {
|
|
Packit |
f0b94e |
data.insert("parameters".into(), parameters.to_json());
|
|
Packit |
f0b94e |
("pointer",
|
|
Packit |
f0b94e |
actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>())
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
data.insert("type".into(), action_type.to_json());
|
|
Packit |
f0b94e |
data.insert("actions".into(), actions.to_json());
|
|
Packit |
f0b94e |
Json::Object(data)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum ActionsType {
|
|
Packit |
f0b94e |
Null(Vec<NullActionItem>),
|
|
Packit |
f0b94e |
Key(Vec<KeyActionItem>),
|
|
Packit |
f0b94e |
Pointer(PointerActionParameters, Vec<PointerActionItem>)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for ActionsType {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<ActionsType> {
|
|
Packit |
f0b94e |
// These unwraps are OK as long as this is only called from ActionSequence::from_json
|
|
Packit |
f0b94e |
let data = body.as_object().expect("Body should be a JSON Object");
|
|
Packit |
f0b94e |
let actions_type = body.find("type").and_then(|x| x.as_string()).expect("Type should be a string");
|
|
Packit |
f0b94e |
let actions_chain = try_opt!(try_opt!(data.get("actions"),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Missing actions parameter").as_array(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'actions' was not an array");
|
|
Packit |
f0b94e |
match actions_type {
|
|
Packit |
f0b94e |
"none" => {
|
|
Packit |
f0b94e |
let mut actions = Vec::with_capacity(actions_chain.len());
|
|
Packit |
f0b94e |
for action_body in actions_chain.iter() {
|
|
Packit |
f0b94e |
actions.push(try!(NullActionItem::from_json(action_body)));
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
Ok(ActionsType::Null(actions))
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
"key" => {
|
|
Packit |
f0b94e |
let mut actions = Vec::with_capacity(actions_chain.len());
|
|
Packit |
f0b94e |
for action_body in actions_chain.iter() {
|
|
Packit |
f0b94e |
actions.push(try!(KeyActionItem::from_json(action_body)));
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
Ok(ActionsType::Key(actions))
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
"pointer" => {
|
|
Packit |
f0b94e |
let mut actions = Vec::with_capacity(actions_chain.len());
|
|
Packit |
f0b94e |
let parameters = match data.get("parameters") {
|
|
Packit |
f0b94e |
Some(x) => try!(PointerActionParameters::from_json(x)),
|
|
Packit |
f0b94e |
None => Default::default()
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
for action_body in actions_chain.iter() {
|
|
Packit |
f0b94e |
actions.push(try!(PointerActionItem::from_json(action_body)));
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
Ok(ActionsType::Pointer(parameters, actions))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
_ => panic!("Got unexpected action type after checking type")
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum PointerType {
|
|
Packit |
f0b94e |
Mouse,
|
|
Packit |
f0b94e |
Pen,
|
|
Packit |
f0b94e |
Touch,
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for PointerType {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<PointerType> {
|
|
Packit |
f0b94e |
match body.as_string() {
|
|
Packit |
f0b94e |
Some("mouse") => Ok(PointerType::Mouse),
|
|
Packit |
f0b94e |
Some("pen") => Ok(PointerType::Pen),
|
|
Packit |
f0b94e |
Some("touch") => Ok(PointerType::Touch),
|
|
Packit |
f0b94e |
Some(_) => Err(WebDriverError::new(
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Unsupported pointer type"
|
|
Packit |
f0b94e |
)),
|
|
Packit |
f0b94e |
None => Err(WebDriverError::new(
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Pointer type was not a string"
|
|
Packit |
f0b94e |
))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for PointerType {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
match *self {
|
|
Packit |
f0b94e |
PointerType::Mouse => "mouse".to_json(),
|
|
Packit |
f0b94e |
PointerType::Pen => "pen".to_json(),
|
|
Packit |
f0b94e |
PointerType::Touch => "touch".to_json(),
|
|
Packit |
f0b94e |
}.to_json()
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Default for PointerType {
|
|
Packit |
f0b94e |
fn default() -> PointerType {
|
|
Packit |
f0b94e |
PointerType::Mouse
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, Default, PartialEq)]
|
|
Packit |
f0b94e |
pub struct PointerActionParameters {
|
|
Packit |
f0b94e |
pub pointer_type: PointerType
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for PointerActionParameters {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<PointerActionParameters> {
|
|
Packit |
f0b94e |
let data = try_opt!(body.as_object(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'parameters' was not an object");
|
|
Packit |
f0b94e |
let pointer_type = match data.get("pointerType") {
|
|
Packit |
f0b94e |
Some(x) => try!(PointerType::from_json(x)),
|
|
Packit |
f0b94e |
None => PointerType::default()
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
Ok(PointerActionParameters {
|
|
Packit |
f0b94e |
pointer_type: pointer_type
|
|
Packit |
f0b94e |
})
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for PointerActionParameters {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
let mut data = BTreeMap::new();
|
|
Packit |
f0b94e |
data.insert("pointerType".to_owned(),
|
|
Packit |
f0b94e |
self.pointer_type.to_json());
|
|
Packit |
f0b94e |
Json::Object(data)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum NullActionItem {
|
|
Packit |
f0b94e |
General(GeneralAction)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for NullActionItem {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<NullActionItem> {
|
|
Packit |
f0b94e |
let data = try_opt!(body.as_object(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Actions chain was not an object");
|
|
Packit |
f0b94e |
let type_name = try_opt!(
|
|
Packit |
f0b94e |
try_opt!(data.get("type"),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Missing 'type' parameter").as_string(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'type' was not a string");
|
|
Packit |
f0b94e |
match type_name {
|
|
Packit |
f0b94e |
"pause" => Ok(NullActionItem::General(
|
|
Packit |
f0b94e |
try!(GeneralAction::from_json(body)))),
|
|
Packit |
f0b94e |
_ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Invalid type attribute"))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for NullActionItem {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
match self {
|
|
Packit |
f0b94e |
&NullActionItem::General(ref x) => x.to_json(),
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum KeyActionItem {
|
|
Packit |
f0b94e |
General(GeneralAction),
|
|
Packit |
f0b94e |
Key(KeyAction)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for KeyActionItem {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<KeyActionItem> {
|
|
Packit |
f0b94e |
let data = try_opt!(body.as_object(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Key action item was not an object");
|
|
Packit |
f0b94e |
let type_name = try_opt!(
|
|
Packit |
f0b94e |
try_opt!(data.get("type"),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Missing 'type' parameter").as_string(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'type' was not a string");
|
|
Packit |
f0b94e |
match type_name {
|
|
Packit |
f0b94e |
"pause" => Ok(KeyActionItem::General(
|
|
Packit |
f0b94e |
try!(GeneralAction::from_json(body)))),
|
|
Packit |
f0b94e |
_ => Ok(KeyActionItem::Key(
|
|
Packit |
f0b94e |
try!(KeyAction::from_json(body))))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for KeyActionItem {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
match *self {
|
|
Packit |
f0b94e |
KeyActionItem::General(ref x) => x.to_json(),
|
|
Packit |
f0b94e |
KeyActionItem::Key(ref x) => x.to_json()
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum PointerActionItem {
|
|
Packit |
f0b94e |
General(GeneralAction),
|
|
Packit |
f0b94e |
Pointer(PointerAction)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for PointerActionItem {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<PointerActionItem> {
|
|
Packit |
f0b94e |
let data = try_opt!(body.as_object(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Pointer action item was not an object");
|
|
Packit |
f0b94e |
let type_name = try_opt!(
|
|
Packit |
f0b94e |
try_opt!(data.get("type"),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Missing 'type' parameter").as_string(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'type' was not a string");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
match type_name {
|
|
Packit |
f0b94e |
"pause" => Ok(PointerActionItem::General(try!(GeneralAction::from_json(body)))),
|
|
Packit |
f0b94e |
_ => Ok(PointerActionItem::Pointer(try!(PointerAction::from_json(body))))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for PointerActionItem {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
match self {
|
|
Packit |
f0b94e |
&PointerActionItem::General(ref x) => x.to_json(),
|
|
Packit |
f0b94e |
&PointerActionItem::Pointer(ref x) => x.to_json()
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum GeneralAction {
|
|
Packit |
f0b94e |
Pause(PauseAction)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for GeneralAction {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<GeneralAction> {
|
|
Packit |
f0b94e |
match body.find("type").and_then(|x| x.as_string()) {
|
|
Packit |
f0b94e |
Some("pause") => Ok(GeneralAction::Pause(try!(PauseAction::from_json(body)))),
|
|
Packit |
f0b94e |
_ => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Invalid or missing type attribute"))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for GeneralAction {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
match self {
|
|
Packit |
f0b94e |
&GeneralAction::Pause(ref x) => x.to_json()
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub struct PauseAction {
|
|
Packit |
f0b94e |
pub duration: u64
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for PauseAction {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<PauseAction> {
|
|
Packit |
f0b94e |
let default = Json::U64(0);
|
|
Packit |
f0b94e |
Ok(PauseAction {
|
|
Packit |
f0b94e |
duration: try_opt!(body.find("duration").unwrap_or(&default).as_u64(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'duration' was not a positive integer")
|
|
Packit |
f0b94e |
})
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for PauseAction {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
let mut data = BTreeMap::new();
|
|
Packit |
f0b94e |
data.insert("type".to_owned(),
|
|
Packit |
f0b94e |
"pause".to_json());
|
|
Packit |
f0b94e |
data.insert("duration".to_owned(),
|
|
Packit |
f0b94e |
self.duration.to_json());
|
|
Packit |
f0b94e |
Json::Object(data)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum KeyAction {
|
|
Packit |
f0b94e |
Up(KeyUpAction),
|
|
Packit |
f0b94e |
Down(KeyDownAction)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for KeyAction {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<KeyAction> {
|
|
Packit |
f0b94e |
match body.find("type").and_then(|x| x.as_string()) {
|
|
Packit |
f0b94e |
Some("keyDown") => Ok(KeyAction::Down(try!(KeyDownAction::from_json(body)))),
|
|
Packit |
f0b94e |
Some("keyUp") => Ok(KeyAction::Up(try!(KeyUpAction::from_json(body)))),
|
|
Packit |
f0b94e |
Some(_) | None => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Invalid type attribute value for key action"))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for KeyAction {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
match self {
|
|
Packit |
f0b94e |
&KeyAction::Down(ref x) => x.to_json(),
|
|
Packit |
f0b94e |
&KeyAction::Up(ref x) => x.to_json(),
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
fn validate_key_value(value_str: &str) -> WebDriverResult<String> {
|
|
Packit |
f0b94e |
let mut graphemes = value_str.graphemes(true);
|
|
Packit |
f0b94e |
let value = if let Some(g) = graphemes.next() {
|
|
Packit |
f0b94e |
g
|
|
Packit |
f0b94e |
} else {
|
|
Packit |
f0b94e |
return Err(WebDriverError::new(
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'value' was an empty string"))
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
if graphemes.next().is_some() {
|
|
Packit |
f0b94e |
return Err(WebDriverError::new(
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'value' contained multiple graphemes"))
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
Ok(value.to_string())
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub struct KeyUpAction {
|
|
Packit |
f0b94e |
pub value: String
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for KeyUpAction {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<KeyUpAction> {
|
|
Packit |
f0b94e |
let value_str = try_opt!(
|
|
Packit |
f0b94e |
try_opt!(body.find("value"),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Missing value parameter").as_string(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'value' was not a string");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let value = try!(validate_key_value(value_str));
|
|
Packit |
f0b94e |
Ok(KeyUpAction {
|
|
Packit |
f0b94e |
value: value
|
|
Packit |
f0b94e |
})
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for KeyUpAction {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
let mut data = BTreeMap::new();
|
|
Packit |
f0b94e |
data.insert("type".to_owned(),
|
|
Packit |
f0b94e |
"keyUp".to_json());
|
|
Packit |
f0b94e |
data.insert("value".to_string(),
|
|
Packit |
f0b94e |
self.value.to_string().to_json());
|
|
Packit |
f0b94e |
Json::Object(data)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub struct KeyDownAction {
|
|
Packit |
f0b94e |
pub value: String
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for KeyDownAction {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<KeyDownAction> {
|
|
Packit |
f0b94e |
let value_str = try_opt!(
|
|
Packit |
f0b94e |
try_opt!(body.find("value"),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Missing value parameter").as_string(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'value' was not a string");
|
|
Packit |
f0b94e |
let value = try!(validate_key_value(value_str));
|
|
Packit |
f0b94e |
Ok(KeyDownAction {
|
|
Packit |
f0b94e |
value: value
|
|
Packit |
f0b94e |
})
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for KeyDownAction {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
let mut data = BTreeMap::new();
|
|
Packit |
f0b94e |
data.insert("type".to_owned(),
|
|
Packit |
f0b94e |
"keyDown".to_json());
|
|
Packit |
f0b94e |
data.insert("value".to_owned(),
|
|
Packit |
f0b94e |
self.value.to_string().to_json());
|
|
Packit |
f0b94e |
Json::Object(data)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum PointerOrigin {
|
|
Packit |
f0b94e |
Viewport,
|
|
Packit |
f0b94e |
Pointer,
|
|
Packit |
f0b94e |
Element(WebElement),
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for PointerOrigin {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<PointerOrigin> {
|
|
Packit |
f0b94e |
match *body {
|
|
Packit |
f0b94e |
Json::String(ref x) => {
|
|
Packit |
f0b94e |
match &**x {
|
|
Packit |
f0b94e |
"viewport" => Ok(PointerOrigin::Viewport),
|
|
Packit |
f0b94e |
"pointer" => Ok(PointerOrigin::Pointer),
|
|
Packit |
f0b94e |
_ => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Unknown pointer origin"))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
Json::Object(_) => Ok(PointerOrigin::Element(try!(WebElement::from_json(body)))),
|
|
Packit |
f0b94e |
_ => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Pointer origin was not a string or an object"))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for PointerOrigin {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
match *self {
|
|
Packit |
f0b94e |
PointerOrigin::Viewport => "viewport".to_json(),
|
|
Packit |
f0b94e |
PointerOrigin::Pointer => "pointer".to_json(),
|
|
Packit |
f0b94e |
PointerOrigin::Element(ref x) => x.to_json(),
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Default for PointerOrigin {
|
|
Packit |
f0b94e |
fn default() -> PointerOrigin {
|
|
Packit |
f0b94e |
PointerOrigin::Viewport
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub enum PointerAction {
|
|
Packit |
f0b94e |
Up(PointerUpAction),
|
|
Packit |
f0b94e |
Down(PointerDownAction),
|
|
Packit |
f0b94e |
Move(PointerMoveAction),
|
|
Packit |
f0b94e |
Cancel
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for PointerAction {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<PointerAction> {
|
|
Packit |
f0b94e |
match body.find("type").and_then(|x| x.as_string()) {
|
|
Packit |
f0b94e |
Some("pointerUp") => Ok(PointerAction::Up(try!(PointerUpAction::from_json(body)))),
|
|
Packit |
f0b94e |
Some("pointerDown") => Ok(PointerAction::Down(try!(PointerDownAction::from_json(body)))),
|
|
Packit |
f0b94e |
Some("pointerMove") => Ok(PointerAction::Move(try!(PointerMoveAction::from_json(body)))),
|
|
Packit |
f0b94e |
Some("pointerCancel") => Ok(PointerAction::Cancel),
|
|
Packit |
f0b94e |
Some(_) | None => Err(WebDriverError::new(
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Missing or invalid type argument for pointer action"))
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for PointerAction {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
match self {
|
|
Packit |
f0b94e |
&PointerAction::Down(ref x) => x.to_json(),
|
|
Packit |
f0b94e |
&PointerAction::Up(ref x) => x.to_json(),
|
|
Packit |
f0b94e |
&PointerAction::Move(ref x) => x.to_json(),
|
|
Packit |
f0b94e |
&PointerAction::Cancel => {
|
|
Packit |
f0b94e |
let mut data = BTreeMap::new();
|
|
Packit |
f0b94e |
data.insert("type".to_owned(),
|
|
Packit |
f0b94e |
"pointerCancel".to_json());
|
|
Packit |
f0b94e |
Json::Object(data)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub struct PointerUpAction {
|
|
Packit |
f0b94e |
pub button: u64,
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for PointerUpAction {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<PointerUpAction> {
|
|
Packit |
f0b94e |
let button = try_opt!(
|
|
Packit |
f0b94e |
try_opt!(body.find("button"),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Missing button parameter").as_u64(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'button' was not a positive integer");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
Ok(PointerUpAction {
|
|
Packit |
f0b94e |
button: button
|
|
Packit |
f0b94e |
})
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for PointerUpAction {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
let mut data = BTreeMap::new();
|
|
Packit |
f0b94e |
data.insert("type".to_owned(),
|
|
Packit |
f0b94e |
"pointerUp".to_json());
|
|
Packit |
f0b94e |
data.insert("button".to_owned(), self.button.to_json());
|
|
Packit |
f0b94e |
Json::Object(data)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub struct PointerDownAction {
|
|
Packit |
f0b94e |
pub button: u64,
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for PointerDownAction {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<PointerDownAction> {
|
|
Packit |
f0b94e |
let button = try_opt!(
|
|
Packit |
f0b94e |
try_opt!(body.find("button"),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Missing button parameter").as_u64(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'button' was not a positive integer");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
Ok(PointerDownAction {
|
|
Packit |
f0b94e |
button: button
|
|
Packit |
f0b94e |
})
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for PointerDownAction {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
let mut data = BTreeMap::new();
|
|
Packit |
f0b94e |
data.insert("type".to_owned(),
|
|
Packit |
f0b94e |
"pointerDown".to_json());
|
|
Packit |
f0b94e |
data.insert("button".to_owned(), self.button.to_json());
|
|
Packit |
f0b94e |
Json::Object(data)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#[derive(Debug, PartialEq)]
|
|
Packit |
f0b94e |
pub struct PointerMoveAction {
|
|
Packit |
f0b94e |
pub duration: Nullable<u64>,
|
|
Packit |
f0b94e |
pub origin: PointerOrigin,
|
|
Packit |
f0b94e |
pub x: Nullable<i64>,
|
|
Packit |
f0b94e |
pub y: Nullable<i64>
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl Parameters for PointerMoveAction {
|
|
Packit |
f0b94e |
fn from_json(body: &Json) -> WebDriverResult<PointerMoveAction> {
|
|
Packit |
f0b94e |
let duration = match body.find("duration") {
|
|
Packit |
f0b94e |
Some(duration) => Some(try_opt!(duration.as_u64(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'duration' was not a positive integer")),
|
|
Packit |
f0b94e |
None => None
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let origin = match body.find("origin") {
|
|
Packit |
f0b94e |
Some(o) => try!(PointerOrigin::from_json(o)),
|
|
Packit |
f0b94e |
None => PointerOrigin::default()
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let x = match body.find("x") {
|
|
Packit |
f0b94e |
Some(x) => {
|
|
Packit |
f0b94e |
Some(try_opt!(x.as_i64(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'x' was not an integer"))
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
None => None
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
let y = match body.find("y") {
|
|
Packit |
f0b94e |
Some(y) => {
|
|
Packit |
f0b94e |
Some(try_opt!(y.as_i64(),
|
|
Packit |
f0b94e |
ErrorStatus::InvalidArgument,
|
|
Packit |
f0b94e |
"Parameter 'y' was not an integer"))
|
|
Packit |
f0b94e |
},
|
|
Packit |
f0b94e |
None => None
|
|
Packit |
f0b94e |
};
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
Ok(PointerMoveAction {
|
|
Packit |
f0b94e |
duration: duration.into(),
|
|
Packit |
f0b94e |
origin: origin.into(),
|
|
Packit |
f0b94e |
x: x.into(),
|
|
Packit |
f0b94e |
y: y.into(),
|
|
Packit |
f0b94e |
})
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
impl ToJson for PointerMoveAction {
|
|
Packit |
f0b94e |
fn to_json(&self) -> Json {
|
|
Packit |
f0b94e |
let mut data = BTreeMap::new();
|
|
Packit |
f0b94e |
data.insert("type".to_owned(), "pointerMove".to_json());
|
|
Packit |
f0b94e |
if self.duration.is_value() {
|
|
Packit |
f0b94e |
data.insert("duration".to_owned(),
|
|
Packit |
f0b94e |
self.duration.to_json());
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
data.insert("origin".to_owned(), self.origin.to_json());
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if self.x.is_value() {
|
|
Packit |
f0b94e |
data.insert("x".to_owned(), self.x.to_json());
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
if self.y.is_value() {
|
|
Packit |
f0b94e |
data.insert("y".to_owned(), self.y.to_json());
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
Json::Object(data)
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|