зеркало из https://github.com/mozilla/gecko-dev.git
geckodriver: Broken implementation of most of what's in the spec (and some things that aren't) except Actions
Source-Repo: https://github.com/mozilla/geckodriver Source-Revision: 14215bccc7dce187ee96ab111bc545deda2c7e8b --HG-- extra : rebase_source : 452b949d8be2903c6d5522b9cf91230c0a4b8e82
This commit is contained in:
Родитель
97d7fef217
Коммит
ba54211b54
|
@ -1,16 +1,15 @@
|
|||
use core::u16;
|
||||
use std::collections::TreeMap;
|
||||
use serialize::json;
|
||||
use serialize::json::{ToJson, Json};
|
||||
use regex::Captures;
|
||||
|
||||
use common::{WebDriverResult, WebDriverError, ErrorStatus};
|
||||
use common::{WebDriverResult, WebDriverError, ErrorStatus, Nullable, WebElement, FrameId, LocatorStrategy};
|
||||
use response::Date; //TODO: Put all these types in a specific file
|
||||
use messagebuilder::MatchType;
|
||||
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
pub enum WebDriverCommand {
|
||||
GetMarionetteId, //TODO: move this
|
||||
NewSession,
|
||||
DeleteSession,
|
||||
Get(GetParameters),
|
||||
|
@ -22,7 +21,6 @@ pub enum WebDriverCommand {
|
|||
GetWindowHandle,
|
||||
GetWindowHandles,
|
||||
Close,
|
||||
Timeouts(TimeoutsParameters),
|
||||
SetWindowSize(WindowSizeParameters),
|
||||
GetWindowSize,
|
||||
MaximizeWindow,
|
||||
|
@ -30,6 +28,8 @@ pub enum WebDriverCommand {
|
|||
SwitchToWindow(SwitchToWindowParameters),
|
||||
SwitchToFrame(SwitchToFrameParameters),
|
||||
SwitchToParentFrame,
|
||||
FindElement(LocatorParameters),
|
||||
FindElements(LocatorParameters),
|
||||
IsDisplayed(WebElement),
|
||||
IsSelected(WebElement),
|
||||
GetElementAttribute(WebElement, String),
|
||||
|
@ -39,7 +39,16 @@ pub enum WebDriverCommand {
|
|||
GetElementRect(WebElement),
|
||||
IsEnabled(WebElement),
|
||||
ExecuteScript(JavascriptCommandParameters),
|
||||
ExecuteAsyncScript(JavascriptCommandParameters)
|
||||
ExecuteAsyncScript(JavascriptCommandParameters),
|
||||
GetCookie(GetCookieParameters),
|
||||
AddCookie(AddCookieParameters),
|
||||
SetTimeouts(TimeoutsParameters),
|
||||
//Actions(ActionsParameters)
|
||||
DismissAlert,
|
||||
AcceptAlert,
|
||||
GetAlertText,
|
||||
SendAlertText(SendAlertTextParameters),
|
||||
TakeScreenshot(TakeScreenshotParameters)
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
|
@ -83,9 +92,9 @@ impl WebDriverMessage {
|
|||
MatchType::GetWindowHandle => WebDriverCommand::GetWindowHandle,
|
||||
MatchType::GetWindowHandles => WebDriverCommand::GetWindowHandles,
|
||||
MatchType::Close => WebDriverCommand::Close,
|
||||
MatchType::Timeouts => {
|
||||
MatchType::SetTimeouts => {
|
||||
let parameters: TimeoutsParameters = try!(Parameters::from_json(&body_data));
|
||||
WebDriverCommand::Timeouts(parameters)
|
||||
WebDriverCommand::SetTimeouts(parameters)
|
||||
},
|
||||
MatchType::SetWindowSize => {
|
||||
let parameters: WindowSizeParameters = try!(Parameters::from_json(&body_data));
|
||||
|
@ -102,6 +111,14 @@ impl WebDriverMessage {
|
|||
WebDriverCommand::SwitchToFrame(parameters)
|
||||
},
|
||||
MatchType::SwitchToParentFrame => WebDriverCommand::SwitchToParentFrame,
|
||||
MatchType::FindElement => {
|
||||
let parameters: LocatorParameters = try!(Parameters::from_json(&body_data));
|
||||
WebDriverCommand::FindElement(parameters)
|
||||
},
|
||||
MatchType::FindElements => {
|
||||
let parameters: LocatorParameters = try!(Parameters::from_json(&body_data));
|
||||
WebDriverCommand::FindElements(parameters)
|
||||
},
|
||||
MatchType::IsDisplayed => {
|
||||
let element = WebElement::new(params.name("elementId").to_string());
|
||||
WebDriverCommand::IsDisplayed(element)
|
||||
|
@ -130,7 +147,7 @@ impl WebDriverMessage {
|
|||
},
|
||||
MatchType::GetElementRect => {
|
||||
let element = WebElement::new(params.name("elementId").to_string());
|
||||
WebDriverCommand::GetElementText(element)
|
||||
WebDriverCommand::GetElementRect(element)
|
||||
},
|
||||
MatchType::IsEnabled => {
|
||||
let element = WebElement::new(params.name("elementId").to_string());
|
||||
|
@ -139,10 +156,35 @@ impl WebDriverMessage {
|
|||
MatchType::ExecuteScript => {
|
||||
let parameters: JavascriptCommandParameters = try!(Parameters::from_json(&body_data));
|
||||
WebDriverCommand::ExecuteScript(parameters)
|
||||
}
|
||||
},
|
||||
MatchType::ExecuteAsyncScript => {
|
||||
let parameters: JavascriptCommandParameters = try!(Parameters::from_json(&body_data));
|
||||
WebDriverCommand::ExecuteAsyncScript(parameters)
|
||||
},
|
||||
MatchType::GetCookie => {
|
||||
let parameters: GetCookieParameters = try!(Parameters::from_json(&body_data));
|
||||
WebDriverCommand::GetCookie(parameters)
|
||||
},
|
||||
MatchType::AddCookie => {
|
||||
let parameters: AddCookieParameters = try!(Parameters::from_json(&body_data));
|
||||
WebDriverCommand::AddCookie(parameters)
|
||||
},
|
||||
MatchType::DismissAlert => {
|
||||
WebDriverCommand::DismissAlert
|
||||
},
|
||||
MatchType::AcceptAlert => {
|
||||
WebDriverCommand::AcceptAlert
|
||||
},
|
||||
MatchType::GetAlertText => {
|
||||
WebDriverCommand::GetAlertText
|
||||
},
|
||||
MatchType::SendAlertText => {
|
||||
let parameters: SendAlertTextParameters = try!(Parameters::from_json(&body_data));
|
||||
WebDriverCommand::SendAlertText(parameters)
|
||||
}
|
||||
MatchType::TakeScreenshot => {
|
||||
let parameters: TakeScreenshotParameters = try!(Parameters::from_json(&body_data));
|
||||
WebDriverCommand::TakeScreenshot(parameters)
|
||||
}
|
||||
};
|
||||
Ok(WebDriverMessage::new(session_id, command))
|
||||
|
@ -160,7 +202,7 @@ impl ToJson for WebDriverMessage {
|
|||
fn to_json(&self) -> json::Json {
|
||||
let mut data = TreeMap::new();
|
||||
let parameters = match self.command {
|
||||
WebDriverCommand::GetMarionetteId | WebDriverCommand::NewSession |
|
||||
WebDriverCommand::NewSession |
|
||||
WebDriverCommand::DeleteSession | WebDriverCommand::GetCurrentUrl |
|
||||
WebDriverCommand::GoBack | WebDriverCommand::GoForward | WebDriverCommand::Refresh |
|
||||
WebDriverCommand::GetTitle | WebDriverCommand::GetWindowHandle |
|
||||
|
@ -170,16 +212,23 @@ impl ToJson for WebDriverMessage {
|
|||
WebDriverCommand::IsSelected(_) | WebDriverCommand::GetElementAttribute(_, _) |
|
||||
WebDriverCommand::GetCSSValue(_, _) | WebDriverCommand::GetElementText(_) |
|
||||
WebDriverCommand::GetElementTagName(_) | WebDriverCommand::GetElementRect(_) |
|
||||
WebDriverCommand::IsEnabled(_) => {
|
||||
WebDriverCommand::IsEnabled(_) | WebDriverCommand::AddCookie(_) |
|
||||
WebDriverCommand::DismissAlert | WebDriverCommand::AcceptAlert |
|
||||
WebDriverCommand::GetAlertText => {
|
||||
None
|
||||
},
|
||||
WebDriverCommand::Get(ref x) => Some(x.to_json()),
|
||||
WebDriverCommand::Timeouts(ref x) => Some(x.to_json()),
|
||||
WebDriverCommand::SetTimeouts(ref x) => Some(x.to_json()),
|
||||
WebDriverCommand::SetWindowSize(ref x) => Some(x.to_json()),
|
||||
WebDriverCommand::SwitchToWindow(ref x) => Some(x.to_json()),
|
||||
WebDriverCommand::SwitchToFrame(ref x) => Some(x.to_json()),
|
||||
WebDriverCommand::FindElement(ref x) => Some(x.to_json()),
|
||||
WebDriverCommand::FindElements(ref x) => Some(x.to_json()),
|
||||
WebDriverCommand::ExecuteScript(ref x) |
|
||||
WebDriverCommand::ExecuteAsyncScript(ref x) => Some(x.to_json())
|
||||
WebDriverCommand::ExecuteAsyncScript(ref x) => Some(x.to_json()),
|
||||
WebDriverCommand::GetCookie(ref x) => Some(x.to_json()),
|
||||
WebDriverCommand::SendAlertText(ref x) => Some(x.to_json()),
|
||||
WebDriverCommand::TakeScreenshot(ref x) => Some(x.to_json())
|
||||
};
|
||||
if parameters.is_some() {
|
||||
data.insert("parameters".to_string(), parameters.unwrap());
|
||||
|
@ -188,76 +237,6 @@ impl ToJson for WebDriverMessage {
|
|||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
struct WebElement {
|
||||
id: String
|
||||
}
|
||||
|
||||
impl WebElement {
|
||||
fn new(id: String) -> WebElement {
|
||||
WebElement {
|
||||
id: id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for WebElement {
|
||||
fn to_json(&self) -> json::Json {
|
||||
let mut data = TreeMap::new();
|
||||
data.insert("element-6066-11e4-a52e-4f735466cecf".to_string(), self.id.to_json());
|
||||
json::Object(data)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
enum FrameId {
|
||||
Short(u16),
|
||||
Element(WebElement),
|
||||
Null
|
||||
}
|
||||
|
||||
impl ToJson for FrameId {
|
||||
fn to_json(&self) -> json::Json {
|
||||
match *self {
|
||||
FrameId::Short(x) => {
|
||||
json::Json::U64(x as u64)
|
||||
},
|
||||
FrameId::Element(ref x) => {
|
||||
json::Json::String(x.id.clone())
|
||||
},
|
||||
FrameId::Null => {
|
||||
json::Json::Null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Clone)]
|
||||
enum Nullable<T: ToJson> {
|
||||
Value(T),
|
||||
Null
|
||||
}
|
||||
|
||||
impl<T: ToJson> Nullable<T> {
|
||||
//This is not very pretty
|
||||
fn from_json<F: FnOnce(&json::Json) -> WebDriverResult<T>>(value: &json::Json, f: F) -> WebDriverResult<Nullable<T>> {
|
||||
if value.is_null() {
|
||||
Ok(Nullable::Null)
|
||||
} else {
|
||||
Ok(Nullable::Value(try!(f(value))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:ToJson> ToJson for Nullable<T> {
|
||||
fn to_json(&self) -> json::Json {
|
||||
match *self {
|
||||
Nullable::Value(ref x) => x.to_json(),
|
||||
Nullable::Null => json::Json::Null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait Parameters {
|
||||
fn from_json(body: &json::Json) -> WebDriverResult<Self>;
|
||||
}
|
||||
|
@ -397,6 +376,45 @@ impl ToJson for SwitchToWindowParameters {
|
|||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
struct LocatorParameters {
|
||||
using: LocatorStrategy,
|
||||
value: String
|
||||
}
|
||||
|
||||
impl Parameters for LocatorParameters {
|
||||
fn from_json(body: &json::Json) -> WebDriverResult<LocatorParameters> {
|
||||
let data = try_opt!(body.as_object(), ErrorStatus::UnknownError,
|
||||
"Message body was not an object");
|
||||
|
||||
let using = try!(LocatorStrategy::from_json(
|
||||
try_opt!(data.get("using"),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Missing 'using' parameter")));
|
||||
|
||||
let value = try_opt!(
|
||||
try_opt!(data.get("value"),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Missing 'using' parameter").as_string(),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Could not convert using to string").into_string();
|
||||
|
||||
return Ok(LocatorParameters {
|
||||
using: using,
|
||||
value: value
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for LocatorParameters {
|
||||
fn to_json(&self) -> json::Json {
|
||||
let mut data = TreeMap::new();
|
||||
data.insert("using".to_string(), self.using.to_json());
|
||||
data.insert("value".to_string(), self.value.to_json());
|
||||
json::Object(data)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
struct SwitchToFrameParameters {
|
||||
id: FrameId
|
||||
|
@ -404,28 +422,13 @@ struct SwitchToFrameParameters {
|
|||
|
||||
impl Parameters for SwitchToFrameParameters {
|
||||
fn from_json(body: &json::Json) -> WebDriverResult<SwitchToFrameParameters> {
|
||||
let data = try_opt!(body.as_object(), ErrorStatus::UnknownError,
|
||||
let data = try_opt!(body.as_object(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Message body was not an object");
|
||||
let id_json = try_opt!(data.get("id"),
|
||||
ErrorStatus::UnknownError,
|
||||
"Missing 'id' parameter");
|
||||
let id = if id_json.is_u64() {
|
||||
let value = id_json.as_u64().unwrap();
|
||||
if value <= u16::MAX as u64 {
|
||||
FrameId::Short(value as u16)
|
||||
} else {
|
||||
return Err(WebDriverError::new(ErrorStatus::NoSuchFrame,
|
||||
"frame id out of range"))
|
||||
}
|
||||
} else if id_json.is_null() {
|
||||
FrameId::Null
|
||||
} else if id_json.is_string() {
|
||||
let value = id_json.as_string().unwrap();
|
||||
FrameId::Element(WebElement::new(value.to_string()))
|
||||
} else {
|
||||
return Err(WebDriverError::new(ErrorStatus::NoSuchFrame,
|
||||
"frame id has unexpected type"))
|
||||
};
|
||||
let id = try!(FrameId::from_json(try_opt!(data.get("id"),
|
||||
ErrorStatus::UnknownError,
|
||||
"Missing 'id' parameter")));
|
||||
|
||||
Ok(SwitchToFrameParameters {
|
||||
id: id
|
||||
})
|
||||
|
@ -490,3 +493,217 @@ impl ToJson for JavascriptCommandParameters {
|
|||
json::Object(data)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
struct GetCookieParameters {
|
||||
name: Nullable<String>
|
||||
}
|
||||
|
||||
impl Parameters for GetCookieParameters {
|
||||
fn from_json(body: &json::Json) -> WebDriverResult<GetCookieParameters> {
|
||||
let data = try_opt!(body.as_object(), ErrorStatus::UnknownError,
|
||||
"Message body was not an object");
|
||||
let name_json = try_opt!(data.get("name"),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Missing 'name' parameter");
|
||||
let name = try!(Nullable::from_json(
|
||||
name_json,
|
||||
|x| {
|
||||
Ok(try_opt!(x.as_string(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to convert name to String").into_string())
|
||||
}));
|
||||
return Ok(GetCookieParameters {
|
||||
name: name
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for GetCookieParameters {
|
||||
fn to_json(&self) -> json::Json {
|
||||
let mut data = TreeMap::new();
|
||||
data.insert("name".to_string(), self.name.to_json());
|
||||
json::Object(data)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
struct AddCookieParameters {
|
||||
name: String,
|
||||
value: String,
|
||||
path: Nullable<String>,
|
||||
domain: Nullable<String>,
|
||||
expiry: Nullable<Date>,
|
||||
maxAge: Date,
|
||||
secure: bool,
|
||||
httpOnly: bool
|
||||
}
|
||||
|
||||
impl Parameters for AddCookieParameters {
|
||||
fn from_json(body: &json::Json) -> WebDriverResult<AddCookieParameters> {
|
||||
let data = try_opt!(body.as_object(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Message body was not an object");
|
||||
let name = try_opt!(
|
||||
try_opt!(data.get("name"),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Missing 'name' parameter").as_string(),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"'name' is not a string").into_string();
|
||||
|
||||
let value = try_opt!(
|
||||
try_opt!(data.get("value"),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Missing 'value' parameter").as_string(),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"'value' is not a string").into_string();
|
||||
|
||||
let path = match data.get("path") {
|
||||
Some(path_json) => {
|
||||
try!(Nullable::from_json(
|
||||
path_json,
|
||||
|x| {
|
||||
Ok(try_opt!(x.as_string(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to convert path to String").into_string())
|
||||
}))
|
||||
},
|
||||
None => Nullable::Null
|
||||
};
|
||||
|
||||
let domain = match data.get("domain") {
|
||||
Some(domain_json) => {
|
||||
try!(Nullable::from_json(
|
||||
domain_json,
|
||||
|x| {
|
||||
Ok(try_opt!(x.as_string(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to convert domain to String").into_string())
|
||||
}))
|
||||
},
|
||||
None => Nullable::Null
|
||||
};
|
||||
|
||||
//TODO: This is supposed to support some text format
|
||||
let expiry = match data.get("expiry") {
|
||||
Some(expiry_json) => {
|
||||
try!(Nullable::from_json(
|
||||
expiry_json,
|
||||
|x| {
|
||||
Ok(Date::new(try_opt!(x.as_u64(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to convert expiry to Date")))
|
||||
}))
|
||||
},
|
||||
None => Nullable::Null
|
||||
};
|
||||
|
||||
let max_age = Date::new(try_opt!(
|
||||
try_opt!(data.get("maxAge"),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Missing 'maxAge' parameter").as_u64(),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"'value' is not a string"));
|
||||
|
||||
let secure = match data.get("secure") {
|
||||
Some(x) => try_opt!(x.as_boolean(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to convert secure to boolean"),
|
||||
None => false
|
||||
};
|
||||
|
||||
let http_only = match data.get("httpOnly") {
|
||||
Some(x) => try_opt!(x.as_boolean(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to convert httpOnly to boolean"),
|
||||
None => false
|
||||
};
|
||||
|
||||
return Ok(AddCookieParameters {
|
||||
name: name,
|
||||
value: value,
|
||||
path: path,
|
||||
domain: domain,
|
||||
expiry: expiry,
|
||||
maxAge: max_age,
|
||||
secure: secure,
|
||||
httpOnly: http_only
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for AddCookieParameters {
|
||||
fn to_json(&self) -> json::Json {
|
||||
let mut data = TreeMap::new();
|
||||
data.insert("name".to_string(), self.name.to_json());
|
||||
data.insert("value".to_string(), self.value.to_json());
|
||||
data.insert("path".to_string(), self.path.to_json());
|
||||
data.insert("domain".to_string(), self.domain.to_json());
|
||||
data.insert("expiry".to_string(), self.expiry.to_json());
|
||||
data.insert("maxAge".to_string(), self.maxAge.to_json());
|
||||
data.insert("secure".to_string(), self.secure.to_json());
|
||||
data.insert("httpOnly".to_string(), self.httpOnly.to_json());
|
||||
json::Object(data)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
struct SendAlertTextParameters {
|
||||
keysToSend: String
|
||||
}
|
||||
|
||||
impl Parameters for SendAlertTextParameters {
|
||||
fn from_json(body: &json::Json) -> WebDriverResult<SendAlertTextParameters> {
|
||||
let data = try_opt!(body.as_object(), ErrorStatus::UnknownError,
|
||||
"Message body was not an object");
|
||||
let keys = try_opt!(
|
||||
try_opt!(data.get("keysToSend"),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Missing 'handle' parameter").as_string(),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"'keysToSend' not a string").into_string();
|
||||
return Ok(SendAlertTextParameters {
|
||||
keysToSend: keys
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for SendAlertTextParameters {
|
||||
fn to_json(&self) -> json::Json {
|
||||
let mut data = TreeMap::new();
|
||||
data.insert("keysToSend".to_string(), self.keysToSend.to_json());
|
||||
json::Object(data)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
struct TakeScreenshotParameters {
|
||||
element: Nullable<WebElement>
|
||||
}
|
||||
|
||||
impl Parameters for TakeScreenshotParameters {
|
||||
fn from_json(body: &json::Json) -> WebDriverResult<TakeScreenshotParameters> {
|
||||
let data = try_opt!(body.as_object(), ErrorStatus::UnknownError,
|
||||
"Message body was not an object");
|
||||
let element = match data.get("element") {
|
||||
Some(element_json) => try!(Nullable::from_json(
|
||||
element_json,
|
||||
|x| {
|
||||
Ok(try!(WebElement::from_json(x)))
|
||||
})),
|
||||
None => Nullable::Null
|
||||
};
|
||||
|
||||
return Ok(TakeScreenshotParameters {
|
||||
element: element
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for TakeScreenshotParameters {
|
||||
fn to_json(&self) -> json::Json {
|
||||
let mut data = TreeMap::new();
|
||||
data.insert("element".to_string(), self.element.to_json());
|
||||
json::Object(data)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use serialize::json;
|
||||
use core::u16;
|
||||
use serialize::{json, Encodable, Encoder};
|
||||
use serialize::json::{ToJson, ParserError};
|
||||
use std::collections::TreeMap;
|
||||
use std::error::{Error, FromError};
|
||||
|
@ -118,3 +119,149 @@ impl FromError<ParserError> for WebDriverError {
|
|||
WebDriverError::new(ErrorStatus::UnknownError, msg.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq, Clone, Show)]
|
||||
pub enum Nullable<T: ToJson> {
|
||||
Value(T),
|
||||
Null
|
||||
}
|
||||
|
||||
impl<T: ToJson> Nullable<T> {
|
||||
//This is not very pretty
|
||||
pub fn from_json<F: FnOnce(&json::Json) -> WebDriverResult<T>>(value: &json::Json, f: F) -> WebDriverResult<Nullable<T>> {
|
||||
if value.is_null() {
|
||||
Ok(Nullable::Null)
|
||||
} else {
|
||||
Ok(Nullable::Value(try!(f(value))))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ToJson> ToJson for Nullable<T> {
|
||||
fn to_json(&self) -> json::Json {
|
||||
match *self {
|
||||
Nullable::Value(ref x) => x.to_json(),
|
||||
Nullable::Null => json::Json::Null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<S: Encoder<E>, E, T: ToJson> Encodable<S, E> for Nullable<T> {
|
||||
fn encode(&self, s: &mut S) -> Result<(), E> {
|
||||
match *self {
|
||||
Nullable::Value(ref x) => x.to_json().encode(s),
|
||||
Nullable::Null => s.emit_nil()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
pub struct WebElement {
|
||||
id: String
|
||||
}
|
||||
|
||||
impl WebElement {
|
||||
pub fn new(id: String) -> WebElement {
|
||||
WebElement {
|
||||
id: id
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_json(data: &json::Json) -> WebDriverResult<WebElement> {
|
||||
Ok(WebElement::new(
|
||||
try_opt!(
|
||||
try_opt!(
|
||||
try_opt!(data.as_object(),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Could not convert webelement to object").get(
|
||||
"element-6066-11e4-a52e-4f735466cecf"),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Could not find webelement key").as_string(),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Could not convert web element to string").into_string()))
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for WebElement {
|
||||
fn to_json(&self) -> json::Json {
|
||||
let mut data = TreeMap::new();
|
||||
data.insert("element-6066-11e4-a52e-4f735466cecf".to_string(), self.id.to_json());
|
||||
json::Object(data)
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
pub enum FrameId {
|
||||
Short(u16),
|
||||
Element(WebElement),
|
||||
Null
|
||||
}
|
||||
|
||||
impl FrameId {
|
||||
pub fn from_json(data: &json::Json) -> WebDriverResult<FrameId> {
|
||||
match data {
|
||||
&json::Json::U64(x) => {
|
||||
if x <= u16::MAX as u64 {
|
||||
Ok(FrameId::Short(x as u16))
|
||||
} else {
|
||||
Err(WebDriverError::new(ErrorStatus::NoSuchFrame,
|
||||
"frame id out of range"))
|
||||
}
|
||||
},
|
||||
&json::Json::Null => Ok(FrameId::Null),
|
||||
&json::Json::String(ref x) => Ok(FrameId::Element(WebElement::new(x.clone()))),
|
||||
_ => Err(WebDriverError::new(ErrorStatus::NoSuchFrame,
|
||||
"frame id has unexpected type"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for FrameId {
|
||||
fn to_json(&self) -> json::Json {
|
||||
match *self {
|
||||
FrameId::Short(x) => {
|
||||
json::Json::U64(x as u64)
|
||||
},
|
||||
FrameId::Element(ref x) => {
|
||||
json::Json::String(x.id.clone())
|
||||
},
|
||||
FrameId::Null => {
|
||||
json::Json::Null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(PartialEq)]
|
||||
pub enum LocatorStrategy {
|
||||
CSSSelector,
|
||||
LinkText,
|
||||
PartialLinkText,
|
||||
XPath
|
||||
}
|
||||
|
||||
impl LocatorStrategy {
|
||||
pub fn from_json(body: &json::Json) -> WebDriverResult<LocatorStrategy> {
|
||||
match try_opt!(body.as_string(),
|
||||
ErrorStatus::InvalidArgument,
|
||||
"Cound not convert strategy to string") {
|
||||
"css selector" => Ok(LocatorStrategy::CSSSelector),
|
||||
"link text" => Ok(LocatorStrategy::LinkText),
|
||||
"partial link text" => Ok(LocatorStrategy::PartialLinkText),
|
||||
"xpath" => Ok(LocatorStrategy::XPath),
|
||||
_ => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
|
||||
"Unknown locator strategy"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for LocatorStrategy {
|
||||
fn to_json(&self) -> json::Json {
|
||||
json::Json::String(match *self {
|
||||
LocatorStrategy::CSSSelector => "css selector",
|
||||
LocatorStrategy::LinkText => "link text",
|
||||
LocatorStrategy::PartialLinkText => "partial link text",
|
||||
LocatorStrategy::XPath => "xpath"
|
||||
}.into_string())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,16 +4,19 @@ use std::collections::TreeMap;
|
|||
use std::io::{IoResult, TcpStream, IoError};
|
||||
|
||||
use command::{WebDriverMessage};
|
||||
use command::WebDriverCommand::{GetMarionetteId, NewSession, DeleteSession, Get, GetCurrentUrl,
|
||||
use command::WebDriverCommand::{NewSession, DeleteSession, Get, GetCurrentUrl,
|
||||
GoBack, GoForward, Refresh, GetTitle, GetWindowHandle,
|
||||
GetWindowHandles, Close, Timeouts, SetWindowSize,
|
||||
GetWindowHandles, Close, SetWindowSize,
|
||||
GetWindowSize, MaximizeWindow, SwitchToWindow, SwitchToFrame,
|
||||
SwitchToParentFrame, IsDisplayed, IsSelected,
|
||||
GetElementAttribute, GetCSSValue, GetElementText,
|
||||
SwitchToParentFrame, FindElement, FindElements, IsDisplayed,
|
||||
IsSelected, GetElementAttribute, GetCSSValue, GetElementText,
|
||||
GetElementTagName, GetElementRect, IsEnabled, ExecuteScript,
|
||||
ExecuteAsyncScript};
|
||||
use response::{WebDriverResponse, NewSessionResponse, ValueResponse, WindowSizeResponse, ElementRectResponse};
|
||||
use common::{WebDriverResult, WebDriverError, ErrorStatus};
|
||||
ExecuteAsyncScript, GetCookie, AddCookie, SetTimeouts,
|
||||
DismissAlert, AcceptAlert, GetAlertText, SendAlertText,
|
||||
TakeScreenshot};
|
||||
use response::{WebDriverResponse, NewSessionResponse, ValueResponse, WindowSizeResponse,
|
||||
ElementRectResponse, CookieResponse, Date, Cookie};
|
||||
use common::{WebDriverResult, WebDriverError, ErrorStatus, Nullable};
|
||||
|
||||
pub struct MarionetteSession {
|
||||
pub session_id: String,
|
||||
|
@ -37,16 +40,6 @@ impl MarionetteSession {
|
|||
|
||||
pub fn update(&mut self, msg: &WebDriverMessage, resp: &TreeMap<String, json::Json>) -> WebDriverResult<()> {
|
||||
match msg.command {
|
||||
GetMarionetteId => {
|
||||
let to = try_opt!(
|
||||
try_opt!(resp.get("to"),
|
||||
ErrorStatus::UnknownError,
|
||||
"Unable to get to value").as_string(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Unable to convert 'to' to a string");
|
||||
|
||||
self.to = to.to_string();
|
||||
},
|
||||
NewSession => {
|
||||
let session_id = try_opt!(
|
||||
try_opt!(resp.get("sessionId"),
|
||||
|
@ -61,49 +54,63 @@ impl MarionetteSession {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn command_name(msg:&WebDriverMessage) -> String {
|
||||
fn command_name(msg:&WebDriverMessage) -> Option<String> {
|
||||
match msg.command {
|
||||
GetMarionetteId => "getMarionetteID",
|
||||
NewSession => "newSession",
|
||||
DeleteSession => "deleteSession",
|
||||
Get(_) => "get",
|
||||
GetCurrentUrl => "getCurrentUrl",
|
||||
GoBack => "goBack",
|
||||
GoForward => "goForward",
|
||||
Refresh => "refresh",
|
||||
GetTitle => "getTitle",
|
||||
GetWindowHandle => "getWindowHandle",
|
||||
GetWindowHandles => "getWindowHandles",
|
||||
Close => "close",
|
||||
Timeouts(_) => "timeouts",
|
||||
SetWindowSize(_) => "setWindowSize",
|
||||
GetWindowSize => "getWindowSize",
|
||||
MaximizeWindow => "maximizeWindow",
|
||||
SwitchToWindow(_) => "switchToWindow",
|
||||
SwitchToFrame(_) => "switchToFrame",
|
||||
SwitchToParentFrame => "switchToParentFrame",
|
||||
IsDisplayed(_) => "isElementDisplayed",
|
||||
IsSelected(_) => "isElementSelected",
|
||||
GetElementAttribute(_, _) => "getElementAttribute",
|
||||
GetCSSValue(_, _) => "getElementValueOfCssProperty",
|
||||
GetElementText(_) => "getElementText",
|
||||
GetElementTagName(_) => "getElementTagName",
|
||||
GetElementRect(_) => "getElementRect",
|
||||
IsEnabled(_) => "isElementEnabled",
|
||||
ExecuteScript(_) => "executeScript",
|
||||
ExecuteAsyncScript(_) => "executeAsyncScript"
|
||||
}.to_string()
|
||||
NewSession => Some("newSession"),
|
||||
DeleteSession => Some("deleteSession"),
|
||||
Get(_) => Some("get"),
|
||||
GetCurrentUrl => Some("getCurrentUrl"),
|
||||
GoBack => Some("goBack"),
|
||||
GoForward => Some("goForward"),
|
||||
Refresh => Some("refresh"),
|
||||
GetTitle => Some("getTitle"),
|
||||
GetWindowHandle => Some("getWindowHandle"),
|
||||
GetWindowHandles => Some("getWindowHandles"),
|
||||
Close => Some("close"),
|
||||
SetTimeouts(_) => Some("timeouts"),
|
||||
SetWindowSize(_) => Some("setWindowSize"),
|
||||
GetWindowSize => Some("getWindowSize"),
|
||||
MaximizeWindow => Some("maximizeWindow"),
|
||||
SwitchToWindow(_) => Some("switchToWindow"),
|
||||
SwitchToFrame(_) => Some("switchToFrame"),
|
||||
SwitchToParentFrame => Some("switchToParentFrame"),
|
||||
FindElement(_) => Some("findElement"),
|
||||
FindElements(_) => Some("findElements"),
|
||||
IsDisplayed(_) => Some("isElementDisplayed"),
|
||||
IsSelected(_) => Some("isElementSelected"),
|
||||
GetElementAttribute(_, _) => Some("getElementAttribute"),
|
||||
GetCSSValue(_, _) => Some("getElementValueOfCssProperty"),
|
||||
GetElementText(_) => Some("getElementText"),
|
||||
GetElementTagName(_) => Some("getElementTagName"),
|
||||
GetElementRect(_) => Some("getElementRect"),
|
||||
IsEnabled(_) => Some("isElementEnabled"),
|
||||
ExecuteScript(_) => Some("executeScript"),
|
||||
ExecuteAsyncScript(_) => Some("executeAsyncScript"),
|
||||
GetCookie(_) => Some("getCookies"),
|
||||
AddCookie(_) => Some("addCookie"),
|
||||
DismissAlert => None, //Unsupported
|
||||
AcceptAlert => None, //Unsupported
|
||||
GetAlertText => None, //Unsupported
|
||||
SendAlertText(_) => None, //Unsupported
|
||||
TakeScreenshot(_) => Some("takeScreenshot")
|
||||
}.map(|x| x.into_string())
|
||||
}
|
||||
|
||||
pub fn msg_to_marionette(&self, msg: &WebDriverMessage) -> json::Json {
|
||||
let mut data = msg.to_json().as_object().unwrap().clone();
|
||||
pub fn msg_to_marionette(&self, msg: &WebDriverMessage) -> WebDriverResult<json::Json> {
|
||||
let command_name = try_opt!(MarionetteSession::command_name(msg),
|
||||
ErrorStatus::UnsupportedOperation,
|
||||
"Operation not supported");
|
||||
let mut data = try_opt!(msg.to_json().as_object(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to convert message to Object"
|
||||
).clone();
|
||||
match msg.session_id {
|
||||
Some(ref x) => data.insert("sessionId".to_string(), x.to_json()),
|
||||
None => None
|
||||
};
|
||||
data.insert("to".to_string(), self.to.to_json());
|
||||
data.insert("name".to_string(), MarionetteSession::command_name(msg).to_json());
|
||||
json::Object(data)
|
||||
data.insert("name".to_string(), command_name.to_json());
|
||||
Ok(json::Object(data))
|
||||
}
|
||||
|
||||
pub fn response_from_json(&mut self, message: &WebDriverMessage,
|
||||
|
@ -129,23 +136,26 @@ impl MarionetteSession {
|
|||
return Err(WebDriverError::new(status, err_msg));
|
||||
}
|
||||
|
||||
self.update(message, &json_data);
|
||||
try!(self.update(message, &json_data));
|
||||
|
||||
match message.command {
|
||||
//Everything that doesn't have a response value
|
||||
GetMarionetteId => Ok(None),
|
||||
Get(_) | GoBack | GoForward | Refresh | Close | Timeouts(_) |
|
||||
Get(_) | GoBack | GoForward | Refresh | Close | SetTimeouts(_) |
|
||||
SetWindowSize(_) | MaximizeWindow | SwitchToWindow(_) | SwitchToFrame(_) |
|
||||
SwitchToParentFrame => {
|
||||
SwitchToParentFrame | AddCookie(_) | DismissAlert | AcceptAlert |
|
||||
SendAlertText(_) => {
|
||||
Ok(Some(WebDriverResponse::Void))
|
||||
},
|
||||
//Things that simply return the contents of the marionette "value" property
|
||||
GetCurrentUrl | GetTitle | GetWindowHandle | GetWindowHandles | IsDisplayed(_) |
|
||||
IsSelected(_) | GetElementAttribute(_, _) | GetCSSValue(_, _) | GetElementText(_) |
|
||||
GetElementTagName(_) | IsEnabled(_) | ExecuteScript(_) | ExecuteAsyncScript(_) => {
|
||||
GetCurrentUrl | GetTitle | GetWindowHandle | GetWindowHandles |
|
||||
FindElement(_) | FindElements(_) | IsDisplayed(_) | IsSelected(_) |
|
||||
GetElementAttribute(_, _) | GetCSSValue(_, _) | GetElementText(_) |
|
||||
GetElementTagName(_) | IsEnabled(_) | ExecuteScript(_) | ExecuteAsyncScript(_) |
|
||||
GetAlertText | TakeScreenshot(_) => {
|
||||
let value = try_opt!(json_data.get("value"),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to find value field");
|
||||
//TODO: Convert webelement keys
|
||||
Ok(Some(WebDriverResponse::Generic(ValueResponse::new(value.clone()))))
|
||||
},
|
||||
GetWindowSize => {
|
||||
|
@ -209,14 +219,84 @@ impl MarionetteSession {
|
|||
"Failed to interpret width as integer");
|
||||
|
||||
Ok(Some(WebDriverResponse::ElementRect(ElementRectResponse::new(x, y, width, height))))
|
||||
}
|
||||
},
|
||||
GetCookie(_) => {
|
||||
let value = try_opt!(
|
||||
try_opt!(json_data.get("value"),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to find value field").as_array(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to interpret value as array");
|
||||
let cookies = try!(value.iter().map(|x| {
|
||||
let name = try_opt!(
|
||||
try_opt!(x.find("name"),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to find name field").as_string(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to interpret name as string").into_string();
|
||||
let value = try_opt!(
|
||||
try_opt!(x.find("value"),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to find value field").as_string(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to interpret value as string").into_string();
|
||||
let path = try!(
|
||||
Nullable::from_json(try_opt!(x.find("path"),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to find path field"),
|
||||
|x| {
|
||||
Ok((try_opt!(x.as_string(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to interpret path as String")).into_string())
|
||||
}));
|
||||
let domain = try!(
|
||||
Nullable::from_json(try_opt!(x.find("domain"),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to find domain field"),
|
||||
|x| {
|
||||
Ok((try_opt!(x.as_string(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to interpret domain as String")).into_string())
|
||||
}));
|
||||
let expiry = try!(
|
||||
Nullable::from_json(try_opt!(x.find("expiry"),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to find expiry field"),
|
||||
|x| {
|
||||
Ok(Date::new((try_opt!(
|
||||
x.as_u64(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to interpret domain as String"))))
|
||||
}));
|
||||
let max_age = Date::new(try_opt!(
|
||||
try_opt!(x.find("maxAge"),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to find maxAge field").as_u64(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to interpret maxAge as u64"));
|
||||
let secure = match x.find("secure") {
|
||||
Some(x) => try_opt!(x.as_boolean(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to interpret secure as boolean"),
|
||||
None => false
|
||||
};
|
||||
let http_only = match x.find("httpOnly") {
|
||||
Some(x) => try_opt!(x.as_boolean(),
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to interpret http_only as boolean"),
|
||||
None => false
|
||||
};
|
||||
Ok(Cookie::new(name, value, path, domain, expiry, max_age, secure, http_only))
|
||||
}).collect::<Result<Vec<_>, _>>());
|
||||
Ok(Some(WebDriverResponse::Cookie(CookieResponse::new(cookies))))
|
||||
},
|
||||
NewSession => {
|
||||
let session_id = try_opt!(
|
||||
try_opt!(json_data.get("sessionId"),
|
||||
ErrorStatus::InvalidSessionId,
|
||||
"Failed to find sessionId field").as_string(),
|
||||
ErrorStatus::InvalidSessionId,
|
||||
"sessionId was not a string");
|
||||
"sessionId was not a string").into_string();
|
||||
|
||||
let value = try_opt!(
|
||||
try_opt!(json_data.get("value"),
|
||||
|
@ -226,7 +306,7 @@ impl MarionetteSession {
|
|||
"value field was not an Object");
|
||||
|
||||
Ok(Some(WebDriverResponse::NewSession(NewSessionResponse::new(
|
||||
session_id.to_string(), json::Object(value.clone())))))
|
||||
session_id, json::Object(value.clone())))))
|
||||
}
|
||||
DeleteSession => {
|
||||
Ok(Some(WebDriverResponse::DeleteSession))
|
||||
|
@ -310,9 +390,7 @@ impl MarionetteConnection {
|
|||
}
|
||||
|
||||
pub fn send_message(&mut self, msg: &WebDriverMessage) -> WebDriverResult<Option<WebDriverResponse>> {
|
||||
let resp = {
|
||||
self.session.msg_to_marionette(msg)
|
||||
};
|
||||
let resp = try!(self.session.msg_to_marionette(msg));
|
||||
let resp = match self.send(&resp) {
|
||||
Ok(resp_data) => self.session.response_from_json(msg, resp_data[]),
|
||||
Err(x) => Err(x)
|
||||
|
|
|
@ -18,13 +18,14 @@ pub enum MatchType {
|
|||
GetWindowHandle,
|
||||
GetWindowHandles,
|
||||
Close,
|
||||
Timeouts,
|
||||
SetWindowSize,
|
||||
GetWindowSize,
|
||||
MaximizeWindow,
|
||||
SwitchToWindow,
|
||||
SwitchToFrame,
|
||||
SwitchToParentFrame,
|
||||
FindElement,
|
||||
FindElements,
|
||||
IsDisplayed,
|
||||
IsSelected,
|
||||
GetElementAttribute,
|
||||
|
@ -35,6 +36,15 @@ pub enum MatchType {
|
|||
IsEnabled,
|
||||
ExecuteScript,
|
||||
ExecuteAsyncScript,
|
||||
GetCookie,
|
||||
AddCookie,
|
||||
SetTimeouts,
|
||||
//Actions XXX - once I understand the spec, perhaps
|
||||
DismissAlert,
|
||||
AcceptAlert,
|
||||
GetAlertText,
|
||||
SendAlertText,
|
||||
TakeScreenshot
|
||||
}
|
||||
|
||||
#[deriving(Clone)]
|
||||
|
@ -131,13 +141,14 @@ pub fn get_builder() -> MessageBuilder {
|
|||
(Get, "/session/{sessionId}/window_handle", MatchType::GetWindowHandle),
|
||||
(Get, "/session/{sessionId}/window_handles", MatchType::GetWindowHandles),
|
||||
(Delete, "/session/{sessionId}/window_handle", MatchType::Close),
|
||||
(Post, "/session/{sessionId}/timeouts", MatchType::Timeouts),
|
||||
(Post, "/session/{sessionId}/window/size", MatchType::SetWindowSize),
|
||||
(Get, "/session/{sessionId}/window/size", MatchType::GetWindowSize),
|
||||
(Post, "/session/{sessionId}/window/maximize", MatchType::MaximizeWindow),
|
||||
(Post, "/session/{sessionId}/window", MatchType::SwitchToWindow),
|
||||
(Post, "/session/{sessionId}/frame", MatchType::SwitchToFrame),
|
||||
(Post, "/session/{sessionId}/frame/parent", MatchType::SwitchToParentFrame),
|
||||
(Post, "/session/{sessionId}/element", MatchType::FindElement),
|
||||
(Post, "/session/{sessionId}/elements", MatchType::FindElements),
|
||||
(Get, "/session/{sessionId}/element/{element}/isDisplayed", MatchType::IsDisplayed),
|
||||
(Get, "/session/{sessionId}/element/{element}/isSelected", MatchType::IsSelected),
|
||||
(Get, "/session/{sessionId}/element/{element}/attribute/{name}", MatchType::GetElementAttribute),
|
||||
|
@ -148,6 +159,15 @@ pub fn get_builder() -> MessageBuilder {
|
|||
(Get, "/session/{sessionId}/element/{element}/enabled", MatchType::IsEnabled),
|
||||
(Post, "/session/{sessionId}/execute", MatchType::ExecuteScript),
|
||||
(Post, "/session/{sessionId}/execute_async", MatchType::ExecuteAsyncScript),
|
||||
(Get, "/session/{sessionId}/cookie", MatchType::GetCookie),
|
||||
(Post, "/session/{sessionId}/cookie", MatchType::AddCookie),
|
||||
(Post, "/session/{sessionId}/timeouts", MatchType::SetTimeouts),
|
||||
//(Post, "/session/{sessionId}/actions", MatchType::Actions),
|
||||
(Post, "/session/{sessionId}/dismiss_alert", MatchType::DismissAlert),
|
||||
(Post, "/session/{sessionId}/accept_alert", MatchType::AcceptAlert),
|
||||
(Get, "/session/{sessionId}/alert_text", MatchType::GetAlertText),
|
||||
(Post, "/session/{sessionId}/alert_text", MatchType::SendAlertText),
|
||||
(Get, "/session/{sessionId}/screenshot", MatchType::TakeScreenshot)
|
||||
];
|
||||
debug!("Creating routes");
|
||||
for &(ref method, ref url, ref match_type) in matchers.iter() {
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
use serialize::json;
|
||||
use serialize::json::ToJson;
|
||||
|
||||
use common::Nullable;
|
||||
|
||||
#[deriving(Show)]
|
||||
pub enum WebDriverResponse {
|
||||
|
@ -6,6 +9,7 @@ pub enum WebDriverResponse {
|
|||
DeleteSession,
|
||||
WindowSize(WindowSizeResponse),
|
||||
ElementRect(ElementRectResponse),
|
||||
Cookie(CookieResponse),
|
||||
Generic(ValueResponse),
|
||||
Void
|
||||
}
|
||||
|
@ -17,6 +21,7 @@ impl WebDriverResponse {
|
|||
WebDriverResponse::DeleteSession => "".into_string(),
|
||||
WebDriverResponse::WindowSize(x) => json::encode(&x),
|
||||
WebDriverResponse::ElementRect(x) => json::encode(&x),
|
||||
WebDriverResponse::Cookie(x) => json::encode(&x),
|
||||
WebDriverResponse::Generic(x) => json::encode(&x),
|
||||
WebDriverResponse::Void => "".into_string()
|
||||
}
|
||||
|
@ -84,3 +89,61 @@ impl ElementRectResponse {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Encodable, PartialEq, Show)]
|
||||
pub struct Date(u64);
|
||||
|
||||
impl Date {
|
||||
pub fn new(timestamp: u64) -> Date {
|
||||
Date(timestamp)
|
||||
}
|
||||
}
|
||||
|
||||
impl ToJson for Date {
|
||||
fn to_json(&self) -> json::Json {
|
||||
let &Date(x) = self;
|
||||
x.to_json()
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: some of these fields are probably supposed to be optional
|
||||
#[deriving(Encodable, PartialEq, Show)]
|
||||
pub struct Cookie {
|
||||
name: String,
|
||||
value: String,
|
||||
path: Nullable<String>,
|
||||
domain: Nullable<String>,
|
||||
expiry: Nullable<Date>,
|
||||
maxAge: Date,
|
||||
secure: bool,
|
||||
httpOnly: bool
|
||||
}
|
||||
|
||||
impl Cookie {
|
||||
pub fn new(name: String, value: String, path: Nullable<String>, domain: Nullable<String>,
|
||||
expiry: Nullable<Date>, max_age: Date, secure: bool, http_only: bool) -> Cookie {
|
||||
Cookie {
|
||||
name: name,
|
||||
value: value,
|
||||
path: path,
|
||||
domain: domain,
|
||||
expiry: expiry,
|
||||
maxAge: max_age,
|
||||
secure: secure,
|
||||
httpOnly: http_only
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Encodable, Show)]
|
||||
pub struct CookieResponse {
|
||||
value: Vec<Cookie>
|
||||
}
|
||||
|
||||
impl CookieResponse {
|
||||
pub fn new(value: Vec<Cookie>) -> CookieResponse {
|
||||
CookieResponse {
|
||||
value: value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче