deleted file mode 100644
--- a/third_party/rust/webdriver/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".travis.yml":"78252ef89a407b1d76616b7afbf7afb8205530a7f7039f3a7ea140684e3aa8bc","Cargo.toml":"9ce1bfb98e94cb9f2494676ef0cc741dcfeab1b60d7f5fa23ae261b02025bc1c","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","README.md":"bd0e99ce271903a9f67cf5f8fca2f67f2583e4336fbaf583fcd78ec238d4176e","src/capabilities.rs":"12a71bf787f1102435f9c2ae2c357acf397b80fadcb3355710ef9bbc39d8a337","src/command.rs":"3538491c5e77746eca8d326185903f3336e47f75f69401167acbd655708e736a","src/common.rs":"79d50f6c29f16d370b707988fe7b1747e17372f979df75d30be3e250dce55836","src/error.rs":"7621e0c325c488b537e1bd26dd580b23863bf07bbae52cf8b77e6a7d37df47c3","src/httpapi.rs":"83fec1cefedbadb8bf7458374f909a44ff76d67046e8428fc01067d5d8401dc6","src/lib.rs":"336c146e934711dfe49f4b44bbcf278686b00be8d89abb9c7b7b045254994fbf","src/macros.rs":"93094c48e3880d925e684fba9678693eb8c0c39c7ed47b130b0751c4bca37ddc","src/response.rs":"160bc15135d623d1bc5b33c6edaf69a4034d36c1cd8d9cefb64f436001dda01e","src/server.rs":"4f8976a215783c98f1e3927e5440590fe3a41189bf62fea151434598f904753c"},"package":"b05f860c230757d0df161f6b2db8820ca636940689b29b148ea53bd8685feb84"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/webdriver/.travis.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-language: rust
-
-rust:
- - nightly
- - stable
-
-script:
- - cargo build --verbose
- - cargo test --verbose
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/webdriver/Cargo.toml
+++ /dev/null
@@ -1,46 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "webdriver"
-version = "0.30.0"
-authors = ["Mozilla Tools and Automation <tools@lists.mozilla.com>"]
-description = "Library implementing the wire protocol for the W3C WebDriver specification"
-documentation = "https://docs.rs/webdriver"
-readme = "README.md"
-keywords = ["webdriver", "browser", "automation", "protocol", "w3c"]
-license = "MPL-2.0"
-repository = "https://github.com/mozilla/webdriver-rust"
-[dependencies.time]
-version = "0.1"
-
-[dependencies.rustc-serialize]
-version = "0.3"
-
-[dependencies.backtrace]
-version = "0.3"
-
-[dependencies.log]
-version = "0.3"
-
-[dependencies.cookie]
-version = "0.9"
-default-features = false
-
-[dependencies.url]
-version = "1"
-
-[dependencies.hyper]
-version = "0.10"
-
-[dependencies.regex]
-version = "0.2"
deleted file mode 100644
--- a/third_party/rust/webdriver/LICENSE
+++ /dev/null
@@ -1,373 +0,0 @@
-Mozilla Public License Version 2.0
-==================================
-
-1. Definitions
---------------
-
-1.1. "Contributor"
- means each individual or legal entity that creates, contributes to
- the creation of, or owns Covered Software.
-
-1.2. "Contributor Version"
- means the combination of the Contributions of others (if any) used
- by a Contributor and that particular Contributor's Contribution.
-
-1.3. "Contribution"
- means Covered Software of a particular Contributor.
-
-1.4. "Covered Software"
- means Source Code Form to which the initial Contributor has attached
- the notice in Exhibit A, the Executable Form of such Source Code
- Form, and Modifications of such Source Code Form, in each case
- including portions thereof.
-
-1.5. "Incompatible With Secondary Licenses"
- means
-
- (a) that the initial Contributor has attached the notice described
- in Exhibit B to the Covered Software; or
-
- (b) that the Covered Software was made available under the terms of
- version 1.1 or earlier of the License, but not also under the
- terms of a Secondary License.
-
-1.6. "Executable Form"
- means any form of the work other than Source Code Form.
-
-1.7. "Larger Work"
- means a work that combines Covered Software with other material, in
- a separate file or files, that is not Covered Software.
-
-1.8. "License"
- means this document.
-
-1.9. "Licensable"
- means having the right to grant, to the maximum extent possible,
- whether at the time of the initial grant or subsequently, any and
- all of the rights conveyed by this License.
-
-1.10. "Modifications"
- means any of the following:
-
- (a) any file in Source Code Form that results from an addition to,
- deletion from, or modification of the contents of Covered
- Software; or
-
- (b) any new file in Source Code Form that contains any Covered
- Software.
-
-1.11. "Patent Claims" of a Contributor
- means any patent claim(s), including without limitation, method,
- process, and apparatus claims, in any patent Licensable by such
- Contributor that would be infringed, but for the grant of the
- License, by the making, using, selling, offering for sale, having
- made, import, or transfer of either its Contributions or its
- Contributor Version.
-
-1.12. "Secondary License"
- means either the GNU General Public License, Version 2.0, the GNU
- Lesser General Public License, Version 2.1, the GNU Affero General
- Public License, Version 3.0, or any later versions of those
- licenses.
-
-1.13. "Source Code Form"
- means the form of the work preferred for making modifications.
-
-1.14. "You" (or "Your")
- means an individual or a legal entity exercising rights under this
- License. For legal entities, "You" includes any entity that
- controls, is controlled by, or is under common control with You. For
- purposes of this definition, "control" means (a) the power, direct
- or indirect, to cause the direction or management of such entity,
- whether by contract or otherwise, or (b) ownership of more than
- fifty percent (50%) of the outstanding shares or beneficial
- ownership of such entity.
-
-2. License Grants and Conditions
---------------------------------
-
-2.1. Grants
-
-Each Contributor hereby grants You a world-wide, royalty-free,
-non-exclusive license:
-
-(a) under intellectual property rights (other than patent or trademark)
- Licensable by such Contributor to use, reproduce, make available,
- modify, display, perform, distribute, and otherwise exploit its
- Contributions, either on an unmodified basis, with Modifications, or
- as part of a Larger Work; and
-
-(b) under Patent Claims of such Contributor to make, use, sell, offer
- for sale, have made, import, and otherwise transfer either its
- Contributions or its Contributor Version.
-
-2.2. Effective Date
-
-The licenses granted in Section 2.1 with respect to any Contribution
-become effective for each Contribution on the date the Contributor first
-distributes such Contribution.
-
-2.3. Limitations on Grant Scope
-
-The licenses granted in this Section 2 are the only rights granted under
-this License. No additional rights or licenses will be implied from the
-distribution or licensing of Covered Software under this License.
-Notwithstanding Section 2.1(b) above, no patent license is granted by a
-Contributor:
-
-(a) for any code that a Contributor has removed from Covered Software;
- or
-
-(b) for infringements caused by: (i) Your and any other third party's
- modifications of Covered Software, or (ii) the combination of its
- Contributions with other software (except as part of its Contributor
- Version); or
-
-(c) under Patent Claims infringed by Covered Software in the absence of
- its Contributions.
-
-This License does not grant any rights in the trademarks, service marks,
-or logos of any Contributor (except as may be necessary to comply with
-the notice requirements in Section 3.4).
-
-2.4. Subsequent Licenses
-
-No Contributor makes additional grants as a result of Your choice to
-distribute the Covered Software under a subsequent version of this
-License (see Section 10.2) or under the terms of a Secondary License (if
-permitted under the terms of Section 3.3).
-
-2.5. Representation
-
-Each Contributor represents that the Contributor believes its
-Contributions are its original creation(s) or it has sufficient rights
-to grant the rights to its Contributions conveyed by this License.
-
-2.6. Fair Use
-
-This License is not intended to limit any rights You have under
-applicable copyright doctrines of fair use, fair dealing, or other
-equivalents.
-
-2.7. Conditions
-
-Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
-in Section 2.1.
-
-3. Responsibilities
--------------------
-
-3.1. Distribution of Source Form
-
-All distribution of Covered Software in Source Code Form, including any
-Modifications that You create or to which You contribute, must be under
-the terms of this License. You must inform recipients that the Source
-Code Form of the Covered Software is governed by the terms of this
-License, and how they can obtain a copy of this License. You may not
-attempt to alter or restrict the recipients' rights in the Source Code
-Form.
-
-3.2. Distribution of Executable Form
-
-If You distribute Covered Software in Executable Form then:
-
-(a) such Covered Software must also be made available in Source Code
- Form, as described in Section 3.1, and You must inform recipients of
- the Executable Form how they can obtain a copy of such Source Code
- Form by reasonable means in a timely manner, at a charge no more
- than the cost of distribution to the recipient; and
-
-(b) You may distribute such Executable Form under the terms of this
- License, or sublicense it under different terms, provided that the
- license for the Executable Form does not attempt to limit or alter
- the recipients' rights in the Source Code Form under this License.
-
-3.3. Distribution of a Larger Work
-
-You may create and distribute a Larger Work under terms of Your choice,
-provided that You also comply with the requirements of this License for
-the Covered Software. If the Larger Work is a combination of Covered
-Software with a work governed by one or more Secondary Licenses, and the
-Covered Software is not Incompatible With Secondary Licenses, this
-License permits You to additionally distribute such Covered Software
-under the terms of such Secondary License(s), so that the recipient of
-the Larger Work may, at their option, further distribute the Covered
-Software under the terms of either this License or such Secondary
-License(s).
-
-3.4. Notices
-
-You may not remove or alter the substance of any license notices
-(including copyright notices, patent notices, disclaimers of warranty,
-or limitations of liability) contained within the Source Code Form of
-the Covered Software, except that You may alter any license notices to
-the extent required to remedy known factual inaccuracies.
-
-3.5. Application of Additional Terms
-
-You may choose to offer, and to charge a fee for, warranty, support,
-indemnity or liability obligations to one or more recipients of Covered
-Software. However, You may do so only on Your own behalf, and not on
-behalf of any Contributor. You must make it absolutely clear that any
-such warranty, support, indemnity, or liability obligation is offered by
-You alone, and You hereby agree to indemnify every Contributor for any
-liability incurred by such Contributor as a result of warranty, support,
-indemnity or liability terms You offer. You may include additional
-disclaimers of warranty and limitations of liability specific to any
-jurisdiction.
-
-4. Inability to Comply Due to Statute or Regulation
----------------------------------------------------
-
-If it is impossible for You to comply with any of the terms of this
-License with respect to some or all of the Covered Software due to
-statute, judicial order, or regulation then You must: (a) comply with
-the terms of this License to the maximum extent possible; and (b)
-describe the limitations and the code they affect. Such description must
-be placed in a text file included with all distributions of the Covered
-Software under this License. Except to the extent prohibited by statute
-or regulation, such description must be sufficiently detailed for a
-recipient of ordinary skill to be able to understand it.
-
-5. Termination
---------------
-
-5.1. The rights granted under this License will terminate automatically
-if You fail to comply with any of its terms. However, if You become
-compliant, then the rights granted under this License from a particular
-Contributor are reinstated (a) provisionally, unless and until such
-Contributor explicitly and finally terminates Your grants, and (b) on an
-ongoing basis, if such Contributor fails to notify You of the
-non-compliance by some reasonable means prior to 60 days after You have
-come back into compliance. Moreover, Your grants from a particular
-Contributor are reinstated on an ongoing basis if such Contributor
-notifies You of the non-compliance by some reasonable means, this is the
-first time You have received notice of non-compliance with this License
-from such Contributor, and You become compliant prior to 30 days after
-Your receipt of the notice.
-
-5.2. If You initiate litigation against any entity by asserting a patent
-infringement claim (excluding declaratory judgment actions,
-counter-claims, and cross-claims) alleging that a Contributor Version
-directly or indirectly infringes any patent, then the rights granted to
-You by any and all Contributors for the Covered Software under Section
-2.1 of this License shall terminate.
-
-5.3. In the event of termination under Sections 5.1 or 5.2 above, all
-end user license agreements (excluding distributors and resellers) which
-have been validly granted by You or Your distributors under this License
-prior to termination shall survive termination.
-
-************************************************************************
-* *
-* 6. Disclaimer of Warranty *
-* ------------------------- *
-* *
-* Covered Software is provided under this License on an "as is" *
-* basis, without warranty of any kind, either expressed, implied, or *
-* statutory, including, without limitation, warranties that the *
-* Covered Software is free of defects, merchantable, fit for a *
-* particular purpose or non-infringing. The entire risk as to the *
-* quality and performance of the Covered Software is with You. *
-* Should any Covered Software prove defective in any respect, You *
-* (not any Contributor) assume the cost of any necessary servicing, *
-* repair, or correction. This disclaimer of warranty constitutes an *
-* essential part of this License. No use of any Covered Software is *
-* authorized under this License except under this disclaimer. *
-* *
-************************************************************************
-
-************************************************************************
-* *
-* 7. Limitation of Liability *
-* -------------------------- *
-* *
-* Under no circumstances and under no legal theory, whether tort *
-* (including negligence), contract, or otherwise, shall any *
-* Contributor, or anyone who distributes Covered Software as *
-* permitted above, be liable to You for any direct, indirect, *
-* special, incidental, or consequential damages of any character *
-* including, without limitation, damages for lost profits, loss of *
-* goodwill, work stoppage, computer failure or malfunction, or any *
-* and all other commercial damages or losses, even if such party *
-* shall have been informed of the possibility of such damages. This *
-* limitation of liability shall not apply to liability for death or *
-* personal injury resulting from such party's negligence to the *
-* extent applicable law prohibits such limitation. Some *
-* jurisdictions do not allow the exclusion or limitation of *
-* incidental or consequential damages, so this exclusion and *
-* limitation may not apply to You. *
-* *
-************************************************************************
-
-8. Litigation
--------------
-
-Any litigation relating to this License may be brought only in the
-courts of a jurisdiction where the defendant maintains its principal
-place of business and such litigation shall be governed by laws of that
-jurisdiction, without reference to its conflict-of-law provisions.
-Nothing in this Section shall prevent a party's ability to bring
-cross-claims or counter-claims.
-
-9. Miscellaneous
-----------------
-
-This License represents the complete agreement concerning the subject
-matter hereof. If any provision of this License is held to be
-unenforceable, such provision shall be reformed only to the extent
-necessary to make it enforceable. Any law or regulation which provides
-that the language of a contract shall be construed against the drafter
-shall not be used to construe this License against a Contributor.
-
-10. Versions of the License
----------------------------
-
-10.1. New Versions
-
-Mozilla Foundation is the license steward. Except as provided in Section
-10.3, no one other than the license steward has the right to modify or
-publish new versions of this License. Each version will be given a
-distinguishing version number.
-
-10.2. Effect of New Versions
-
-You may distribute the Covered Software under the terms of the version
-of the License under which You originally received the Covered Software,
-or under the terms of any subsequent version published by the license
-steward.
-
-10.3. Modified Versions
-
-If you create software not governed by this License, and you want to
-create a new license for such software, you may create and use a
-modified version of this License if you rename the license and remove
-any references to the name of the license steward (except to note that
-such modified license differs from this License).
-
-10.4. Distributing Source Code Form that is Incompatible With Secondary
-Licenses
-
-If You choose to distribute Source Code Form that is Incompatible With
-Secondary Licenses under the terms of this version of the License, the
-notice described in Exhibit B of this License must be attached.
-
-Exhibit A - Source Code Form License Notice
--------------------------------------------
-
- 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/.
-
-If it is not possible or desirable to put the notice in a particular
-file, then You may include the notice in a location (such as a LICENSE
-file in a relevant directory) where a recipient would be likely to look
-for such a notice.
-
-You may add additional accurate notices of copyright ownership.
-
-Exhibit B - "Incompatible With Secondary Licenses" Notice
----------------------------------------------------------
-
- This Source Code Form is "Incompatible With Secondary Licenses", as
- defined by the Mozilla Public License, v. 2.0.
deleted file mode 100644
--- a/third_party/rust/webdriver/README.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# webdriver Rust library [![Crate version](https://img.shields.io/crates/v/webdriver.svg)](https://crates.io/crates/webdriver) [![Documentation](https://docs.rs/webdriver/badge.svg)](https://docs.rs/webdriver/) [![Build status](https://travis-ci.org/mozilla/webdriver-rust.svg?branch=master)](https://travis-ci.org/mozilla/webdriver-rust)
-
-As of right now this is an implementation
-for the server side of the WebDriver API in Rust,
-not the client side.
deleted file mode 100644
--- a/third_party/rust/webdriver/src/capabilities.rs
+++ /dev/null
@@ -1,520 +0,0 @@
-use command::Parameters;
-use error::{ErrorStatus, WebDriverError, WebDriverResult};
-use rustc_serialize::json::{Json, ToJson};
-use std::collections::BTreeMap;
-use url::Url;
-
-pub type Capabilities = BTreeMap<String, Json>;
-
-/// Trait for objects that can be used to inspect browser capabilities
-///
-/// The main methods in this trait are called with a Capabilites object
-/// resulting from a full set of potential capabilites for the session.
-/// Given those Capabilities they return a property of the browser instance
-/// that would be initiated. In many cases this will be independent of the
-/// input, but in the case of e.g. browser version, it might depend on a
-/// path to the binary provided as a capability.
-pub trait BrowserCapabilities {
- /// Set up the Capabilites object
- ///
- /// Typically used to create any internal caches
- fn init(&mut self, &Capabilities);
-
- /// Name of the browser
- fn browser_name(&mut self, &Capabilities) -> WebDriverResult<Option<String>>;
- /// Version number of the browser
- fn browser_version(&mut self, &Capabilities) -> WebDriverResult<Option<String>>;
- /// Compare actual browser version to that provided in a version specifier
- ///
- /// Parameters are the actual browser version and the comparison string,
- /// respectively. The format of the comparison string is implementation-defined.
- fn compare_browser_version(&mut self, version: &str, comparison: &str) -> WebDriverResult<bool>;
- /// Name of the platform/OS
- fn platform_name(&mut self, &Capabilities) -> WebDriverResult<Option<String>>;
- /// Whether insecure certificates are supported
- fn accept_insecure_certs(&mut self, &Capabilities) -> WebDriverResult<bool>;
-
- fn accept_proxy(&mut self, proxy_settings: &BTreeMap<String, Json>, &Capabilities) -> WebDriverResult<bool>;
-
- /// Type check custom properties
- ///
- /// Check that custom properties containing ":" have the correct data types.
- /// Properties that are unrecognised must be ignored i.e. return without
- /// error.
- fn validate_custom(&self, name: &str, value: &Json) -> WebDriverResult<()>;
- /// Check if custom properties are accepted capabilites
- ///
- /// Check that custom properties containing ":" are compatible with
- /// the implementation.
- fn accept_custom(&mut self, name: &str, value: &Json, merged: &Capabilities) -> WebDriverResult<bool>;
-}
-
-/// Trait to abstract over various version of the new session parameters
-///
-/// This trait is expected to be implemented on objects holding the capabilities
-/// from a new session command.
-pub trait CapabilitiesMatching {
- /// Match the BrowserCapabilities against some candidate capabilites
- ///
- /// Takes a BrowserCapabilites object and returns a set of capabilites that
- /// are valid for that browser, if any, or None if there are no matching
- /// capabilities.
- fn match_browser<T: BrowserCapabilities>(&self, browser_capabilities: &mut T)
- -> WebDriverResult<Option<Capabilities>>;
-}
-
-#[derive(Debug, PartialEq)]
-pub struct SpecNewSessionParameters {
- pub alwaysMatch: Capabilities,
- pub firstMatch: Vec<Capabilities>,
-}
-
-impl SpecNewSessionParameters {
- fn validate<T: BrowserCapabilities>(&self,
- mut capabilities: Capabilities,
- browser_capabilities: &T) -> WebDriverResult<Capabilities> {
- // Filter out entries with the value `null`
- let null_entries = capabilities
- .iter()
- .filter(|&(_, ref value)| **value == Json::Null)
- .map(|(k, _)| k.clone())
- .collect::<Vec<String>>();
- for key in null_entries {
- capabilities.remove(&key);
- }
-
- for (key, value) in capabilities.iter() {
- match &**key {
- "acceptInsecureCerts" => if !value.is_boolean() {
- return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "acceptInsecureCerts was not a boolean"))
- },
- x @ "browserName" |
- x @ "browserVersion" |
- x @ "platformName" => if !value.is_string() {
- return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- format!("{} was not a boolean", x)))
- },
- "pageLoadStrategy" => {
- try!(SpecNewSessionParameters::validate_page_load_strategy(value))
- }
- "proxy" => {
- try!(SpecNewSessionParameters::validate_proxy(value))
- },
- "timeouts" => {
- try!(SpecNewSessionParameters::validate_timeouts(value))
- },
- "unhandledPromptBehavior" => {
- try!(SpecNewSessionParameters::validate_unhandled_prompt_behaviour(value))
- }
- x => {
- if !x.contains(":") {
- return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- format!("{} was not a the name of a known capability or a valid extension capability", x)))
- } else {
- try!(browser_capabilities.validate_custom(x, value));
- }
- }
- }
- }
- Ok(capabilities)
- }
-
- fn validate_page_load_strategy(value: &Json) -> WebDriverResult<()> {
- match value {
- &Json::String(ref x) => {
- match &**x {
- "normal" |
- "eager" |
- "none" => {},
- x => {
- return Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- format!("\"{}\" not a valid page load strategy", x)))
- }
- }
- }
- _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "pageLoadStrategy was not a string"))
- }
- Ok(())
- }
-
- fn validate_proxy(proxy_value: &Json) -> WebDriverResult<()> {
- let obj = try_opt!(proxy_value.as_object(),
- ErrorStatus::InvalidArgument,
- "proxy was not an object");
- for (key, value) in obj.iter() {
- match &**key {
- "proxyType" => match value.as_string() {
- Some("pac") |
- Some("direct") |
- Some("autodetect") |
- Some("system") |
- Some("manual") => {},
- Some(x) => return Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- format!("{} was not a valid proxyType value", x))),
- None => return Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "proxyType value was not a string")),
- },
- "proxyAutoconfigUrl" => match value.as_string() {
- Some(x) => {
- try!(Url::parse(x).or(Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "proxyAutoconfigUrl was not a valid url"))));
- },
- None => return Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "proxyAutoconfigUrl was not a string"
- ))
- },
- "ftpProxy" => try!(SpecNewSessionParameters::validate_host(value)),
- "httpProxy" => try!(SpecNewSessionParameters::validate_host(value)),
- "sslProxy" => try!(SpecNewSessionParameters::validate_host(value)),
- "socksProxy" => try!(SpecNewSessionParameters::validate_host(value)),
- "socksVersion" => if !value.is_number() {
- return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "socksVersion was not a number"))
- },
- "socksUsername" => if !value.is_string() {
- return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "socksUsername was not a string"))
- },
- "socksPassword" => if !value.is_string() {
- return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "socksPassword was not a string"))
- },
- x => return Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- format!("{} was not a valid proxy configuration capability", x)))
- }
- }
- Ok(())
- }
-
- /// Validate whether a named capability is JSON value is a string containing a host
- /// and possible port
- fn validate_host(value: &Json) -> WebDriverResult<()> {
- match value.as_string() {
- Some(host) => {
- if host.contains("://") {
- return Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- format!("{} contains a scheme", host)));
- }
-
- // Temporarily add a scheme so the host can be parsed as URL
- let s = String::from(format!("http://{}", host));
- let url = try!(Url::parse(s.as_str()).or(Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- format!("{} is not a valid host", host)))));
-
- if url.username() != "" ||
- url.password() != None ||
- url.path() != "/" ||
- url.query() != None ||
- url.fragment() != None {
- return Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- format!("{} was not of the form host[:port]", host)));
- }
- },
- None => return Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- format!("{} was not a string", value)
- ))
- }
- Ok(())
- }
-
- fn validate_timeouts(value: &Json) -> WebDriverResult<()> {
- let obj = try_opt!(value.as_object(),
- ErrorStatus::InvalidArgument,
- "timeouts capability was not an object");
- for (key, value) in obj.iter() {
- match &**key {
- x @ "script" |
- x @ "pageLoad" |
- x @ "implicit" => {
- let timeout = try_opt!(value.as_i64(),
- ErrorStatus::InvalidArgument,
- format!("{} timeouts value was not an integer", x));
- if timeout < 0 {
- return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- format!("{} timeouts value was negative", x)))
- }
- },
- x => return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- format!("{} was not a valid timeouts capability", x)))
- }
- }
- Ok(())
- }
-
- fn validate_unhandled_prompt_behaviour(value: &Json) -> WebDriverResult<()> {
- let behaviour = try_opt!(value.as_string(),
- ErrorStatus::InvalidArgument,
- "unhandledPromptBehavior capability was not a string");
- match behaviour {
- "dismiss" |
- "accept" => {},
- x => return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- format!("{} was not a valid unhandledPromptBehavior value", x))) }
- Ok(())
- }
-}
-
-impl Parameters for SpecNewSessionParameters {
- fn from_json(body: &Json) -> WebDriverResult<SpecNewSessionParameters> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::UnknownError,
- "Message body was not an object");
-
- let capabilities = try_opt!(
- try_opt!(data.get("capabilities"),
- ErrorStatus::InvalidArgument,
- "Missing 'capabilities' parameter").as_object(),
- ErrorStatus::InvalidArgument,
- "'capabilities' parameter is not an object");
-
- let default_always_match = Json::Object(Capabilities::new());
- let always_match = try_opt!(capabilities.get("alwaysMatch")
- .unwrap_or(&default_always_match)
- .as_object(),
- ErrorStatus::InvalidArgument,
- "'alwaysMatch' parameter is not an object");
- let default_first_matches = Json::Array(vec![]);
- let first_matches = try!(
- try_opt!(capabilities.get("firstMatch")
- .unwrap_or(&default_first_matches)
- .as_array(),
- ErrorStatus::InvalidArgument,
- "'firstMatch' parameter is not an array")
- .iter()
- .map(|x| x.as_object()
- .map(|x| x.clone())
- .ok_or(WebDriverError::new(ErrorStatus::InvalidArgument,
- "'firstMatch' entry is not an object")))
- .collect::<WebDriverResult<Vec<Capabilities>>>());
-
- return Ok(SpecNewSessionParameters {
- alwaysMatch: always_match.clone(),
- firstMatch: first_matches
- });
- }
-}
-
-impl ToJson for SpecNewSessionParameters {
- fn to_json(&self) -> Json {
- let mut body = BTreeMap::new();
- let mut capabilities = BTreeMap::new();
- capabilities.insert("alwaysMatch".into(), self.alwaysMatch.to_json());
- capabilities.insert("firstMatch".into(), self.firstMatch.to_json());
- body.insert("capabilities".into(), capabilities.to_json());
- Json::Object(body)
- }
-}
-
-impl CapabilitiesMatching for SpecNewSessionParameters {
- fn match_browser<T: BrowserCapabilities>(&self, browser_capabilities: &mut T)
- -> WebDriverResult<Option<Capabilities>> {
- let default = vec![BTreeMap::new()];
- let capabilities_list = if self.firstMatch.len() > 0 {
- &self.firstMatch
- } else {
- &default
- };
-
- let merged_capabilities = try!(capabilities_list
- .iter()
- .map(|first_match_entry| {
- if first_match_entry.keys().any(|k| {
- self.alwaysMatch.contains_key(k)
- }) {
- return Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "'firstMatch' key shadowed a value in 'alwaysMatch'"));
- }
- let mut merged = self.alwaysMatch.clone();
- merged.append(&mut first_match_entry.clone());
- Ok(merged)
- })
- .map(|merged| merged.and_then(|x| self.validate(x, browser_capabilities)))
- .collect::<WebDriverResult<Vec<Capabilities>>>());
-
- let selected = merged_capabilities
- .iter()
- .filter_map(|merged| {
- browser_capabilities.init(merged);
-
- for (key, value) in merged.iter() {
- match &**key {
- "browserName" => {
- let browserValue = browser_capabilities
- .browser_name(merged)
- .ok()
- .and_then(|x| x);
-
- if value.as_string() != browserValue.as_ref().map(|x| &**x) {
- return None;
- }
- },
- "browserVersion" => {
- let browserValue = browser_capabilities
- .browser_version(merged)
- .ok()
- .and_then(|x| x);
- // We already validated this was a string
- let version_cond = value.as_string().unwrap_or("");
- if let Some(version) = browserValue {
- if !browser_capabilities
- .compare_browser_version(&*version, version_cond)
- .unwrap_or(false) {
- return None;
- }
- } else {
- return None
- }
- },
- "platformName" => {
- let browserValue = browser_capabilities
- .platform_name(merged)
- .ok()
- .and_then(|x| x);
- if value.as_string() != browserValue.as_ref().map(|x| &**x) {
- return None;
- }
- }
- "acceptInsecureCerts" => {
- if value.as_boolean().unwrap_or(false) &&
- !browser_capabilities
- .accept_insecure_certs(merged)
- .unwrap_or(false) {
- return None;
- }
- },
- "proxy" => {
- let default = BTreeMap::new();
- let proxy = value.as_object().unwrap_or(&default);
- if !browser_capabilities.accept_proxy(&proxy,
- merged)
- .unwrap_or(false) {
- return None
- }
- },
- name => {
- if name.contains(":") {
- if !browser_capabilities
- .accept_custom(name, value, merged)
- .unwrap_or(false) {
- return None
- }
- } else {
- // Accept the capability
- }
- }
- }
- }
-
- return Some(merged)
- })
- .next()
- .map(|x| x.clone());
- Ok(selected)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct LegacyNewSessionParameters {
- pub desired: Capabilities,
- pub required: Capabilities,
-}
-
-impl CapabilitiesMatching for LegacyNewSessionParameters {
- fn match_browser<T: BrowserCapabilities>(&self, browser_capabilities: &mut T)
- -> WebDriverResult<Option<Capabilities>> {
- /* For now don't do anything much, just merge the
- desired and required and return the merged list. */
-
- let mut capabilities: Capabilities = BTreeMap::new();
- self.required.iter()
- .chain(self.desired.iter())
- .fold(&mut capabilities,
- |mut caps, (key, value)| {
- if !caps.contains_key(key) {
- caps.insert(key.clone(), value.clone());
- }
- caps});
- browser_capabilities.init(&capabilities);
- Ok(Some(capabilities))
- }
-}
-
-impl Parameters for LegacyNewSessionParameters {
- fn from_json(body: &Json) -> WebDriverResult<LegacyNewSessionParameters> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::UnknownError,
- "Message body was not an object");
-
- let desired_capabilities =
- if let Some(capabilities) = data.get("desiredCapabilities") {
- try_opt!(capabilities.as_object(),
- ErrorStatus::InvalidArgument,
- "'desiredCapabilities' parameter is not an object").clone()
- } else {
- BTreeMap::new()
- };
-
- let required_capabilities =
- if let Some(capabilities) = data.get("requiredCapabilities") {
- try_opt!(capabilities.as_object(),
- ErrorStatus::InvalidArgument,
- "'requiredCapabilities' parameter is not an object").clone()
- } else {
- BTreeMap::new()
- };
-
- Ok(LegacyNewSessionParameters {
- desired: desired_capabilities,
- required: required_capabilities
- })
- }
-}
-
-impl ToJson for LegacyNewSessionParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("desiredCapabilities".to_owned(), self.desired.to_json());
- data.insert("requiredCapabilities".to_owned(), self.required.to_json());
- Json::Object(data)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use rustc_serialize::json::Json;
- use super::{WebDriverResult, SpecNewSessionParameters};
-
- fn validate_host(value: &str) -> WebDriverResult<()> {
- SpecNewSessionParameters::validate_host(&Json::String(value.into()))
- }
-
- #[test]
- fn test_validate_host() {
- validate_host("127.0.0.1").unwrap();
- validate_host("127.0.0.1:").unwrap();
- validate_host("127.0.0.1:3128").unwrap();
- validate_host("[2001:db8::1]").unwrap();
- validate_host("[2001:db8::1]:3128").unwrap();
- validate_host("localhost").unwrap();
- validate_host("localhost:3128").unwrap();
- validate_host("example.org").unwrap();
- validate_host("example.org:3128").unwrap();
-
- assert!(validate_host("http://example.org").is_err()); // existing scheme
- assert!(validate_host("example.org:-1").is_err()); // invalid port
- assert!(validate_host("2001:db8::1").is_err()); // missing brackets
- }
-}
deleted file mode 100644
--- a/third_party/rust/webdriver/src/command.rs
+++ /dev/null
@@ -1,1743 +0,0 @@
-use capabilities::{SpecNewSessionParameters, LegacyNewSessionParameters,
- CapabilitiesMatching, BrowserCapabilities, Capabilities};
-use common::{Date, Nullable, WebElement, FrameId, LocatorStrategy};
-use error::{WebDriverResult, WebDriverError, ErrorStatus};
-use httpapi::{Route, WebDriverExtensionRoute, VoidWebDriverExtensionRoute};
-use regex::Captures;
-use rustc_serialize::json;
-use rustc_serialize::json::{ToJson, Json};
-use std::collections::BTreeMap;
-use std::default::Default;
-
-#[derive(Debug, PartialEq)]
-pub enum WebDriverCommand<T: WebDriverExtensionCommand> {
- NewSession(NewSessionParameters),
- DeleteSession,
- Get(GetParameters),
- GetCurrentUrl,
- GoBack,
- GoForward,
- Refresh,
- GetTitle,
- GetPageSource,
- GetWindowHandle,
- GetWindowHandles,
- CloseWindow,
- GetWindowRect,
- SetWindowRect(WindowRectParameters),
- MinimizeWindow,
- MaximizeWindow,
- FullscreenWindow,
- SwitchToWindow(SwitchToWindowParameters),
- SwitchToFrame(SwitchToFrameParameters),
- SwitchToParentFrame,
- FindElement(LocatorParameters),
- FindElements(LocatorParameters),
- FindElementElement(WebElement, LocatorParameters),
- FindElementElements(WebElement, LocatorParameters),
- GetActiveElement,
- IsDisplayed(WebElement),
- IsSelected(WebElement),
- GetElementAttribute(WebElement, String),
- GetElementProperty(WebElement, String),
- GetCSSValue(WebElement, String),
- GetElementText(WebElement),
- GetElementTagName(WebElement),
- GetElementRect(WebElement),
- IsEnabled(WebElement),
- ExecuteScript(JavascriptCommandParameters),
- ExecuteAsyncScript(JavascriptCommandParameters),
- GetCookies,
- GetNamedCookie(String),
- AddCookie(AddCookieParameters),
- DeleteCookies,
- DeleteCookie(String),
- GetTimeouts,
- SetTimeouts(TimeoutsParameters),
- ElementClick(WebElement),
- ElementTap(WebElement),
- ElementClear(WebElement),
- ElementSendKeys(WebElement, SendKeysParameters),
- PerformActions(ActionsParameters),
- ReleaseActions,
- DismissAlert,
- AcceptAlert,
- GetAlertText,
- SendAlertText(SendKeysParameters),
- TakeScreenshot,
- TakeElementScreenshot(WebElement),
- Status,
- Extension(T)
-}
-
-pub trait WebDriverExtensionCommand : Clone + Send + PartialEq {
- fn parameters_json(&self) -> Option<Json>;
-}
-
-#[derive(Clone, Debug, PartialEq)]
-pub struct VoidWebDriverExtensionCommand;
-
-impl WebDriverExtensionCommand for VoidWebDriverExtensionCommand {
- fn parameters_json(&self) -> Option<Json> {
- panic!("No extensions implemented");
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct WebDriverMessage <U: WebDriverExtensionRoute=VoidWebDriverExtensionRoute> {
- pub session_id: Option<String>,
- pub command: WebDriverCommand<U::Command>,
-}
-
-impl<U: WebDriverExtensionRoute> WebDriverMessage<U> {
- pub fn new(session_id: Option<String>,
- command: WebDriverCommand<U::Command>)
- -> WebDriverMessage<U> {
- WebDriverMessage {
- session_id: session_id,
- command: command,
- }
- }
-
- pub fn from_http(match_type: Route<U>,
- params: &Captures,
- raw_body: &str,
- requires_body: bool)
- -> WebDriverResult<WebDriverMessage<U>> {
- let session_id = WebDriverMessage::<U>::get_session_id(params);
- let body_data = try!(WebDriverMessage::<U>::decode_body(raw_body, requires_body));
-
- let command = match match_type {
- Route::NewSession => {
- let parameters: NewSessionParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::NewSession(parameters)
- },
- Route::DeleteSession => WebDriverCommand::DeleteSession,
- Route::Get => {
- let parameters: GetParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::Get(parameters)
- },
- Route::GetCurrentUrl => WebDriverCommand::GetCurrentUrl,
- Route::GoBack => WebDriverCommand::GoBack,
- Route::GoForward => WebDriverCommand::GoForward,
- Route::Refresh => WebDriverCommand::Refresh,
- Route::GetTitle => WebDriverCommand::GetTitle,
- Route::GetPageSource => WebDriverCommand::GetPageSource,
- Route::GetWindowHandle => WebDriverCommand::GetWindowHandle,
- Route::GetWindowHandles => WebDriverCommand::GetWindowHandles,
- Route::CloseWindow => WebDriverCommand::CloseWindow,
- Route::GetTimeouts => WebDriverCommand::GetTimeouts,
- Route::SetTimeouts => {
- let parameters: TimeoutsParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::SetTimeouts(parameters)
- },
- Route::GetWindowRect | Route::GetWindowPosition | Route::GetWindowSize => WebDriverCommand::GetWindowRect,
- Route::SetWindowRect | Route::SetWindowPosition | Route::SetWindowSize => {
- let parameters: WindowRectParameters = Parameters::from_json(&body_data)?;
- WebDriverCommand::SetWindowRect(parameters)
- },
- Route::MinimizeWindow => WebDriverCommand::MinimizeWindow,
- Route::MaximizeWindow => WebDriverCommand::MaximizeWindow,
- Route::FullscreenWindow => WebDriverCommand::FullscreenWindow,
- Route::SwitchToWindow => {
- let parameters: SwitchToWindowParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::SwitchToWindow(parameters)
- }
- Route::SwitchToFrame => {
- let parameters: SwitchToFrameParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::SwitchToFrame(parameters)
- },
- Route::SwitchToParentFrame => WebDriverCommand::SwitchToParentFrame,
- Route::FindElement => {
- let parameters: LocatorParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::FindElement(parameters)
- },
- Route::FindElements => {
- let parameters: LocatorParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::FindElements(parameters)
- },
- Route::FindElementElement => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- let parameters: LocatorParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::FindElementElement(element, parameters)
- },
- Route::FindElementElements => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- let parameters: LocatorParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::FindElementElements(element, parameters)
- },
- Route::GetActiveElement => WebDriverCommand::GetActiveElement,
- Route::IsDisplayed => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- WebDriverCommand::IsDisplayed(element)
- },
- Route::IsSelected => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- WebDriverCommand::IsSelected(element)
- },
- Route::GetElementAttribute => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- let attr = try_opt!(params.name("name"),
- ErrorStatus::InvalidArgument,
- "Missing name parameter").as_str();
- WebDriverCommand::GetElementAttribute(element, attr.into())
- },
- Route::GetElementProperty => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- let property = try_opt!(params.name("name"),
- ErrorStatus::InvalidArgument,
- "Missing name parameter").as_str();
- WebDriverCommand::GetElementProperty(element, property.into())
- },
- Route::GetCSSValue => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- let property = try_opt!(params.name("propertyName"),
- ErrorStatus::InvalidArgument,
- "Missing propertyName parameter").as_str();
- WebDriverCommand::GetCSSValue(element, property.into())
- },
- Route::GetElementText => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- WebDriverCommand::GetElementText(element)
- },
- Route::GetElementTagName => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- WebDriverCommand::GetElementTagName(element)
- },
- Route::GetElementRect => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- WebDriverCommand::GetElementRect(element)
- },
- Route::IsEnabled => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- WebDriverCommand::IsEnabled(element)
- },
- Route::ElementClick => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- WebDriverCommand::ElementClick(element)
- },
- Route::ElementTap => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- WebDriverCommand::ElementTap(element)
- },
- Route::ElementClear => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- WebDriverCommand::ElementClear(element)
- },
- Route::ElementSendKeys => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- let parameters: SendKeysParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::ElementSendKeys(element, parameters)
- },
- Route::ExecuteScript => {
- let parameters: JavascriptCommandParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::ExecuteScript(parameters)
- },
- Route::ExecuteAsyncScript => {
- let parameters: JavascriptCommandParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::ExecuteAsyncScript(parameters)
- },
- Route::GetCookies => {
- WebDriverCommand::GetCookies
- },
- Route::GetNamedCookie => {
- let name = try_opt!(params.name("name"),
- ErrorStatus::InvalidArgument,
- "Missing 'name' parameter").as_str().into();
- WebDriverCommand::GetNamedCookie(name)
- },
- Route::AddCookie => {
- let parameters: AddCookieParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::AddCookie(parameters)
- },
- Route::DeleteCookies => {
- WebDriverCommand::DeleteCookies
- },
- Route::DeleteCookie => {
- let name = try_opt!(params.name("name"),
- ErrorStatus::InvalidArgument,
- "Missing name parameter").as_str().into();
- WebDriverCommand::DeleteCookie(name)
- },
- Route::PerformActions => {
- let parameters: ActionsParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::PerformActions(parameters)
- },
- Route::ReleaseActions => {
- WebDriverCommand::ReleaseActions
- },
- Route::DismissAlert => {
- WebDriverCommand::DismissAlert
- },
- Route::AcceptAlert => {
- WebDriverCommand::AcceptAlert
- },
- Route::GetAlertText => {
- WebDriverCommand::GetAlertText
- },
- Route::SendAlertText => {
- let parameters: SendKeysParameters = try!(Parameters::from_json(&body_data));
- WebDriverCommand::SendAlertText(parameters)
- },
- Route::TakeScreenshot => WebDriverCommand::TakeScreenshot,
- Route::TakeElementScreenshot => {
- let element_id = try_opt!(params.name("elementId"),
- ErrorStatus::InvalidArgument,
- "Missing elementId parameter");
- let element = WebElement::new(element_id.as_str().into());
- WebDriverCommand::TakeElementScreenshot(element)
- },
- Route::Status => WebDriverCommand::Status,
- Route::Extension(ref extension) => {
- try!(extension.command(params, &body_data))
- }
- };
- Ok(WebDriverMessage::new(session_id, command))
- }
-
- fn get_session_id(params: &Captures) -> Option<String> {
- params.name("sessionId").map(|x| x.as_str().into())
- }
-
- fn decode_body(body: &str, requires_body: bool) -> WebDriverResult<Json> {
- if requires_body {
- match Json::from_str(body) {
- Ok(x @ Json::Object(_)) => Ok(x),
- Ok(_) => {
- Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "Body was not a JSON Object"))
- }
- Err(json::ParserError::SyntaxError(_, line, col)) => {
- let msg = format!("Failed to decode request as JSON: {}", body);
- let stack = format!("Syntax error at :{}:{}", line, col);
- Err(WebDriverError::new_with_stack(ErrorStatus::InvalidArgument, msg, stack))
- }
- Err(json::ParserError::IoError(e)) => {
- Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- format!("I/O error whilst decoding body: {}", e)))
- }
- }
- } else {
- Ok(Json::Null)
- }
- }
-}
-
-impl <U:WebDriverExtensionRoute> ToJson for WebDriverMessage<U> {
- fn to_json(&self) -> Json {
- let parameters = match self.command {
- WebDriverCommand::AcceptAlert |
- WebDriverCommand::CloseWindow |
- WebDriverCommand::ReleaseActions |
- WebDriverCommand::DeleteCookie(_) |
- WebDriverCommand::DeleteCookies |
- WebDriverCommand::DeleteSession |
- WebDriverCommand::DismissAlert |
- WebDriverCommand::ElementClear(_) |
- WebDriverCommand::ElementClick(_) |
- WebDriverCommand::ElementTap(_) |
- WebDriverCommand::GetActiveElement |
- WebDriverCommand::GetAlertText |
- WebDriverCommand::GetNamedCookie(_) |
- WebDriverCommand::GetCookies |
- WebDriverCommand::GetCSSValue(_, _) |
- WebDriverCommand::GetCurrentUrl |
- WebDriverCommand::GetElementAttribute(_, _) |
- WebDriverCommand::GetElementProperty(_, _) |
- WebDriverCommand::GetElementRect(_) |
- WebDriverCommand::GetElementTagName(_) |
- WebDriverCommand::GetElementText(_) |
- WebDriverCommand::GetPageSource |
- WebDriverCommand::GetTimeouts |
- WebDriverCommand::GetTitle |
- WebDriverCommand::GetWindowHandle |
- WebDriverCommand::GetWindowHandles |
- WebDriverCommand::GetWindowRect |
- WebDriverCommand::GoBack |
- WebDriverCommand::GoForward |
- WebDriverCommand::IsDisplayed(_) |
- WebDriverCommand::IsEnabled(_) |
- WebDriverCommand::IsSelected(_) |
- WebDriverCommand::MinimizeWindow |
- WebDriverCommand::MaximizeWindow |
- WebDriverCommand::FullscreenWindow |
- WebDriverCommand::NewSession(_) |
- WebDriverCommand::Refresh |
- WebDriverCommand::Status |
- WebDriverCommand::SwitchToParentFrame |
- WebDriverCommand::TakeElementScreenshot(_) |
- WebDriverCommand::TakeScreenshot => {
- None
- },
-
- WebDriverCommand::AddCookie(ref x) => Some(x.to_json()),
- WebDriverCommand::ElementSendKeys(_, ref x) => Some(x.to_json()),
- WebDriverCommand::ExecuteAsyncScript(ref x) |
- WebDriverCommand::ExecuteScript(ref x) => Some(x.to_json()),
- WebDriverCommand::FindElementElement(_, ref x) => Some(x.to_json()),
- WebDriverCommand::FindElementElements(_, ref x) => Some(x.to_json()),
- WebDriverCommand::FindElement(ref x) => Some(x.to_json()),
- WebDriverCommand::FindElements(ref x) => Some(x.to_json()),
- WebDriverCommand::Get(ref x) => Some(x.to_json()),
- WebDriverCommand::PerformActions(ref x) => Some(x.to_json()),
- WebDriverCommand::SendAlertText(ref x) => Some(x.to_json()),
- WebDriverCommand::SetTimeouts(ref x) => Some(x.to_json()),
- WebDriverCommand::SetWindowRect(ref x) => Some(x.to_json()),
- WebDriverCommand::SwitchToFrame(ref x) => Some(x.to_json()),
- WebDriverCommand::SwitchToWindow(ref x) => Some(x.to_json()),
- WebDriverCommand::Extension(ref x) => x.parameters_json(),
- };
-
- let mut data = BTreeMap::new();
- if let Some(parameters) = parameters {
- data.insert("parameters".to_string(), parameters);
- }
- Json::Object(data)
- }
-}
-
-pub trait Parameters: Sized {
- fn from_json(body: &Json) -> WebDriverResult<Self>;
-}
-
-/// Wrapper around the two supported variants of new session paramters
-///
-/// The Spec variant is used for storing spec-compliant parameters whereas
-/// the legacy variant is used to store desiredCapabilities/requiredCapabilities
-/// parameters, and is intended to minimise breakage as we transition users to
-/// the spec design.
-#[derive(Debug, PartialEq)]
-pub enum NewSessionParameters {
- Spec(SpecNewSessionParameters),
- Legacy(LegacyNewSessionParameters),
-}
-
-impl Parameters for NewSessionParameters {
- fn from_json(body: &Json) -> WebDriverResult<NewSessionParameters> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::UnknownError,
- "Message body was not an object");
- if data.get("capabilities").is_some() {
- Ok(NewSessionParameters::Spec(try!(SpecNewSessionParameters::from_json(body))))
- } else {
- Ok(NewSessionParameters::Legacy(try!(LegacyNewSessionParameters::from_json(body))))
- }
- }
-}
-
-impl ToJson for NewSessionParameters {
- fn to_json(&self) -> Json {
- match self {
- &NewSessionParameters::Spec(ref x) => x.to_json(),
- &NewSessionParameters::Legacy(ref x) => x.to_json()
- }
- }
-}
-
-impl CapabilitiesMatching for NewSessionParameters {
- fn match_browser<T: BrowserCapabilities>(&self, browser_capabilities: &mut T)
- -> WebDriverResult<Option<Capabilities>> {
- match self {
- &NewSessionParameters::Spec(ref x) => x.match_browser(browser_capabilities),
- &NewSessionParameters::Legacy(ref x) => x.match_browser(browser_capabilities)
- }
- }
-}
-
-
-#[derive(Debug, PartialEq)]
-pub struct GetParameters {
- pub url: String
-}
-
-impl Parameters for GetParameters {
- fn from_json(body: &Json) -> WebDriverResult<GetParameters> {
- let data = try_opt!(body.as_object(), ErrorStatus::UnknownError,
- "Message body was not an object");
- let url = try_opt!(
- try_opt!(data.get("url"),
- ErrorStatus::InvalidArgument,
- "Missing 'url' parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "'url' not a string");
- Ok(GetParameters {
- url: url.to_string()
- })
- }
-}
-
-impl ToJson for GetParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("url".to_string(), self.url.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct TimeoutsParameters {
- pub script: Option<u64>,
- pub page_load: Option<u64>,
- pub implicit: Option<u64>,
-}
-
-impl Parameters for TimeoutsParameters {
- fn from_json(body: &Json) -> WebDriverResult<TimeoutsParameters> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::UnknownError,
- "Message body was not an object");
-
- let script = match data.get("script") {
- Some(json) => {
- Some(try_opt!(json.as_u64(),
- ErrorStatus::InvalidArgument,
- "Script timeout duration was not a signed integer"))
- }
- None => None,
- };
-
- let page_load = match data.get("pageLoad") {
- Some(json) => {
- Some(try_opt!(json.as_u64(),
- ErrorStatus::InvalidArgument,
- "Page load timeout duration was not a signed integer"))
- }
- None => None,
- };
-
- let implicit = match data.get("implicit") {
- Some(json) => {
- Some(try_opt!(json.as_u64(),
- ErrorStatus::InvalidArgument,
- "Implicit timeout duration was not a signed integer"))
- }
- None => None,
- };
-
- Ok(TimeoutsParameters {
- script: script,
- page_load: page_load,
- implicit: implicit,
- })
- }
-}
-
-impl ToJson for TimeoutsParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- if let Some(ms) = self.script {
- data.insert("script".into(), ms.to_json());
- }
- if let Some(ms) = self.page_load {
- data.insert("pageLoad".into(), ms.to_json());
- }
- if let Some(ms) = self.implicit {
- data.insert("implicit".into(), ms.to_json());
- }
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct WindowRectParameters {
- pub x: Nullable<i64>,
- pub y: Nullable<i64>,
- pub width: Nullable<u64>,
- pub height: Nullable<u64>,
-}
-
-impl Parameters for WindowRectParameters {
- fn from_json(body: &Json) -> WebDriverResult<WindowRectParameters> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::UnknownError,
- "Message body was not an object");
-
- let x = match data.get("x") {
- Some(json) => {
- try!(Nullable::from_json(json, |n| {
- Ok((try_opt!(n.as_i64(),
- ErrorStatus::InvalidArgument,
- "'x' is not an integer")))
- }))
- }
- None => Nullable::Null,
- };
- let y = match data.get("y") {
- Some(json) => {
- try!(Nullable::from_json(json, |n| {
- Ok((try_opt!(n.as_i64(),
- ErrorStatus::InvalidArgument,
- "'y' is not an integer")))
- }))
- }
- None => Nullable::Null,
- };
- let width = match data.get("width") {
- Some(json) => {
- try!(Nullable::from_json(json, |n| {
- Ok((try_opt!(n.as_u64(),
- ErrorStatus::InvalidArgument,
- "'width' is not a positive integer")))
- }))
- }
- None => Nullable::Null,
- };
- let height = match data.get("height") {
- Some(json) => {
- try!(Nullable::from_json(json, |n| {
- Ok((try_opt!(n.as_u64(),
- ErrorStatus::InvalidArgument,
- "'height' is not a positive integer")))
- }))
- }
- None => Nullable::Null,
- };
-
- Ok(WindowRectParameters {
- x: x,
- y: y,
- width: width,
- height: height,
- })
- }
-}
-
-impl ToJson for WindowRectParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("x".to_string(), self.x.to_json());
- data.insert("y".to_string(), self.y.to_json());
- data.insert("width".to_string(), self.width.to_json());
- data.insert("height".to_string(), self.height.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct SwitchToWindowParameters {
- pub handle: String
-}
-
-impl Parameters for SwitchToWindowParameters {
- fn from_json(body: &Json) -> WebDriverResult<SwitchToWindowParameters> {
- let data = try_opt!(body.as_object(), ErrorStatus::UnknownError,
- "Message body was not an object");
- let handle = try_opt!(
- try_opt!(data.get("handle"),
- ErrorStatus::InvalidArgument,
- "Missing 'handle' parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "'handle' not a string");
- return Ok(SwitchToWindowParameters {
- handle: handle.to_string()
- })
- }
-}
-
-impl ToJson for SwitchToWindowParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("handle".to_string(), self.handle.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct LocatorParameters {
- pub using: LocatorStrategy,
- pub value: String
-}
-
-impl Parameters for LocatorParameters {
- fn from_json(body: &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 'value' parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "Could not convert using to string").to_string();
-
- return Ok(LocatorParameters {
- using: using,
- value: value
- })
- }
-}
-
-impl ToJson for LocatorParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("using".to_string(), self.using.to_json());
- data.insert("value".to_string(), self.value.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct SwitchToFrameParameters {
- pub id: FrameId
-}
-
-impl Parameters for SwitchToFrameParameters {
- fn from_json(body: &Json) -> WebDriverResult<SwitchToFrameParameters> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::UnknownError,
- "Message body was not an object");
- let id = try!(FrameId::from_json(try_opt!(data.get("id"),
- ErrorStatus::UnknownError,
- "Missing 'id' parameter")));
-
- Ok(SwitchToFrameParameters {
- id: id
- })
- }
-}
-
-impl ToJson for SwitchToFrameParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("id".to_string(), self.id.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct SendKeysParameters {
- pub text: String
-}
-
-impl Parameters for SendKeysParameters {
- fn from_json(body: &Json) -> WebDriverResult<SendKeysParameters> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::InvalidArgument,
- "Message body was not an object");
- let text = try_opt!(try_opt!(data.get("text"),
- ErrorStatus::InvalidArgument,
- "Missing 'text' parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "Could not convert 'text' to string");
-
- Ok(SendKeysParameters {
- text: text.into()
- })
- }
-}
-
-impl ToJson for SendKeysParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("value".to_string(), self.text.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct JavascriptCommandParameters {
- pub script: String,
- pub args: Nullable<Vec<Json>>
-}
-
-impl Parameters for JavascriptCommandParameters {
- fn from_json(body: &Json) -> WebDriverResult<JavascriptCommandParameters> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::InvalidArgument,
- "Message body was not an object");
-
- let args_json = try_opt!(data.get("args"),
- ErrorStatus::InvalidArgument,
- "Missing args parameter");
-
- let args = try!(Nullable::from_json(
- args_json,
- |x| {
- Ok((try_opt!(x.as_array(),
- 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::InvalidArgument,
- "Missing script parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "Failed to convert script to String");
- Ok(JavascriptCommandParameters {
- script: script.to_string(),
- args: args.clone()
- })
- }
-}
-
-impl ToJson for JavascriptCommandParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- //TODO: Wrap script so that it becomes marionette-compatible
- data.insert("script".to_string(), self.script.to_json());
- data.insert("args".to_string(), self.args.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct GetNamedCookieParameters {
- pub name: Nullable<String>,
-}
-
-impl Parameters for GetNamedCookieParameters {
- fn from_json(body: &Json) -> WebDriverResult<GetNamedCookieParameters> {
- 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,
- "Missing 'name' parameter");
- let name = try!(Nullable::from_json(name_json, |x| {
- Ok(try_opt!(x.as_string(),
- ErrorStatus::InvalidArgument,
- "Failed to convert name to string")
- .to_string())
- }));
- return Ok(GetNamedCookieParameters { name: name });
- }
-}
-
-impl ToJson for GetNamedCookieParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("name".to_string(), self.name.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct AddCookieParameters {
- pub name: String,
- pub value: String,
- pub path: Nullable<String>,
- pub domain: Nullable<String>,
- pub expiry: Nullable<Date>,
- pub secure: bool,
- pub httpOnly: bool
-}
-
-impl Parameters for AddCookieParameters {
- fn from_json(body: &Json) -> WebDriverResult<AddCookieParameters> {
- if !body.is_object() {
- return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "Message body was not an object"));
- }
-
- let data = try_opt!(body.find("cookie").and_then(|x| x.as_object()),
- ErrorStatus::UnableToSetCookie,
- "Cookie parameter not found or 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").to_string();
-
- let value = try_opt!(
- try_opt!(data.get("value"),
- ErrorStatus::InvalidArgument,
- "Missing 'value' parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "'value' is not a string").to_string();
-
- let path = match data.get("path") {
- Some(path_json) => {
- try!(Nullable::from_json(
- path_json,
- |x| {
- Ok(try_opt!(x.as_string(),
- ErrorStatus::InvalidArgument,
- "Failed to convert path to String").to_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::InvalidArgument,
- "Failed to convert domain to String").to_string())
- }))
- },
- None => Nullable::Null
- };
-
- 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::InvalidArgument,
- "Failed to convert expiry to Date")))
- }))
- },
- None => Nullable::Null
- };
-
- let secure = match data.get("secure") {
- Some(x) => try_opt!(x.as_boolean(),
- 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::InvalidArgument,
- "Failed to convert httpOnly to boolean"),
- None => false
- };
-
- return Ok(AddCookieParameters {
- name: name,
- value: value,
- path: path,
- domain: domain,
- expiry: expiry,
- secure: secure,
- httpOnly: http_only
- })
- }
-}
-
-impl ToJson for AddCookieParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::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("secure".to_string(), self.secure.to_json());
- data.insert("httpOnly".to_string(), self.httpOnly.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct TakeScreenshotParameters {
- pub element: Nullable<WebElement>
-}
-
-impl Parameters for TakeScreenshotParameters {
- fn from_json(body: &Json) -> WebDriverResult<TakeScreenshotParameters> {
- 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(
- 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 {
- let mut data = BTreeMap::new();
- data.insert("element".to_string(), self.element.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct ActionsParameters {
- pub actions: Vec<ActionSequence>
-}
-
-impl Parameters for ActionsParameters {
- fn from_json(body: &Json) -> WebDriverResult<ActionsParameters> {
- try_opt!(body.as_object(),
- ErrorStatus::InvalidArgument,
- "Message body was not an object");
- let actions = try_opt!(
- try_opt!(body.find("actions"),
- ErrorStatus::InvalidArgument,
- "No actions parameter found").as_array(),
- ErrorStatus::InvalidArgument,
- "Parameter 'actions' was not an array");
-
- let mut result = Vec::with_capacity(actions.len());
- for chain in actions.iter() {
- result.push(try!(ActionSequence::from_json(chain)));
- }
- Ok(ActionsParameters {
- actions: result
- })
- }
-}
-
-impl ToJson for ActionsParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("actions".to_owned(),
- self.actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>().to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct ActionSequence {
- pub id: Nullable<String>,
- pub actions: ActionsType
-}
-
-impl Parameters for ActionSequence {
- fn from_json(body: &Json) -> WebDriverResult<ActionSequence> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::InvalidArgument,
- "Actions chain was not an object");
-
- let type_name = try_opt!(try_opt!(data.get("type"),
- ErrorStatus::InvalidArgument,
- "Missing type parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "Parameter ;type' was not a string");
-
- let id = match data.get("id") {
- Some(x) => Some(try_opt!(x.as_string(),
- ErrorStatus::InvalidArgument,
- "Parameter 'id' was not a string").to_owned()),
- None => None
- };
-
-
- // Note that unlike the spec we get the pointer parameters in ActionsType::from_json
-
- let actions = match type_name {
- "none" | "key" | "pointer" => try!(ActionsType::from_json(&body)),
- _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "Invalid action type"))
- };
-
- Ok(ActionSequence {
- id: id.into(),
- actions: actions
- })
- }
-}
-
-impl ToJson for ActionSequence {
- fn to_json(&self) -> Json {
- let mut data: BTreeMap<String, Json> = BTreeMap::new();
- data.insert("id".into(), self.id.to_json());
- let (action_type, actions) = match self.actions {
- ActionsType::Null(ref actions) => {
- ("none",
- actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>())
- }
- ActionsType::Key(ref actions) => {
- ("key",
- actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>())
- }
- ActionsType::Pointer(ref parameters, ref actions) => {
- data.insert("parameters".into(), parameters.to_json());
- ("pointer",
- actions.iter().map(|x| x.to_json()).collect::<Vec<Json>>())
- }
- };
- data.insert("type".into(), action_type.to_json());
- data.insert("actions".into(), actions.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum ActionsType {
- Null(Vec<NullActionItem>),
- Key(Vec<KeyActionItem>),
- Pointer(PointerActionParameters, Vec<PointerActionItem>)
-}
-
-impl Parameters for ActionsType {
- fn from_json(body: &Json) -> WebDriverResult<ActionsType> {
- // These unwraps are OK as long as this is only called from ActionSequence::from_json
- let data = body.as_object().expect("Body should be a JSON Object");
- let actions_type = body.find("type").and_then(|x| x.as_string()).expect("Type should be a string");
- let actions_chain = try_opt!(try_opt!(data.get("actions"),
- ErrorStatus::InvalidArgument,
- "Missing actions parameter").as_array(),
- ErrorStatus::InvalidArgument,
- "Parameter 'actions' was not an array");
- match actions_type {
- "none" => {
- let mut actions = Vec::with_capacity(actions_chain.len());
- for action_body in actions_chain.iter() {
- actions.push(try!(NullActionItem::from_json(action_body)));
- };
- Ok(ActionsType::Null(actions))
- },
- "key" => {
- let mut actions = Vec::with_capacity(actions_chain.len());
- for action_body in actions_chain.iter() {
- actions.push(try!(KeyActionItem::from_json(action_body)));
- };
- Ok(ActionsType::Key(actions))
- },
- "pointer" => {
- let mut actions = Vec::with_capacity(actions_chain.len());
- let parameters = match data.get("parameters") {
- Some(x) => try!(PointerActionParameters::from_json(x)),
- None => Default::default()
- };
-
- for action_body in actions_chain.iter() {
- actions.push(try!(PointerActionItem::from_json(action_body)));
- }
- Ok(ActionsType::Pointer(parameters, actions))
- }
- _ => panic!("Got unexpected action type after checking type")
- }
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum PointerType {
- Mouse,
- Pen,
- Touch,
-}
-
-impl Parameters for PointerType {
- fn from_json(body: &Json) -> WebDriverResult<PointerType> {
- match body.as_string() {
- Some("mouse") => Ok(PointerType::Mouse),
- Some("pen") => Ok(PointerType::Pen),
- Some("touch") => Ok(PointerType::Touch),
- Some(_) => Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "Unsupported pointer type"
- )),
- None => Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "Pointer type was not a string"
- ))
- }
- }
-}
-
-impl ToJson for PointerType {
- fn to_json(&self) -> Json {
- match *self {
- PointerType::Mouse => "mouse".to_json(),
- PointerType::Pen => "pen".to_json(),
- PointerType::Touch => "touch".to_json(),
- }.to_json()
- }
-}
-
-impl Default for PointerType {
- fn default() -> PointerType {
- PointerType::Mouse
- }
-}
-
-#[derive(Debug, Default, PartialEq)]
-pub struct PointerActionParameters {
- pub pointer_type: PointerType
-}
-
-impl Parameters for PointerActionParameters {
- fn from_json(body: &Json) -> WebDriverResult<PointerActionParameters> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::InvalidArgument,
- "Parameter 'parameters' was not an object");
- let pointer_type = match data.get("pointerType") {
- Some(x) => try!(PointerType::from_json(x)),
- None => PointerType::default()
- };
- Ok(PointerActionParameters {
- pointer_type: pointer_type
- })
- }
-}
-
-impl ToJson for PointerActionParameters {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("pointerType".to_owned(),
- self.pointer_type.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum NullActionItem {
- General(GeneralAction)
-}
-
-impl Parameters for NullActionItem {
- fn from_json(body: &Json) -> WebDriverResult<NullActionItem> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::InvalidArgument,
- "Actions chain was not an object");
- let type_name = try_opt!(
- try_opt!(data.get("type"),
- ErrorStatus::InvalidArgument,
- "Missing 'type' parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "Parameter 'type' was not a string");
- match type_name {
- "pause" => Ok(NullActionItem::General(
- try!(GeneralAction::from_json(body)))),
- _ => return Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "Invalid type attribute"))
- }
- }
-}
-
-impl ToJson for NullActionItem {
- fn to_json(&self) -> Json {
- match self {
- &NullActionItem::General(ref x) => x.to_json(),
- }
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum KeyActionItem {
- General(GeneralAction),
- Key(KeyAction)
-}
-
-impl Parameters for KeyActionItem {
- fn from_json(body: &Json) -> WebDriverResult<KeyActionItem> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::InvalidArgument,
- "Key action item was not an object");
- let type_name = try_opt!(
- try_opt!(data.get("type"),
- ErrorStatus::InvalidArgument,
- "Missing 'type' parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "Parameter 'type' was not a string");
- match type_name {
- "pause" => Ok(KeyActionItem::General(
- try!(GeneralAction::from_json(body)))),
- _ => Ok(KeyActionItem::Key(
- try!(KeyAction::from_json(body))))
- }
- }
-}
-
-impl ToJson for KeyActionItem {
- fn to_json(&self) -> Json {
- match *self {
- KeyActionItem::General(ref x) => x.to_json(),
- KeyActionItem::Key(ref x) => x.to_json()
- }
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum PointerActionItem {
- General(GeneralAction),
- Pointer(PointerAction)
-}
-
-impl Parameters for PointerActionItem {
- fn from_json(body: &Json) -> WebDriverResult<PointerActionItem> {
- let data = try_opt!(body.as_object(),
- ErrorStatus::InvalidArgument,
- "Pointer action item was not an object");
- let type_name = try_opt!(
- try_opt!(data.get("type"),
- ErrorStatus::InvalidArgument,
- "Missing 'type' parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "Parameter 'type' was not a string");
-
- match type_name {
- "pause" => Ok(PointerActionItem::General(try!(GeneralAction::from_json(body)))),
- _ => Ok(PointerActionItem::Pointer(try!(PointerAction::from_json(body))))
- }
- }
-}
-
-impl ToJson for PointerActionItem {
- fn to_json(&self) -> Json {
- match self {
- &PointerActionItem::General(ref x) => x.to_json(),
- &PointerActionItem::Pointer(ref x) => x.to_json()
- }
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum GeneralAction {
- Pause(PauseAction)
-}
-
-impl Parameters for GeneralAction {
- fn from_json(body: &Json) -> WebDriverResult<GeneralAction> {
- match body.find("type").and_then(|x| x.as_string()) {
- Some("pause") => Ok(GeneralAction::Pause(try!(PauseAction::from_json(body)))),
- _ => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "Invalid or missing type attribute"))
- }
- }
-}
-
-impl ToJson for GeneralAction {
- fn to_json(&self) -> Json {
- match self {
- &GeneralAction::Pause(ref x) => x.to_json()
- }
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct PauseAction {
- pub duration: u64
-}
-
-impl Parameters for PauseAction {
- fn from_json(body: &Json) -> WebDriverResult<PauseAction> {
- let default = Json::U64(0);
- Ok(PauseAction {
- duration: try_opt!(body.find("duration").unwrap_or(&default).as_u64(),
- ErrorStatus::InvalidArgument,
- "Parameter 'duration' was not a positive integer")
- })
- }
-}
-
-impl ToJson for PauseAction {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("type".to_owned(),
- "pause".to_json());
- data.insert("duration".to_owned(),
- self.duration.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum KeyAction {
- Up(KeyUpAction),
- Down(KeyDownAction)
-}
-
-impl Parameters for KeyAction {
- fn from_json(body: &Json) -> WebDriverResult<KeyAction> {
- match body.find("type").and_then(|x| x.as_string()) {
- Some("keyDown") => Ok(KeyAction::Down(try!(KeyDownAction::from_json(body)))),
- Some("keyUp") => Ok(KeyAction::Up(try!(KeyUpAction::from_json(body)))),
- Some(_) | None => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "Invalid type attribute value for key action"))
- }
- }
-}
-
-impl ToJson for KeyAction {
- fn to_json(&self) -> Json {
- match self {
- &KeyAction::Down(ref x) => x.to_json(),
- &KeyAction::Up(ref x) => x.to_json(),
- }
- }
-}
-
-fn validate_key_value(value_str: &str) -> WebDriverResult<char> {
- let mut chars = value_str.chars();
- let value = if let Some(c) = chars.next() {
- c
- } else {
- return Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "Parameter 'value' was an empty string"))
- };
- if chars.next().is_some() {
- return Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "Parameter 'value' contained multiple characters"))
- };
- Ok(value)
-}
-
-#[derive(Debug, PartialEq)]
-pub struct KeyUpAction {
- pub value: char
-}
-
-impl Parameters for KeyUpAction {
- fn from_json(body: &Json) -> WebDriverResult<KeyUpAction> {
- let value_str = try_opt!(
- try_opt!(body.find("value"),
- ErrorStatus::InvalidArgument,
- "Missing value parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "Parameter 'value' was not a string");
-
- let value = try!(validate_key_value(value_str));
- Ok(KeyUpAction {
- value: value
- })
- }
-}
-
-impl ToJson for KeyUpAction {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("type".to_owned(),
- "keyUp".to_json());
- data.insert("value".to_string(),
- self.value.to_string().to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct KeyDownAction {
- pub value: char
-}
-
-impl Parameters for KeyDownAction {
- fn from_json(body: &Json) -> WebDriverResult<KeyDownAction> {
- let value_str = try_opt!(
- try_opt!(body.find("value"),
- ErrorStatus::InvalidArgument,
- "Missing value parameter").as_string(),
- ErrorStatus::InvalidArgument,
- "Parameter 'value' was not a string");
- let value = try!(validate_key_value(value_str));
- Ok(KeyDownAction {
- value: value
- })
- }
-}
-
-impl ToJson for KeyDownAction {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("type".to_owned(),
- "keyDown".to_json());
- data.insert("value".to_owned(),
- self.value.to_string().to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum PointerOrigin {
- Viewport,
- Pointer,
- Element(WebElement),
-}
-
-impl Parameters for PointerOrigin {
- fn from_json(body: &Json) -> WebDriverResult<PointerOrigin> {
- match *body {
- Json::String(ref x) => {
- match &**x {
- "viewport" => Ok(PointerOrigin::Viewport),
- "pointer" => Ok(PointerOrigin::Pointer),
- _ => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "Unknown pointer origin"))
- }
- },
- Json::Object(_) => Ok(PointerOrigin::Element(try!(WebElement::from_json(body)))),
- _ => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- "Pointer origin was not a string or an object"))
- }
- }
-}
-
-impl ToJson for PointerOrigin {
- fn to_json(&self) -> Json {
- match *self {
- PointerOrigin::Viewport => "viewport".to_json(),
- PointerOrigin::Pointer => "pointer".to_json(),
- PointerOrigin::Element(ref x) => x.to_json(),
- }
- }
-}
-
-impl Default for PointerOrigin {
- fn default() -> PointerOrigin {
- PointerOrigin::Viewport
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum PointerAction {
- Up(PointerUpAction),
- Down(PointerDownAction),
- Move(PointerMoveAction),
- Cancel
-}
-
-impl Parameters for PointerAction {
- fn from_json(body: &Json) -> WebDriverResult<PointerAction> {
- match body.find("type").and_then(|x| x.as_string()) {
- Some("pointerUp") => Ok(PointerAction::Up(try!(PointerUpAction::from_json(body)))),
- Some("pointerDown") => Ok(PointerAction::Down(try!(PointerDownAction::from_json(body)))),
- Some("pointerMove") => Ok(PointerAction::Move(try!(PointerMoveAction::from_json(body)))),
- Some("pointerCancel") => Ok(PointerAction::Cancel),
- Some(_) | None => Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- "Missing or invalid type argument for pointer action"))
- }
- }
-}
-
-impl ToJson for PointerAction {
- fn to_json(&self) -> Json {
- match self {
- &PointerAction::Down(ref x) => x.to_json(),
- &PointerAction::Up(ref x) => x.to_json(),
- &PointerAction::Move(ref x) => x.to_json(),
- &PointerAction::Cancel => {
- let mut data = BTreeMap::new();
- data.insert("type".to_owned(),
- "pointerCancel".to_json());
- Json::Object(data)
- }
- }
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct PointerUpAction {
- pub button: u64,
-}
-
-impl Parameters for PointerUpAction {
- fn from_json(body: &Json) -> WebDriverResult<PointerUpAction> {
- let button = try_opt!(
- try_opt!(body.find("button"),
- ErrorStatus::InvalidArgument,
- "Missing button parameter").as_u64(),
- ErrorStatus::InvalidArgument,
- "Parameter 'button' was not a positive integer");
-
- Ok(PointerUpAction {
- button: button
- })
- }
-}
-
-impl ToJson for PointerUpAction {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("type".to_owned(),
- "pointerUp".to_json());
- data.insert("button".to_owned(), self.button.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct PointerDownAction {
- pub button: u64,
-}
-
-impl Parameters for PointerDownAction {
- fn from_json(body: &Json) -> WebDriverResult<PointerDownAction> {
- let button = try_opt!(
- try_opt!(body.find("button"),
- ErrorStatus::InvalidArgument,
- "Missing button parameter").as_u64(),
- ErrorStatus::InvalidArgument,
- "Parameter 'button' was not a positive integer");
-
- Ok(PointerDownAction {
- button: button
- })
- }
-}
-
-impl ToJson for PointerDownAction {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("type".to_owned(),
- "pointerDown".to_json());
- data.insert("button".to_owned(), self.button.to_json());
- Json::Object(data)
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub struct PointerMoveAction {
- pub duration: Nullable<u64>,
- pub origin: PointerOrigin,
- pub x: Nullable<i64>,
- pub y: Nullable<i64>
-}
-
-impl Parameters for PointerMoveAction {
- fn from_json(body: &Json) -> WebDriverResult<PointerMoveAction> {
- let duration = match body.find("duration") {
- Some(duration) => Some(try_opt!(duration.as_u64(),
- ErrorStatus::InvalidArgument,
- "Parameter 'duration' was not a positive integer")),
- None => None
-
- };
-
- let origin = match body.find("origin") {
- Some(o) => try!(PointerOrigin::from_json(o)),
- None => PointerOrigin::default()
- };
-
- let x = match body.find("x") {
- Some(x) => {
- Some(try_opt!(x.as_i64(),
- ErrorStatus::InvalidArgument,
- "Parameter 'x' was not an integer"))
- },
- None => None
- };
-
- let y = match body.find("y") {
- Some(y) => {
- Some(try_opt!(y.as_i64(),
- ErrorStatus::InvalidArgument,
- "Parameter 'y' was not an integer"))
- },
- None => None
- };
-
- Ok(PointerMoveAction {
- duration: duration.into(),
- origin: origin.into(),
- x: x.into(),
- y: y.into(),
- })
- }
-}
-
-impl ToJson for PointerMoveAction {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("type".to_owned(), "pointerMove".to_json());
- if self.duration.is_value() {
- data.insert("duration".to_owned(),
- self.duration.to_json());
- }
-
- data.insert("origin".to_owned(), self.origin.to_json());
-
- if self.x.is_value() {
- data.insert("x".to_owned(), self.x.to_json());
- }
- if self.y.is_value() {
- data.insert("y".to_owned(), self.y.to_json());
- }
- Json::Object(data)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use rustc_serialize::json::Json;
- use super::{Nullable, Parameters, WindowRectParameters};
-
- #[test]
- fn test_window_rect() {
- let expected = WindowRectParameters {
- x: Nullable::Value(0i64),
- y: Nullable::Value(1i64),
- width: Nullable::Value(2u64),
- height: Nullable::Value(3u64),
- };
- let actual = Json::from_str(r#"{"x": 0, "y": 1, "width": 2, "height": 3}"#).unwrap();
- assert_eq!(expected, Parameters::from_json(&actual).unwrap());
- }
-
- #[test]
- fn test_window_rect_nullable() {
- let expected = WindowRectParameters {
- x: Nullable::Value(0i64),
- y: Nullable::Null,
- width: Nullable::Value(2u64),
- height: Nullable::Null,
- };
- let actual = Json::from_str(r#"{"x": 0, "y": null, "width": 2, "height": null}"#).unwrap();
- assert_eq!(expected, Parameters::from_json(&actual).unwrap());
- }
-
- #[test]
- fn test_window_rect_missing_fields() {
- let expected = WindowRectParameters {
- x: Nullable::Value(0i64),
- y: Nullable::Null,
- width: Nullable::Value(2u64),
- height: Nullable::Null,
- };
- let actual = Json::from_str(r#"{"x": 0, "width": 2}"#).unwrap();
- assert_eq!(expected, Parameters::from_json(&actual).unwrap());
- }
-}
deleted file mode 100644
--- a/third_party/rust/webdriver/src/common.rs
+++ /dev/null
@@ -1,271 +0,0 @@
-use rustc_serialize::{Encodable, Encoder};
-use rustc_serialize::json::{Json, ToJson};
-use std::collections::BTreeMap;
-
-use error::{WebDriverResult, WebDriverError, ErrorStatus};
-
-pub static ELEMENT_KEY: &'static str = "element-6066-11e4-a52e-4f735466cecf";
-
-#[derive(Clone, Debug, PartialEq, RustcEncodable)]
-pub struct Date(pub u64);
-
-impl Date {
- pub fn new(timestamp: u64) -> Date {
- Date(timestamp)
- }
-}
-
-impl ToJson for Date {
- fn to_json(&self) -> Json {
- let &Date(x) = self;
- x.to_json()
- }
-}
-
-#[derive(Clone, Debug, PartialEq)]
-pub enum Nullable<T: ToJson> {
- Value(T),
- Null
-}
-
-impl<T: ToJson> Nullable<T> {
- pub fn is_null(&self) -> bool {
- match *self {
- Nullable::Value(_) => false,
- Nullable::Null => true
- }
- }
-
- pub fn is_value(&self) -> bool {
- match *self {
- Nullable::Value(_) => true,
- Nullable::Null => false
- }
- }
-
- pub fn map<F, U: ToJson>(self, f: F) -> Nullable<U>
- where F: FnOnce(T) -> U {
- match self {
- Nullable::Value(val) => Nullable::Value(f(val)),
- Nullable::Null => Nullable::Null
- }
- }
-}
-
-impl<T: ToJson> Nullable<T> {
- //This is not very pretty
- pub fn from_json<F: FnOnce(&Json) -> WebDriverResult<T>>(value: &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 {
- match *self {
- Nullable::Value(ref x) => x.to_json(),
- Nullable::Null => Json::Null
- }
- }
-}
-
-impl<T: ToJson> Encodable for Nullable<T> {
- fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
- match *self {
- Nullable::Value(ref x) => x.to_json().encode(s),
- Nullable::Null => s.emit_option_none()
- }
- }
-}
-
-impl<T: ToJson> Into<Option<T>> for Nullable<T> {
- fn into(self) -> Option<T> {
- match self {
- Nullable::Value(val) => Some(val),
- Nullable::Null => None
- }
- }
-}
-
-impl<T: ToJson> From<Option<T>> for Nullable<T> {
- fn from(option: Option<T>) -> Nullable<T> {
- match option {
- Some(val) => Nullable::Value(val),
- None => Nullable::Null,
- }
- }
-}
-
-#[derive(Clone, Debug, PartialEq)]
-pub struct WebElement {
- pub id: String
-}
-
-impl WebElement {
- pub fn new(id: String) -> WebElement {
- WebElement {
- id: id
- }
- }
-
- pub fn from_json(data: &Json) -> WebDriverResult<WebElement> {
- let object = try_opt!(data.as_object(),
- ErrorStatus::InvalidArgument,
- "Could not convert webelement to object");
- let id_value = try_opt!(object.get(ELEMENT_KEY),
- ErrorStatus::InvalidArgument,
- "Could not find webelement key");
-
- let id = try_opt!(id_value.as_string(),
- ErrorStatus::InvalidArgument,
- "Could not convert web element to string").to_string();
-
- Ok(WebElement::new(id))
- }
-}
-
-impl ToJson for WebElement {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert(ELEMENT_KEY.to_string(), self.id.to_json());
- Json::Object(data)
- }
-}
-
-impl <T> From<T> for WebElement
- where T: Into<String> {
- fn from(data: T) -> WebElement {
- WebElement::new(data.into())
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum FrameId {
- Short(u16),
- Element(WebElement),
- Null
-}
-
-impl FrameId {
- pub fn from_json(data: &Json) -> WebDriverResult<FrameId> {
- match data {
- &Json::U64(x) => {
- if x > u16::max_value() as u64 || x < u16::min_value() as u64 {
- return Err(WebDriverError::new(ErrorStatus::NoSuchFrame,
- "frame id out of range"))
- };
- Ok(FrameId::Short(x as u16))
- },
- &Json::Null => Ok(FrameId::Null),
- &Json::Object(_) => Ok(FrameId::Element(
- try!(WebElement::from_json(data)))),
- _ => Err(WebDriverError::new(ErrorStatus::NoSuchFrame,
- "frame id has unexpected type"))
- }
- }
-}
-
-impl ToJson for FrameId {
- fn to_json(&self) -> Json {
- match *self {
- FrameId::Short(x) => {
- Json::U64(x as u64)
- },
- FrameId::Element(ref x) => {
- Json::String(x.id.clone())
- },
- FrameId::Null => {
- Json::Null
- }
- }
- }
-}
-
-#[derive(Debug, PartialEq)]
-pub enum LocatorStrategy {
- CSSSelector,
- LinkText,
- PartialLinkText,
- XPath,
-}
-
-impl LocatorStrategy {
- pub fn from_json(body: &Json) -> WebDriverResult<LocatorStrategy> {
- match try_opt!(body.as_string(),
- ErrorStatus::InvalidArgument,
- "Expected locator strategy as string") {
- "css selector" => Ok(LocatorStrategy::CSSSelector),
- "link text" => Ok(LocatorStrategy::LinkText),
- "partial link text" => Ok(LocatorStrategy::PartialLinkText),
- "xpath" => Ok(LocatorStrategy::XPath),
- x => Err(WebDriverError::new(ErrorStatus::InvalidArgument,
- format!("Unknown locator strategy {}", x)))
- }
- }
-}
-
-impl ToJson for LocatorStrategy {
- fn to_json(&self) -> Json {
- Json::String(match *self {
- LocatorStrategy::CSSSelector => "css selector",
- LocatorStrategy::LinkText => "link text",
- LocatorStrategy::PartialLinkText => "partial link text",
- LocatorStrategy::XPath => "xpath"
- }.to_string())
- }
-}
-
-/// The top-level browsing context has an associated window state which
-/// describes what visibility state its OS widget window is in.
-///
-/// The default state is [`Normal`].
-///
-/// [`normal`]: #variant.Normal
-#[derive(Debug)]
-pub enum WindowState {
- /// The window is maximized.
- Maximized,
- /// The window is iconified.
- Minimized,
- /// The window is shown normally.
- Normal,
- /// The window is in full screen mode.
- Fullscreen,
-}
-
-impl WindowState {
- pub fn from_json(body: &Json) -> WebDriverResult<WindowState> {
- use self::WindowState::*;
- let s = try_opt!(
- body.as_string(),
- ErrorStatus::InvalidArgument,
- "Expecetd window state as string"
- );
- match s {
- "maximized" => Ok(Maximized),
- "minimized" => Ok(Minimized),
- "normal" => Ok(Normal),
- "fullscreen" => Ok(Fullscreen),
- x => Err(WebDriverError::new(
- ErrorStatus::InvalidArgument,
- format!("Unknown window state {}", x),
- )),
- }
- }
-}
-
-impl ToJson for WindowState {
- fn to_json(&self) -> Json {
- use self::WindowState::*;
- let state = match *self {
- Maximized => "maximized",
- Minimized => "minimized",
- Normal => "normal",
- Fullscreen => "fullscreen",
- };
- Json::String(state.to_string())
- }
-}
deleted file mode 100644
--- a/third_party/rust/webdriver/src/error.rs
+++ /dev/null
@@ -1,318 +0,0 @@
-use backtrace::Backtrace;
-use hyper::status::StatusCode;
-use rustc_serialize::base64::FromBase64Error;
-use rustc_serialize::json::{DecoderError, Json, ParserError, ToJson};
-use std::borrow::Cow;
-use std::collections::BTreeMap;
-use std::convert::From;
-use std::error::Error;
-use std::fmt;
-use std::io;
-
-#[derive(Debug, PartialEq)]
-pub enum ErrorStatus {
- /// The [`ElementClick`] command could not be completed because the
- /// [element] receiving the events is obscuring the element that was
- /// requested clicked.
- ///
- /// [`ElementClick`]:
- /// ../command/enum.WebDriverCommand.html#variant.ElementClick
- /// [element]: ../common/struct.WebElement.html
- ElementClickIntercepted,
-
- /// A [command] could not be completed because the element is not pointer-
- /// or keyboard interactable.
- ///
- /// [command]: ../command/index.html
- ElementNotInteractable,
-
- /// An attempt was made to select an [element] that cannot be selected.
- ///
- /// [element]: ../common/struct.WebElement.html
- ElementNotSelectable,
-
- /// Navigation caused the user agent to hit a certificate warning, which is
- /// usually the result of an expired or invalid TLS certificate.
- InsecureCertificate,
-
- /// The arguments passed to a [command] are either invalid or malformed.
- ///
- /// [command]: ../command/index.html
- InvalidArgument,
-
- /// An illegal attempt was made to set a cookie under a different domain
- /// than the current page.
- InvalidCookieDomain,
-
- /// The coordinates provided to an interactions operation are invalid.
- InvalidCoordinates,
-
- /// A [command] could not be completed because the element is an invalid
- /// state, e.g. attempting to click an element that is no longer attached
- /// to the document.
- ///
- /// [command]: ../command/index.html
- InvalidElementState,
-
- /// Argument was an invalid selector.
- InvalidSelector,
-
- /// Occurs if the given session ID is not in the list of active sessions,
- /// meaning the session either does not exist or that it’s not active.
- InvalidSessionId,
-
- /// An error occurred while executing JavaScript supplied by the user.
- JavascriptError,
-
- /// The target for mouse interaction is not in the browser’s viewport and
- /// cannot be brought into that viewport.
- MoveTargetOutOfBounds,
-
- /// An attempt was made to operate on a modal dialogue when one was not
- /// open.
- NoSuchAlert,
-
- /// No cookie matching the given path name was found amongst the associated
- /// cookies of the current browsing context’s active document.
- NoSuchCookie,
-
- /// An [element] could not be located on the page using the given search
- /// parameters.
- ///
- /// [element]: ../common/struct.WebElement.html
- NoSuchElement,
-
- /// A [command] to switch to a frame could not be satisfied because the
- /// frame could not be found.
- ///
- /// [command]: ../command/index.html
- NoSuchFrame,
-
- /// A [command] to switch to a window could not be satisfied because the
- /// window could not be found.
- ///
- /// [command]: ../command/index.html
- NoSuchWindow,
-
- /// A script did not complete before its timeout expired.
- ScriptTimeout,
-
- /// A new session could not be created.
- SessionNotCreated,
-
- /// A [command] failed because the referenced [element] is no longer
- /// attached to the DOM.
- ///
- /// [command]: ../command/index.html
- /// [element]: ../common/struct.WebElement.html
- StaleElementReference,
-
- /// An operation did not complete before its timeout expired.
- Timeout,
-
- /// A screen capture was made impossible.
- UnableToCaptureScreen,
-
- /// Setting the cookie’s value could not be done.
- UnableToSetCookie,
-
- /// A modal dialogue was open, blocking this operation.
- UnexpectedAlertOpen,
-
- /// The requested command could not be executed because it does not exist.
- UnknownCommand,
-
- /// An unknown error occurred in the remote end whilst processing the
- /// [command].
- ///
- /// [command]: ../command/index.html
- UnknownError,
-
- /// The requested [command] matched a known endpoint, but did not match a
- /// method for that endpoint.
- ///
- /// [command]: ../command/index.html
- UnknownMethod,
-
- UnknownPath,
-
- /// Indicates that a [command] that should have executed properly is not
- /// currently supported.
- UnsupportedOperation,
-}
-
-
-impl ErrorStatus {
- pub fn error_code(&self) -> &'static str {
- match *self {
- ErrorStatus::ElementClickIntercepted => "element click intercepted",
- ErrorStatus::ElementNotInteractable => "element not interactable",
- ErrorStatus::ElementNotSelectable => "element not selectable",
- ErrorStatus::InsecureCertificate => "insecure certificate",
- ErrorStatus::InvalidArgument => "invalid argument",
- ErrorStatus::InvalidCookieDomain => "invalid cookie domain",
- ErrorStatus::InvalidCoordinates => "invalid coordinates",
- ErrorStatus::InvalidElementState => "invalid element state",
- ErrorStatus::InvalidSelector => "invalid selector",
- ErrorStatus::InvalidSessionId => "invalid session id",
- ErrorStatus::JavascriptError => "javascript error",
- ErrorStatus::MoveTargetOutOfBounds => "move target out of bounds",
- ErrorStatus::NoSuchAlert => "no such alert",
- ErrorStatus::NoSuchCookie => "no such cookie",
- ErrorStatus::NoSuchElement => "no such element",
- ErrorStatus::NoSuchFrame => "no such frame",
- ErrorStatus::NoSuchWindow => "no such window",
- ErrorStatus::ScriptTimeout => "script timeout",
- ErrorStatus::SessionNotCreated => "session not created",
- ErrorStatus::StaleElementReference => "stale element reference",
- ErrorStatus::Timeout => "timeout",
- ErrorStatus::UnableToCaptureScreen => "unable to capture screen",
- ErrorStatus::UnableToSetCookie => "unable to set cookie",
- ErrorStatus::UnexpectedAlertOpen => "unexpected alert open",
- ErrorStatus::UnknownCommand |
- ErrorStatus::UnknownError => "unknown error",
- ErrorStatus::UnknownMethod => "unknown method",
- ErrorStatus::UnknownPath => "unknown command",
- ErrorStatus::UnsupportedOperation => "unsupported operation",
- }
- }
-
- pub fn http_status(&self) -> StatusCode {
- match *self {
- ErrorStatus::ElementClickIntercepted => StatusCode::BadRequest,
- ErrorStatus::ElementNotInteractable => StatusCode::BadRequest,
- ErrorStatus::ElementNotSelectable => StatusCode::BadRequest,
- ErrorStatus::InsecureCertificate => StatusCode::BadRequest,
- ErrorStatus::InvalidArgument => StatusCode::BadRequest,
- ErrorStatus::InvalidCookieDomain => StatusCode::BadRequest,
- ErrorStatus::InvalidCoordinates => StatusCode::BadRequest,
- ErrorStatus::InvalidElementState => StatusCode::BadRequest,
- ErrorStatus::InvalidSelector => StatusCode::BadRequest,
- ErrorStatus::InvalidSessionId => StatusCode::NotFound,
- ErrorStatus::JavascriptError => StatusCode::InternalServerError,
- ErrorStatus::MoveTargetOutOfBounds => StatusCode::InternalServerError,
- ErrorStatus::NoSuchAlert => StatusCode::BadRequest,
- ErrorStatus::NoSuchCookie => StatusCode::NotFound,
- ErrorStatus::NoSuchElement => StatusCode::NotFound,
- ErrorStatus::NoSuchFrame => StatusCode::BadRequest,
- ErrorStatus::NoSuchWindow => StatusCode::BadRequest,
- ErrorStatus::ScriptTimeout => StatusCode::RequestTimeout,
- ErrorStatus::SessionNotCreated => StatusCode::InternalServerError,
- ErrorStatus::StaleElementReference => StatusCode::BadRequest,
- ErrorStatus::Timeout => StatusCode::RequestTimeout,
- ErrorStatus::UnableToCaptureScreen => StatusCode::BadRequest,
- ErrorStatus::UnableToSetCookie => StatusCode::InternalServerError,
- ErrorStatus::UnexpectedAlertOpen => StatusCode::InternalServerError,
- ErrorStatus::UnknownCommand => StatusCode::NotFound,
- ErrorStatus::UnknownError => StatusCode::InternalServerError,
- ErrorStatus::UnknownMethod => StatusCode::MethodNotAllowed,
- ErrorStatus::UnknownPath => StatusCode::NotFound,
- ErrorStatus::UnsupportedOperation => StatusCode::InternalServerError,
- }
- }
-}
-
-pub type WebDriverResult<T> = Result<T, WebDriverError>;
-
-#[derive(Debug)]
-pub struct WebDriverError {
- pub error: ErrorStatus,
- pub message: Cow<'static, str>,
- pub stack: Cow<'static, str>,
- pub delete_session: bool,
-}
-
-impl WebDriverError {
- pub fn new<S>(error: ErrorStatus, message: S) -> WebDriverError
- where S: Into<Cow<'static, str>>
- {
- WebDriverError {
- error: error,
- message: message.into(),
- stack: format!("{:?}", Backtrace::new()).into(),
- delete_session: false,
- }
- }
-
- pub fn new_with_stack<S>(error: ErrorStatus, message: S, stack: S) -> WebDriverError
- where S: Into<Cow<'static, str>>
- {
- WebDriverError {
- error: error,
- message: message.into(),
- stack: stack.into(),
- delete_session: false,
- }
- }
-
- pub fn error_code(&self) -> &'static str {
- self.error.error_code()
- }
-
- pub fn http_status(&self) -> StatusCode {
- self.error.http_status()
- }
-
- pub fn to_json_string(&self) -> String {
- self.to_json().to_string()
- }
-}
-
-impl ToJson for WebDriverError {
- fn to_json(&self) -> Json {
- let mut data = BTreeMap::new();
- data.insert("error".into(), self.error_code().to_json());
- data.insert("message".into(), self.message.to_json());
- data.insert("stacktrace".into(), self.stack.to_json());
-
- let mut wrapper = BTreeMap::new();
- wrapper.insert("value".into(), Json::Object(data));
- Json::Object(wrapper)
- }
-}
-
-impl Error for WebDriverError {
- fn description(&self) -> &str {
- self.error_code()
- }
-
- fn cause(&self) -> Option<&Error> {
- None
- }
-}
-
-impl fmt::Display for WebDriverError {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- self.message.fmt(f)
- }
-}
-
-impl From<ParserError> for WebDriverError {
- fn from(err: ParserError) -> WebDriverError {
- WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
- }
-}
-
-impl From<io::Error> for WebDriverError {
- fn from(err: io::Error) -> WebDriverError {
- WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
- }
-}
-
-impl From<DecoderError> for WebDriverError {
- fn from(err: DecoderError) -> WebDriverError {
- WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
- }
-}
-
-impl From<FromBase64Error> for WebDriverError {
- fn from(err: FromBase64Error) -> WebDriverError {
- WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
- }
-}
-
-impl From<Box<Error>> for WebDriverError {
- fn from(err: Box<Error>) -> WebDriverError {
- WebDriverError::new(ErrorStatus::UnknownError, err.description().to_string())
- }
-}
deleted file mode 100644
--- a/third_party/rust/webdriver/src/httpapi.rs
+++ /dev/null
@@ -1,245 +0,0 @@
-use regex::{Regex, Captures};
-use rustc_serialize::json::Json;
-
-use hyper::method::Method;
-use hyper::method::Method::{Get, Post, Delete};
-
-use command::{WebDriverCommand, WebDriverMessage, WebDriverExtensionCommand,
- VoidWebDriverExtensionCommand};
-use error::{WebDriverResult, WebDriverError, ErrorStatus};
-
-fn standard_routes<U:WebDriverExtensionRoute>() -> Vec<(Method, &'static str, Route<U>)> {
- return vec![(Post, "/session", Route::NewSession),
- (Delete, "/session/{sessionId}", Route::DeleteSession),
- (Post, "/session/{sessionId}/url", Route::Get),
- (Get, "/session/{sessionId}/url", Route::GetCurrentUrl),
- (Post, "/session/{sessionId}/back", Route::GoBack),
- (Post, "/session/{sessionId}/forward", Route::GoForward),
- (Post, "/session/{sessionId}/refresh", Route::Refresh),
- (Get, "/session/{sessionId}/title", Route::GetTitle),
- (Get, "/session/{sessionId}/source", Route::GetPageSource),
- (Get, "/session/{sessionId}/window", Route::GetWindowHandle),
- (Get, "/session/{sessionId}/window/handles", Route::GetWindowHandles),
- (Delete, "/session/{sessionId}/window", Route::CloseWindow),
- (Get, "/session/{sessionId}/window/size", Route::GetWindowSize),
- (Post, "/session/{sessionId}/window/size", Route::SetWindowSize),
- (Get, "/session/{sessionId}/window/position", Route::GetWindowPosition),
- (Post, "/session/{sessionId}/window/position", Route::SetWindowPosition),
- (Get, "/session/{sessionId}/window/rect", Route::GetWindowRect),
- (Post, "/session/{sessionId}/window/rect", Route::SetWindowRect),
- (Post, "/session/{sessionId}/window/minimize", Route::MinimizeWindow),
- (Post, "/session/{sessionId}/window/maximize", Route::MaximizeWindow),
- (Post, "/session/{sessionId}/window/fullscreen", Route::FullscreenWindow),
- (Post, "/session/{sessionId}/window", Route::SwitchToWindow),
- (Post, "/session/{sessionId}/frame", Route::SwitchToFrame),
- (Post, "/session/{sessionId}/frame/parent", Route::SwitchToParentFrame),
- (Post, "/session/{sessionId}/element", Route::FindElement),
- (Post, "/session/{sessionId}/elements", Route::FindElements),
- (Post, "/session/{sessionId}/element/{elementId}/element", Route::FindElementElement),
- (Post, "/session/{sessionId}/element/{elementId}/elements", Route::FindElementElements),
- (Get, "/session/{sessionId}/element/active", Route::GetActiveElement),
- (Get, "/session/{sessionId}/element/{elementId}/displayed", Route::IsDisplayed),
- (Get, "/session/{sessionId}/element/{elementId}/selected", Route::IsSelected),
- (Get, "/session/{sessionId}/element/{elementId}/attribute/{name}", Route::GetElementAttribute),
- (Get, "/session/{sessionId}/element/{elementId}/property/{name}", Route::GetElementProperty),
- (Get, "/session/{sessionId}/element/{elementId}/css/{propertyName}", Route::GetCSSValue),
- (Get, "/session/{sessionId}/element/{elementId}/text", Route::GetElementText),
- (Get, "/session/{sessionId}/element/{elementId}/name", Route::GetElementTagName),
- (Get, "/session/{sessionId}/element/{elementId}/rect", Route::GetElementRect),
- (Get, "/session/{sessionId}/element/{elementId}/enabled", Route::IsEnabled),
- (Post, "/session/{sessionId}/execute/sync", Route::ExecuteScript),
- (Post, "/session/{sessionId}/execute/async", Route::ExecuteAsyncScript),
- (Get, "/session/{sessionId}/cookie", Route::GetCookies),
- (Get, "/session/{sessionId}/cookie/{name}", Route::GetNamedCookie),
- (Post, "/session/{sessionId}/cookie", Route::AddCookie),
- (Delete, "/session/{sessionId}/cookie", Route::DeleteCookies),
- (Delete, "/session/{sessionId}/cookie/{name}", Route::DeleteCookie),
- (Get, "/session/{sessionId}/timeouts", Route::GetTimeouts),
- (Post, "/session/{sessionId}/timeouts", Route::SetTimeouts),
- (Post, "/session/{sessionId}/element/{elementId}/click", Route::ElementClick),
- (Post, "/session/{sessionId}/element/{elementId}/tap", Route::ElementTap),
- (Post, "/session/{sessionId}/element/{elementId}/clear", Route::ElementClear),
- (Post, "/session/{sessionId}/element/{elementId}/value", Route::ElementSendKeys),
- (Post, "/session/{sessionId}/alert/dismiss", Route::DismissAlert),
- (Post, "/session/{sessionId}/alert/accept", Route::AcceptAlert),
- (Get, "/session/{sessionId}/alert/text", Route::GetAlertText),
- (Post, "/session/{sessionId}/alert/text", Route::SendAlertText),
- (Get, "/session/{sessionId}/screenshot", Route::TakeScreenshot),
- (Get, "/session/{sessionId}/element/{elementId}/screenshot", Route::TakeElementScreenshot),
- (Post, "/session/{sessionId}/actions", Route::PerformActions),
- (Delete, "/session/{sessionId}/actions", Route::ReleaseActions),
- (Get, "/status", Route::Status),]
-}
-
-#[derive(Clone, Copy, Debug)]
-pub enum Route<U:WebDriverExtensionRoute> {
- NewSession,
- DeleteSession,
- Get,
- GetCurrentUrl,
- GoBack,
- GoForward,
- Refresh,
- GetTitle,
- GetPageSource,
- GetWindowHandle,
- GetWindowHandles,
- CloseWindow,
- GetWindowSize, // deprecated
- SetWindowSize, // deprecated
- GetWindowPosition, // deprecated
- SetWindowPosition, // deprecated
- GetWindowRect,
- SetWindowRect,
- MinimizeWindow,
- MaximizeWindow,
- FullscreenWindow,
- SwitchToWindow,
- SwitchToFrame,
- SwitchToParentFrame,
- FindElement,
- FindElements,
- FindElementElement,
- FindElementElements,
- GetActiveElement,
- IsDisplayed,
- IsSelected,
- GetElementAttribute,
- GetElementProperty,
- GetCSSValue,
- GetElementText,
- GetElementTagName,
- GetElementRect,
- IsEnabled,
- ExecuteScript,
- ExecuteAsyncScript,
- GetCookies,
- GetNamedCookie,
- AddCookie,
- DeleteCookies,
- DeleteCookie,
- GetTimeouts,
- SetTimeouts,
- ElementClick,
- ElementTap,
- ElementClear,
- ElementSendKeys,
- PerformActions,
- ReleaseActions,
- DismissAlert,
- AcceptAlert,
- GetAlertText,
- SendAlertText,
- TakeScreenshot,
- TakeElementScreenshot,
- Status,
- Extension(U),
-}
-
-pub trait WebDriverExtensionRoute : Clone + Send + PartialEq {
- type Command: WebDriverExtensionCommand + 'static;
-
- fn command(&self, &Captures, &Json) -> WebDriverResult<WebDriverCommand<Self::Command>>;
-}
-
-#[derive(Clone, Debug, PartialEq)]
-pub struct VoidWebDriverExtensionRoute;
-
-impl WebDriverExtensionRoute for VoidWebDriverExtensionRoute {
- type Command = VoidWebDriverExtensionCommand;
-
- fn command(&self, _:&Captures, _:&Json) -> WebDriverResult<WebDriverCommand<VoidWebDriverExtensionCommand>> {
- panic!("No extensions implemented");
- }
-}
-
-#[derive(Clone, Debug)]
-struct RequestMatcher<U: WebDriverExtensionRoute> {
- method: Method,
- path_regexp: Regex,
- match_type: Route<U>
-}
-
-impl <U: WebDriverExtensionRoute> RequestMatcher<U> {
- pub fn new(method: Method, path: &str, match_type: Route<U>) -> RequestMatcher<U> {
- let path_regexp = RequestMatcher::<U>::compile_path(path);
- RequestMatcher {
- method: method,
- path_regexp: path_regexp,
- match_type: match_type
- }
- }
-
- pub fn get_match<'t>(&'t self, method: Method, path: &'t str) -> (bool, Option<Captures>) {
- let captures = self.path_regexp.captures(path);
- (method == self.method, captures)
- }
-
- fn compile_path(path: &str) -> Regex {
- let mut rv = String::new();
- rv.push_str("^");
- let components = path.split('/');
- for component in components {
- if component.starts_with("{") {
- if !component.ends_with("}") {
- panic!("Invalid url pattern")
- }
- rv.push_str(&format!("(?P<{}>[^/]+)/", &component[1..component.len()-1])[..]);
- } else {
- rv.push_str(&format!("{}/", component)[..]);
- }
- }
- //Remove the trailing /
- rv.pop();
- rv.push_str("$");
- //This will fail at runtime if the regexp is invalid
- Regex::new(&rv[..]).unwrap()
- }
-}
-
-#[derive(Debug)]
-pub struct WebDriverHttpApi<U: WebDriverExtensionRoute> {
- routes: Vec<(Method, RequestMatcher<U>)>,
-}
-
-impl <U: WebDriverExtensionRoute> WebDriverHttpApi<U> {
- pub fn new(extension_routes: &[(Method, &str, U)]) -> WebDriverHttpApi<U> {
- let mut rv = WebDriverHttpApi::<U> {
- routes: vec![],
- };
- debug!("Creating routes");
- for &(ref method, ref url, ref match_type) in standard_routes::<U>().iter() {
- rv.add(method.clone(), *url, (*match_type).clone());
- };
- for &(ref method, ref url, ref extension_route) in extension_routes.iter() {
- rv.add(method.clone(), *url, Route::Extension(extension_route.clone()));
- };
- rv
- }
-
- fn add(&mut self, method: Method, path: &str, match_type: Route<U>) {
- let http_matcher = RequestMatcher::new(method.clone(), path, match_type);
- self.routes.push((method, http_matcher));
- }
-
- pub fn decode_request(&self, method: Method, path: &str, body: &str) -> WebDriverResult<WebDriverMessage<U>> {
- let mut error = ErrorStatus::UnknownPath;
- for &(ref match_method, ref matcher) in self.routes.iter() {
- if method == *match_method {
- let (method_match, captures) = matcher.get_match(method.clone(), path);
- if captures.is_some() {
- if method_match {
- return WebDriverMessage::from_http(matcher.match_type.clone(),
- &captures.unwrap(),
- body,
- method == Post)
- } else {
- error = ErrorStatus::UnknownMethod;
- }
- }
- }
- }
- Err(WebDriverError::new(error,
- format!("{} {} did not match a known command", method, path)))
- }
-}
deleted file mode 100644
--- a/third_party/rust/webdriver/src/lib.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-#![allow(non_snake_case)]
-
-extern crate backtrace;
-#[macro_use]
-extern crate log;
-extern crate rustc_serialize;
-extern crate hyper;
-extern crate regex;
-extern crate cookie;
-extern crate time;
-extern crate url;
-
-#[macro_use] pub mod macros;
-pub mod httpapi;
-pub mod capabilities;
-pub mod command;
-pub mod common;
-pub mod error;
-pub mod server;
-pub mod response;
-
-#[cfg(test)]
-mod nullable_tests {
- use super::common::Nullable;
-
- #[test]
- fn test_nullable_map() {
- let mut test = Nullable::Value(21);
-
- assert_eq!(test.map(|x| x << 1), Nullable::Value(42));
-
- test = Nullable::Null;
-
- assert_eq!(test.map(|x| x << 1), Nullable::Null);
- }
-
- #[test]
- fn test_nullable_into() {
- let test: Option<i32> = Nullable::Value(42).into();
-
- assert_eq!(test, Some(42));
- }
-}
deleted file mode 100644
--- a/third_party/rust/webdriver/src/macros.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-macro_rules! try_opt {
- ($expr:expr, $err_type:expr, $err_msg:expr) => ({
- match $expr {
- Some(x) => x,
- None => return Err(WebDriverError::new($err_type, $err_msg))
- }
- })
-}
deleted file mode 100644
--- a/third_party/rust/webdriver/src/response.rs
+++ /dev/null
@@ -1,336 +0,0 @@
-use common::{Date, Nullable, WindowState};
-use cookie;
-use rustc_serialize::json::{self, Json, ToJson};
-use std::collections::BTreeMap;
-use time;
-
-#[derive(Debug)]
-pub enum WebDriverResponse {
- CloseWindow(CloseWindowResponse),
- Cookie(CookieResponse),
- Cookies(CookiesResponse),
- DeleteSession,
- ElementRect(ElementRectResponse),
- Generic(ValueResponse),
- NewSession(NewSessionResponse),
- Timeouts(TimeoutsResponse),
- Void,
- WindowRect(WindowRectResponse),
-}
-
-impl WebDriverResponse {
- pub fn to_json_string(self) -> String {
- use response::WebDriverResponse::*;
-
- let obj = match self {
- CloseWindow(ref x) => json::encode(&x.to_json()),
- Cookie(ref x) => json::encode(x),
- Cookies(ref x) => json::encode(x),
- DeleteSession => Ok("{}".to_string()),
- ElementRect(ref x) => json::encode(x),
- Generic(ref x) => json::encode(x),
- NewSession(ref x) => json::encode(x),
- Timeouts(ref x) => json::encode(x),
- Void => Ok("{}".to_string()),
- WindowRect(ref x) => json::encode(&x.to_json()),
- }.unwrap();
-
- match self {
- Generic(_) | Cookie(_) | Cookies(_) => obj,
- _ => {
- let mut data = String::with_capacity(11 + obj.len());
- data.push_str("{\"value\": ");
- data.push_str(&*obj);
- data.push_str("}");
- data
- }
- }
- }
-}
-
-#[derive(Debug, RustcEncodable)]
-pub struct CloseWindowResponse {
- pub window_handles: Vec<String>,
-}
-
-impl CloseWindowResponse {
- pub fn new(handles: Vec<String>) -> CloseWindowResponse {
- CloseWindowResponse { window_handles: handles }
- }
-}
-
-impl ToJson for CloseWindowResponse {
- fn to_json(&self) -> Json {
- Json::Array(self.window_handles
- .iter()
- .map(|x| Json::String(x.clone()))
- .collect::<Vec<Json>>())
- }
-}
-
-#[derive(Debug, RustcEncodable)]
-pub struct NewSessionResponse {
- pub sessionId: String,
- pub capabilities: json::Json
-}
-
-impl NewSessionResponse {
- pub fn new(session_id: String, capabilities: json::Json) -> NewSessionResponse {
- NewSessionResponse {
- capabilities: capabilities,
- sessionId: session_id
- }
- }
-}
-
-#[derive(Debug, RustcEncodable)]
-pub struct TimeoutsResponse {
- pub script: u64,
- pub pageLoad: u64,
- pub implicit: u64,
-}
-
-impl TimeoutsResponse {
- pub fn new(script: u64, page_load: u64, implicit: u64) -> TimeoutsResponse {
- TimeoutsResponse {
- script: script,
- pageLoad: page_load,
- implicit: implicit,
- }
- }
-}
-
-#[derive(Debug, RustcEncodable)]
-pub struct ValueResponse {
- pub value: json::Json
-}
-
-impl ValueResponse {
- pub fn new(value: json::Json) -> ValueResponse {
- ValueResponse {
- value: value
- }
- }
-}
-
-#[derive(Debug, RustcEncodable)]
-pub struct ElementRectResponse {
- /// X axis position of the top-left corner of the element relative
- // to the current browsing context’s document element in CSS reference
- // pixels.
- pub x: f64,
-
- /// Y axis position of the top-left corner of the element relative
- // to the current browsing context’s document element in CSS reference
- // pixels.
- pub y: f64,
-
- /// Height of the element’s [bounding rectangle] in CSS reference
- /// pixels.
- ///
- /// [bounding rectangle]: https://drafts.fxtf.org/geometry/#rectangle
- pub width: f64,
-
- /// Width of the element’s [bounding rectangle] in CSS reference
- /// pixels.
- ///
- /// [bounding rectangle]: https://drafts.fxtf.org/geometry/#rectangle
- pub height: f64,
-}
-
-#[derive(Debug)]
-pub struct WindowRectResponse {
- /// `WindowProxy`’s [screenX] attribute.
- ///
- /// [screenX]: https://drafts.csswg.org/cssom-view/#dom-window-screenx
- pub x: f64,
-
- /// `WindowProxy`’s [screenY] attribute.
- ///
- /// [screenY]: https://drafts.csswg.org/cssom-view/#dom-window-screeny
- pub y: f64,
-
- /// Width of the top-level browsing context’s outer dimensions, including
- /// any browser chrome and externally drawn window decorations in CSS
- /// reference pixels.
- pub width: f64,
-
- /// Height of the top-level browsing context’s outer dimensions, including
- /// any browser chrome and externally drawn window decorations in CSS
- /// reference pixels.
- pub height: f64,
-
- /// The top-level browsing context’s window state.
- pub state: WindowState,
-}
-
-impl ToJson for WindowRectResponse {
- fn to_json(&self) -> Json {
- let mut body = BTreeMap::new();
- body.insert("x".to_owned(), self.x.to_json());
- body.insert("y".to_owned(), self.y.to_json());
- body.insert("width".to_owned(), self.width.to_json());
- body.insert("height".to_owned(), self.height.to_json());
- body.insert("state".to_owned(), self.state.to_json());
- Json::Object(body)
- }
-}
-
-#[derive(Clone, Debug, PartialEq, RustcEncodable)]
-pub struct Cookie {
- pub name: String,
- pub value: String,
- pub path: Nullable<String>,
- pub domain: Nullable<String>,
- pub expiry: Nullable<Date>,
- pub secure: bool,
- pub httpOnly: bool,
-}
-
-impl Into<cookie::Cookie<'static>> for Cookie {
- fn into(self) -> cookie::Cookie<'static> {
- let cookie = cookie::Cookie::build(self.name, self.value)
- .secure(self.secure)
- .http_only(self.httpOnly);
- let cookie = match self.domain {
- Nullable::Value(domain) => cookie.domain(domain),
- Nullable::Null => cookie,
- };
- let cookie = match self.path {
- Nullable::Value(path) => cookie.path(path),
- Nullable::Null => cookie,
- };
- let cookie = match self.expiry {
- Nullable::Value(Date(expiry)) => {
- cookie.expires(time::at(time::Timespec::new(expiry as i64, 0)))
- }
- Nullable::Null => cookie,
- };
- cookie.finish()
- }
-}
-
-#[derive(Debug, RustcEncodable)]
-pub struct CookieResponse {
- pub value: Cookie,
-}
-
-#[derive(Debug, RustcEncodable)]
-pub struct CookiesResponse {
- pub value: Vec<Cookie>,
-}
-
-#[cfg(test)]
-mod tests {
- use super::{CloseWindowResponse, Cookie, CookieResponse, CookiesResponse, ElementRectResponse,
- NewSessionResponse, Nullable, TimeoutsResponse, ValueResponse, WebDriverResponse,
- WindowRectResponse};
- use common::WindowState;
- use rustc_serialize::json::Json;
- use std::collections::BTreeMap;
-
- fn test(resp: WebDriverResponse, expected_str: &str) {
- let data = resp.to_json_string();
- let actual = Json::from_str(&*data).unwrap();
- let expected = Json::from_str(expected_str).unwrap();
- assert_eq!(actual, expected);
- }
-
- #[test]
- fn test_close_window() {
- let resp = WebDriverResponse::CloseWindow(
- CloseWindowResponse::new(vec!["test".into()]));
- let expected = r#"{"value": ["test"]}"#;
- test(resp, expected);
- }
-
- #[test]
- fn test_cookie() {
- let cookie = Cookie {
- name: "name".into(),
- value: "value".into(),
- path: Nullable::Value("/".into()),
- domain: Nullable::Null,
- expiry: Nullable::Null,
- secure: true,
- httpOnly: false,
- };
- let resp = WebDriverResponse::Cookie(CookieResponse { value: cookie });
- let expected = r#"{"value": {"name": "name", "expiry": null, "value": "value",
-"path": "/", "domain": null, "secure": true, "httpOnly": false}}"#;
- test(resp, expected);
- }
-
- #[test]
- fn test_cookies() {
- let resp = WebDriverResponse::Cookies(CookiesResponse {
- value: vec![
- Cookie {
- name: "name".into(),
- value: "value".into(),
- path: Nullable::Value("/".into()),
- domain: Nullable::Null,
- expiry: Nullable::Null,
- secure: true,
- httpOnly: false,
- }
- ]});
- let expected = r#"{"value": [{"name": "name", "value": "value", "path": "/",
-"domain": null, "expiry": null, "secure": true, "httpOnly": false}]}"#;
- test(resp, expected);
- }
-
- #[test]
- fn test_element_rect() {
- let rect = ElementRectResponse {
- x: 0f64,
- y: 1f64,
- width: 2f64,
- height: 3f64,
- };
- let resp = WebDriverResponse::ElementRect(rect);
- let expected = r#"{"value": {"x": 0.0, "y": 1.0, "width": 2.0, "height": 3.0}}"#;
- test(resp, expected);
- }
-
- #[test]
- fn test_window_rect() {
- let rect = WindowRectResponse {
- x: 0f64,
- y: 1f64,
- width: 2f64,
- height: 3f64,
- state: WindowState::Normal,
- };
- let resp = WebDriverResponse::WindowRect(rect);
- let expected = r#"{"value": {"x": 0.0, "y": 1.0, "width": 2.0, "height": 3.0, "state": "normal"}}"#;
- test(resp, expected);
- }
-
- #[test]
- fn test_new_session() {
- let resp = WebDriverResponse::NewSession(
- NewSessionResponse::new("test".into(),
- Json::Object(BTreeMap::new())));
- let expected = r#"{"value": {"sessionId": "test", "capabilities": {}}}"#;
- test(resp, expected);
- }
-
- #[test]
- fn test_timeouts() {
- let resp = WebDriverResponse::Timeouts(TimeoutsResponse::new(
- 1, 2, 3));
- let expected = r#"{"value": {"script": 1, "pageLoad": 2, "implicit": 3}}"#;
- test(resp, expected);
- }
-
- #[test]
- fn test_value() {
- let mut value = BTreeMap::new();
- value.insert("example".into(), Json::Array(vec![Json::String("test".into())]));
- let resp = WebDriverResponse::Generic(ValueResponse::new(
- Json::Object(value)));
- let expected = r#"{"value": {"example": ["test"]}}"#;
- test(resp, expected);
- }
-}
deleted file mode 100644
--- a/third_party/rust/webdriver/src/server.rs
+++ /dev/null
@@ -1,263 +0,0 @@
-use std::io::Read;
-use std::marker::PhantomData;
-use std::net::SocketAddr;
-use std::sync::mpsc::{channel, Receiver, Sender};
-use std::sync::Mutex;
-use std::thread;
-
-use hyper::header::{ContentType, CacheControl, CacheDirective};
-use hyper::mime::{Mime, TopLevel, SubLevel, Attr, Value};
-use hyper::method::Method;
-use hyper::Result;
-use hyper::server::{Handler, Listening, Request, Response, Server};
-use hyper::status::StatusCode;
-use hyper::uri::RequestUri::AbsolutePath;
-
-use command::{WebDriverMessage, WebDriverCommand};
-use error::{WebDriverResult, WebDriverError, ErrorStatus};
-use httpapi::{WebDriverHttpApi, WebDriverExtensionRoute, VoidWebDriverExtensionRoute};
-use response::{CloseWindowResponse, WebDriverResponse};
-
-enum DispatchMessage<U: WebDriverExtensionRoute> {
- HandleWebDriver(WebDriverMessage<U>, Sender<WebDriverResult<WebDriverResponse>>),
- Quit
-}
-
-#[derive(Clone, Debug, PartialEq)]
-pub struct Session {
- id: String
-}
-
-impl Session {
- fn new(id: String) -> Session {
- Session {
- id: id
- }
- }
-}
-
-pub trait WebDriverHandler<U: WebDriverExtensionRoute=VoidWebDriverExtensionRoute> : Send {
- fn handle_command(&mut self, session: &Option<Session>, msg: WebDriverMessage<U>) -> WebDriverResult<WebDriverResponse>;
- fn delete_session(&mut self, session: &Option<Session>);
-}
-
-#[derive(Debug)]
-struct Dispatcher<T: WebDriverHandler<U>,
- U: WebDriverExtensionRoute> {
- handler: T,
- session: Option<Session>,
- extension_type: PhantomData<U>,
-}
-
-impl<T: WebDriverHandler<U>, U: WebDriverExtensionRoute> Dispatcher<T, U> {
- fn new(handler: T) -> Dispatcher<T, U> {
- Dispatcher {
- handler: handler,
- session: None,
- extension_type: PhantomData,
- }
- }
-
- fn run(&mut self, msg_chan: Receiver<DispatchMessage<U>>) {
- loop {
- match msg_chan.recv() {
- Ok(DispatchMessage::HandleWebDriver(msg, resp_chan)) => {
- let resp = match self.check_session(&msg) {
- Ok(_) => self.handler.handle_command(&self.session, msg),
- Err(e) => Err(e),
- };
-
- match resp {
- Ok(WebDriverResponse::NewSession(ref new_session)) => {
- self.session = Some(Session::new(new_session.sessionId.clone()));
- }
- Ok(WebDriverResponse::CloseWindow(CloseWindowResponse { ref window_handles })) => {
- if window_handles.len() == 0 {
- debug!("Last window was closed, deleting session");
- self.delete_session();
- }
- }
- Ok(WebDriverResponse::DeleteSession) => self.delete_session(),
- Err(ref x) if x.delete_session => self.delete_session(),
- _ => {}
- }
-
- if resp_chan.send(resp).is_err() {
- error!("Sending response to the main thread failed");
- };
- }
- Ok(DispatchMessage::Quit) => break,
- Err(_) => panic!("Error receiving message in handler"),
- }
- }
- }
-
- fn delete_session(&mut self) {
- debug!("Deleting session");
- self.handler.delete_session(&self.session);
- self.session = None;
- }
-
- fn check_session(&self, msg: &WebDriverMessage<U>) -> WebDriverResult<()> {
- match msg.session_id {
- Some(ref msg_session_id) => {
- match self.session {
- Some(ref existing_session) => {
- if existing_session.id != *msg_session_id {
- Err(WebDriverError::new(
- ErrorStatus::InvalidSessionId,
- format!("Got unexpected session id {}",
- msg_session_id)))
- } else {
- Ok(())
- }
- },
- None => Ok(())
- }
- },
- None => {
- match self.session {
- Some(_) => {
- match msg.command {
- WebDriverCommand::Status => Ok(()),
- WebDriverCommand::NewSession(_) => {
- Err(WebDriverError::new(
- ErrorStatus::SessionNotCreated,
- "Session is already started"))
- },
- _ => {
- //This should be impossible
- error!("Got a message with no session id");
- Err(WebDriverError::new(
- ErrorStatus::UnknownError,
- "Got a command with no session?!"))
- }
- }
- },
- None => {
- match msg.command {
- WebDriverCommand::NewSession(_) => Ok(()),
- WebDriverCommand::Status => Ok(()),
- _ => Err(WebDriverError::new(
- ErrorStatus::InvalidSessionId,
- "Tried to run a command before creating a session"))
- }
- }
- }
- }
- }
- }
-}
-
-#[derive(Debug)]
-struct HttpHandler<U: WebDriverExtensionRoute> {
- chan: Mutex<Sender<DispatchMessage<U>>>,
- api: Mutex<WebDriverHttpApi<U>>
-}
-
-impl <U: WebDriverExtensionRoute> HttpHandler<U> {
- fn new(api: WebDriverHttpApi<U>, chan: Sender<DispatchMessage<U>>) -> HttpHandler<U> {
- HttpHandler {
- chan: Mutex::new(chan),
- api: Mutex::new(api)
- }
- }
-}
-
-impl<U: WebDriverExtensionRoute> Handler for HttpHandler<U> {
- fn handle(&self, req: Request, res: Response) {
- let mut req = req;
- let mut res = res;
-
- let mut body = String::new();
- if let Method::Post = req.method {
- req.read_to_string(&mut body).unwrap();
- }
-
- debug!("-> {} {} {}", req.method, req.uri, body);
-
- match req.uri {
- AbsolutePath(path) => {
- let msg_result = {
- // The fact that this locks for basically the whole request doesn't
- // matter as long as we are only handling one request at a time.
- match self.api.lock() {
- Ok(ref api) => api.decode_request(req.method, &path[..], &body[..]),
- Err(_) => return,
- }
- };
- let (status, resp_body) = match msg_result {
- Ok(message) => {
- let (send_res, recv_res) = channel();
- match self.chan.lock() {
- Ok(ref c) => {
- let res =
- c.send(DispatchMessage::HandleWebDriver(message, send_res));
- match res {
- Ok(x) => x,
- Err(_) => {
- error!("Something terrible happened");
- return;
- }
- }
- }
- Err(_) => {
- error!("Something terrible happened");
- return;
- }
- }
- match recv_res.recv() {
- Ok(data) => {
- match data {
- Ok(response) => (StatusCode::Ok, response.to_json_string()),
- Err(err) => (err.http_status(), err.to_json_string()),
- }
- }
- Err(e) => panic!("Error reading response: {:?}", e),
- }
- }
- Err(err) => (err.http_status(), err.to_json_string()),
- };
-
- debug!("<- {} {}", status, resp_body);
-
- {
- let resp_status = res.status_mut();
- *resp_status = status;
- }
- res.headers_mut()
- .set(ContentType(Mime(TopLevel::Application,
- SubLevel::Json,
- vec![(Attr::Charset, Value::Utf8)])));
- res.headers_mut()
- .set(CacheControl(vec![CacheDirective::NoCache]));
-
- res.send(&resp_body.as_bytes()).unwrap();
- }
- _ => {}
- }
- }
-}
-
-pub fn start<T, U>(address: SocketAddr,
- handler: T,
- extension_routes: &[(Method, &str, U)])
- -> Result<Listening>
- where T: 'static + WebDriverHandler<U>,
- U: 'static + WebDriverExtensionRoute
-{
- let (msg_send, msg_recv) = channel();
-
- let api = WebDriverHttpApi::new(extension_routes);
- let http_handler = HttpHandler::new(api, msg_send);
- let mut server = try!(Server::http(address));
- server.keep_alive(None);
-
- let builder = thread::Builder::new().name("webdriver dispatcher".to_string());
- try!(builder.spawn(move || {
- let mut dispatcher = Dispatcher::new(handler);
- dispatcher.run(msg_recv);
- }));
-
- server.handle(http_handler)
-}