Skip to content

Commit

Permalink
Add support for high-level ations based on what the spec probably oug…
Browse files Browse the repository at this point in the history
…ht to say.
  • Loading branch information
jgraham committed Jan 7, 2015
1 parent 84ced38 commit 19fb41e
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 20 deletions.
90 changes: 72 additions & 18 deletions src/command.rs
Expand Up @@ -43,7 +43,11 @@ pub enum WebDriverCommand {
GetCookie(GetCookieParameters),
AddCookie(AddCookieParameters),
SetTimeouts(TimeoutsParameters),
//Actions(ActionsParameters)
//Actions(ActionsParameters),
ElementClick(WebElement),
ElementTap(WebElement),
ElementClear(WebElement),
ElementSendKeys(WebElement, SendKeysParameters),
DismissAlert,
AcceptAlert,
GetAlertText,
Expand Down Expand Up @@ -153,6 +157,23 @@ impl WebDriverMessage {
let element = WebElement::new(params.name("elementId").to_string());
WebDriverCommand::IsEnabled(element)
},
MatchType::ElementClick => {
let element = WebElement::new(params.name("elementId").to_string());
WebDriverCommand::ElementClick(element)
},
MatchType::ElementTap => {
let element = WebElement::new(params.name("elementId").to_string());
WebDriverCommand::ElementTap(element)
},
MatchType::ElementClear => {
let element = WebElement::new(params.name("elementId").to_string());
WebDriverCommand::ElementClear(element)
},
MatchType::ElementSendKeys => {
let element = WebElement::new(params.name("elementId").to_string());
let parameters: SendKeysParameters = try!(Parameters::from_json(&body_data));
WebDriverCommand::ElementSendKeys(element, parameters)
},
MatchType::ExecuteScript => {
let parameters: JavascriptCommandParameters = try!(Parameters::from_json(&body_data));
WebDriverCommand::ExecuteScript(parameters)
Expand Down Expand Up @@ -214,7 +235,8 @@ impl ToJson for WebDriverMessage {
WebDriverCommand::GetElementTagName(_) | WebDriverCommand::GetElementRect(_) |
WebDriverCommand::IsEnabled(_) | WebDriverCommand::AddCookie(_) |
WebDriverCommand::DismissAlert | WebDriverCommand::AcceptAlert |
WebDriverCommand::GetAlertText => {
WebDriverCommand::GetAlertText | WebDriverCommand::ElementClick(_) |
WebDriverCommand::ElementTap(_) | WebDriverCommand::ElementClear(_) => {
None
},
WebDriverCommand::Get(ref x) => Some(x.to_json()),
Expand All @@ -224,6 +246,7 @@ impl ToJson for WebDriverMessage {
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::ElementSendKeys(_, ref x) => Some(x.to_json()),
WebDriverCommand::ExecuteScript(ref x) |
WebDriverCommand::ExecuteAsyncScript(ref x) => Some(x.to_json()),
WebDriverCommand::GetCookie(ref x) => Some(x.to_json()),
Expand Down Expand Up @@ -443,6 +466,36 @@ impl ToJson for SwitchToFrameParameters {
}
}

#[deriving(PartialEq)]
pub struct SendKeysParameters {
pub value: String
}

impl Parameters for SendKeysParameters {
fn from_json(body: &json::Json) -> WebDriverResult<SendKeysParameters> {
let data = try_opt!(body.as_object(),
ErrorStatus::InvalidArgument,
"Message body was not an object");
let value = try_opt!(try_opt!(data.get("value"),
ErrorStatus::InvalidArgument,
"Missing 'value' parameter").as_string(),
ErrorStatus::InvalidArgument,
"'value' not a string").into_string();

Ok(SendKeysParameters {
value: value
})
}
}

impl ToJson for SendKeysParameters {
fn to_json(&self) -> json::Json {
let mut data = TreeMap::new();
data.insert("value".to_string(), self.value.to_json());
json::Object(data)
}
}

#[deriving(PartialEq)]
pub struct JavascriptCommandParameters {
script: String,
Expand All @@ -452,27 +505,27 @@ pub struct JavascriptCommandParameters {
impl Parameters for JavascriptCommandParameters {
fn from_json(body: &json::Json) -> WebDriverResult<JavascriptCommandParameters> {
let data = try_opt!(body.as_object(),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Message body was not an object");

let args_json = try_opt!(data.get("args"),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Missing args parameter");

let args = try!(Nullable::from_json(
args_json,
|x| {
Ok((try_opt!(x.as_array(),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Failed to convert args to Array")).clone())
}));

//TODO: Look for WebElements in args?
let script = try_opt!(
try_opt!(data.get("script"),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Missing script parameter").as_string(),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Failed to convert script to String");
Ok(JavascriptCommandParameters {
script: script.to_string(),
Expand Down Expand Up @@ -501,7 +554,7 @@ pub struct GetCookieParameters {

impl Parameters for GetCookieParameters {
fn from_json(body: &json::Json) -> WebDriverResult<GetCookieParameters> {
let data = try_opt!(body.as_object(), ErrorStatus::UnknownError,
let data = try_opt!(body.as_object(), ErrorStatus::InvalidArgument,
"Message body was not an object");
let name_json = try_opt!(data.get("name"),
ErrorStatus::InvalidArgument,
Expand All @@ -510,7 +563,7 @@ impl Parameters for GetCookieParameters {
name_json,
|x| {
Ok(try_opt!(x.as_string(),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Failed to convert name to String").into_string())
}));
return Ok(GetCookieParameters {
Expand Down Expand Up @@ -542,7 +595,7 @@ pub struct AddCookieParameters {
impl Parameters for AddCookieParameters {
fn from_json(body: &json::Json) -> WebDriverResult<AddCookieParameters> {
let data = try_opt!(body.as_object(),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Message body was not an object");
let name = try_opt!(
try_opt!(data.get("name"),
Expand All @@ -564,7 +617,7 @@ impl Parameters for AddCookieParameters {
path_json,
|x| {
Ok(try_opt!(x.as_string(),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Failed to convert path to String").into_string())
}))
},
Expand All @@ -577,7 +630,7 @@ impl Parameters for AddCookieParameters {
domain_json,
|x| {
Ok(try_opt!(x.as_string(),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Failed to convert domain to String").into_string())
}))
},
Expand All @@ -591,7 +644,7 @@ impl Parameters for AddCookieParameters {
expiry_json,
|x| {
Ok(Date::new(try_opt!(x.as_u64(),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Failed to convert expiry to Date")))
}))
},
Expand All @@ -604,7 +657,7 @@ impl Parameters for AddCookieParameters {
max_age_json,
|x| {
Ok(Date::new(try_opt!(x.as_u64(),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Failed to convert expiry to Date")))
}))
},
Expand All @@ -613,14 +666,14 @@ impl Parameters for AddCookieParameters {

let secure = match data.get("secure") {
Some(x) => try_opt!(x.as_boolean(),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Failed to convert secure to boolean"),
None => false
};

let http_only = match data.get("httpOnly") {
Some(x) => try_opt!(x.as_boolean(),
ErrorStatus::UnknownError,
ErrorStatus::InvalidArgument,
"Failed to convert httpOnly to boolean"),
None => false
};
Expand Down Expand Up @@ -660,7 +713,7 @@ pub struct SendAlertTextParameters {

impl Parameters for SendAlertTextParameters {
fn from_json(body: &json::Json) -> WebDriverResult<SendAlertTextParameters> {
let data = try_opt!(body.as_object(), ErrorStatus::UnknownError,
let data = try_opt!(body.as_object(), ErrorStatus::InvalidArgument,
"Message body was not an object");
let keys = try_opt!(
try_opt!(data.get("keysToSend"),
Expand Down Expand Up @@ -689,7 +742,8 @@ pub struct TakeScreenshotParameters {

impl Parameters for TakeScreenshotParameters {
fn from_json(body: &json::Json) -> WebDriverResult<TakeScreenshotParameters> {
let data = try_opt!(body.as_object(), ErrorStatus::UnknownError,
let data = try_opt!(body.as_object(),
ErrorStatus::InvalidArgument,
"Message body was not an object");
let element = match data.get("element") {
Some(element_json) => try!(Nullable::from_json(
Expand Down
15 changes: 13 additions & 2 deletions src/marionette.rs
Expand Up @@ -10,7 +10,8 @@ use command::WebDriverCommand::{NewSession, DeleteSession, Get, GetCurrentUrl,
GetWindowSize, MaximizeWindow, SwitchToWindow, SwitchToFrame,
SwitchToParentFrame, FindElement, FindElements, IsDisplayed,
IsSelected, GetElementAttribute, GetCSSValue, GetElementText,
GetElementTagName, GetElementRect, IsEnabled, ExecuteScript,
GetElementTagName, GetElementRect, IsEnabled, ElementClick,
ElementTap, ElementClear, ElementSendKeys, ExecuteScript,
ExecuteAsyncScript, GetCookie, AddCookie, SetTimeouts,
DismissAlert, AcceptAlert, GetAlertText, SendAlertText,
TakeScreenshot};
Expand Down Expand Up @@ -97,7 +98,8 @@ impl MarionetteSession {
Get(_) | GoBack | GoForward | Refresh | Close | SetTimeouts(_) |
SetWindowSize(_) | MaximizeWindow | SwitchToWindow(_) | SwitchToFrame(_) |
SwitchToParentFrame | AddCookie(_) | DismissAlert | AcceptAlert |
SendAlertText(_) => {
SendAlertText(_) | ElementClick(_) | ElementTap(_) | ElementClear(_) |
ElementSendKeys(_, _) => {
Ok(Some(WebDriverResponse::Void))
},
//Things that simply return the contents of the marionette "value" property
Expand Down Expand Up @@ -438,6 +440,15 @@ impl ToMarionette for WebDriverMessage {
GetElementTagName(ref x) => (Some("getElementTagName"), Some(x.to_marionette())),
GetElementRect(ref x) => (Some("getElementRect"), Some(x.to_marionette())),
IsEnabled(ref x) => (Some("isElementEnabled"), Some(x.to_marionette())),
ElementClick(ref x) => (Some("clickElement"), Some(x.to_marionette())),
ElementTap(ref x) => (Some("singleTap"), Some(x.to_marionette())),
ElementClear(ref x) => (Some("clearElement"), Some(x.to_marionette())),
ElementSendKeys(ref e, ref x) => {
let mut data = TreeMap::new();
data.insert("id".to_string(), e.id.to_json());
data.insert("value".to_string(), x.value.to_json());
(Some("sendKeysToElement"), Some(Ok(Json::Object(data))))
},
ExecuteScript(ref x) => (Some("executeScript"), Some(x.to_marionette())),
ExecuteAsyncScript(ref x) => (Some("executeAsyncScript"), Some(x.to_marionette())),
GetCookie(ref x) => (Some("getCookies"), Some(x.to_marionette())),
Expand Down
8 changes: 8 additions & 0 deletions src/messagebuilder.rs
Expand Up @@ -40,6 +40,10 @@ pub enum MatchType {
AddCookie,
SetTimeouts,
//Actions XXX - once I understand the spec, perhaps
ElementClick,
ElementTap,
ElementClear,
ElementSendKeys,
DismissAlert,
AcceptAlert,
GetAlertText,
Expand Down Expand Up @@ -163,6 +167,10 @@ pub fn get_builder() -> MessageBuilder {
(Post, "/session/{sessionId}/cookie", MatchType::AddCookie),
(Post, "/session/{sessionId}/timeouts", MatchType::SetTimeouts),
//(Post, "/session/{sessionId}/actions", MatchType::Actions),
(Post, "/session/{sessionId}/element/{elementId}/click", MatchType::ElementClick),
(Post, "/session/{sessionId}/element/{elementId}/tap", MatchType::ElementTap),
(Post, "/session/{sessionId}/element/{elementId}/clear", MatchType::ElementClear),
(Post, "/session/{sessionId}/element/{elementId}/sendKeys", MatchType::ElementSendKeys),
(Post, "/session/{sessionId}/dismiss_alert", MatchType::DismissAlert),
(Post, "/session/{sessionId}/accept_alert", MatchType::AcceptAlert),
(Get, "/session/{sessionId}/alert_text", MatchType::GetAlertText),
Expand Down

0 comments on commit 19fb41e

Please sign in to comment.