зеркало из https://github.com/mozilla/gecko-dev.git
geckodriver: Merge pull request #161 from mozilla/firefox_options
Change the format used for capabilities Source-Repo: https://github.com/mozilla/geckodriver Source-Revision: 38902f618fe435f134e3d73a98c9f074453bf9e3 --HG-- extra : rebase_source : 37db4bb63c1b0d90e9d2aacc3b4d27724e4d83e3
This commit is contained in:
Родитель
69fe7f8e36
Коммит
2cd07eccde
|
@ -12,8 +12,8 @@ dependencies = [
|
|||
"regex 0.1.73 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"uuid 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webdriver 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zip 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"webdriver 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"zip 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -430,7 +430,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
|
||||
[[package]]
|
||||
name = "webdriver"
|
||||
version = "0.12.0"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"cookie 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -465,7 +465,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.1.18"
|
||||
version = "0.1.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bzip2 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
|
|
@ -16,7 +16,7 @@ mozrunner = "^0.3.1"
|
|||
regex = "0.1.47"
|
||||
rustc-serialize = "0.3.16"
|
||||
uuid = "0.1.18"
|
||||
webdriver = "0.12"
|
||||
webdriver = "0.13"
|
||||
zip = "0.1.16"
|
||||
|
||||
[dependencies.clap]
|
||||
|
|
|
@ -36,29 +36,46 @@ the more bug fixes and features.
|
|||
|
||||
## Firefox capabilities
|
||||
|
||||
**Note**: The names of these capabilities will change in a future release to better match
|
||||
the precedent set by ChromeDriver.
|
||||
geckodriver supports a capability named `firefoxOptions` which takes
|
||||
Firefox-specific preference values. This must be a dictionary and may
|
||||
contain any of the following fields:
|
||||
|
||||
geckodriver supports a couple of non-standard capabilities
|
||||
to customise and configure a Firefox session:
|
||||
|
||||
<dl>
|
||||
<dt><code>firefox_binary</code>
|
||||
<dd>Set to full path of the Firefox binary,
|
||||
e.g. <i>/usr/bin/firefox</i> or <i>/Applications/Firefox.app/Contents/MacOS/firefox</i>,
|
||||
to select which custom browser binary to use.
|
||||
If left undefined geckodriver will attempt
|
||||
to deduce the default location of Firefox
|
||||
on the current system.
|
||||
|
||||
<dt><code>firefox_profile</code>
|
||||
<dd>For each session, geckodriver creates a new temporary profile by default.
|
||||
To set custom preferences or use an add-on/extension,
|
||||
you may want to provide a custom profile.
|
||||
A profile can be sent across the wire protocol
|
||||
by setting this capability to its path
|
||||
on the local filesystem.
|
||||
</dl>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name
|
||||
<th>Type
|
||||
<th>Default
|
||||
<th>Description
|
||||
</tr>
|
||||
</thead>
|
||||
<tr>
|
||||
<td><code>binary</code>
|
||||
<td>String
|
||||
<td>Taken from geckodriver command line or system defaults.
|
||||
<td>Absolute path of the Firefox binary,
|
||||
e.g. <code>/usr/bin/firefox</code> or <code>/Applications/Firefox.app/Contents/MacOS/firefox</code>,
|
||||
to select which custom browser binary to use.
|
||||
If left undefined geckodriver will attempt
|
||||
to deduce the default location of Firefox
|
||||
on the current system.
|
||||
<tr>
|
||||
<td><code>args</code>
|
||||
<td>Array of strings
|
||||
<td>
|
||||
<td>Command line arguments to pass to the
|
||||
Firefox binary. These must include the leading `--` where required
|
||||
e.g. `["--devtools"]`.
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>profile</code>
|
||||
<td>String
|
||||
<td>New empty profile
|
||||
<td>Base64-encoded zip of a profile directory
|
||||
to use as the profile for the Firefox instance. This may be used to
|
||||
e.g. install extensions or custom certificates.
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
## Building
|
||||
|
||||
|
@ -73,7 +90,7 @@ ensure you do a compilation with optimisations:
|
|||
Or if you want a non-optimised binary for debugging:
|
||||
|
||||
% cargo build
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
Usage steps are [documented on MDN](https://developer.mozilla.org/en-US/docs/Mozilla/QA/Marionette/WebDriver),
|
||||
|
|
|
@ -164,7 +164,7 @@ fn main() {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::BTreeMap;
|
||||
use marionette::{MarionetteSettings, MarionetteHandler};
|
||||
use marionette::{FirefoxOptions};
|
||||
use webdriver::command::NewSessionParameters;
|
||||
use rustc_serialize::json::Json;
|
||||
use std::fs::File;
|
||||
|
@ -172,8 +172,6 @@ mod tests {
|
|||
use mozprofile::preferences::Pref;
|
||||
use std::io::Read;
|
||||
|
||||
const MARIONETTE_PORT: u16 = 2828;
|
||||
|
||||
#[test]
|
||||
fn test_profile() {
|
||||
let mut profile_data = Vec::with_capacity(1024);
|
||||
|
@ -189,31 +187,22 @@ mod tests {
|
|||
|
||||
let desired: BTreeMap<String, Json> = BTreeMap::new();
|
||||
let mut required: BTreeMap<String, Json> = BTreeMap::new();
|
||||
required.insert("firefox_profile".into(), encoded_profile);
|
||||
let capabilities = NewSessionParameters {
|
||||
let mut firefox_options: BTreeMap<String, Json> = BTreeMap::new();
|
||||
firefox_options.insert("profile".into(), encoded_profile);
|
||||
required.insert("firefoxOptions".into(), Json::Object(firefox_options));
|
||||
let mut capabilities = NewSessionParameters {
|
||||
desired: desired,
|
||||
required: required
|
||||
};
|
||||
|
||||
let settings = MarionetteSettings {
|
||||
port: None,
|
||||
binary: None,
|
||||
connect_existing: false,
|
||||
log_level: None,
|
||||
};
|
||||
let handler = MarionetteHandler::new(settings);
|
||||
|
||||
let mut gecko_profile = handler.load_profile(&capabilities).unwrap().unwrap();
|
||||
handler.set_prefs(MARIONETTE_PORT, &mut gecko_profile, true).unwrap();
|
||||
|
||||
let prefs = gecko_profile.user_prefs().unwrap();
|
||||
let options = FirefoxOptions::from_capabilities(&mut capabilities).unwrap();
|
||||
let mut profile = options.profile.unwrap();
|
||||
let prefs = profile.user_prefs().unwrap();
|
||||
|
||||
println!("{:?}",prefs.prefs);
|
||||
|
||||
assert_eq!(prefs.get("startup.homepage_welcome_url"),
|
||||
Some(&Pref::new("data:text/html,PASS")));
|
||||
assert_eq!(prefs.get("marionette.defaultPrefs.enabled"),
|
||||
Some(&Pref::new(true)));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -221,11 +221,6 @@ impl ToMarionette for GeckoContextParameters {
|
|||
}
|
||||
}
|
||||
|
||||
pub enum BrowserLauncher {
|
||||
None,
|
||||
BinaryLauncher(PathBuf),
|
||||
}
|
||||
|
||||
/// Logger levels from [Log.jsm]
|
||||
/// (https://developer.mozilla.org/en/docs/Mozilla/JavaScript_code_modules/Log.jsm).
|
||||
#[derive(Debug)]
|
||||
|
@ -271,156 +266,75 @@ impl FromStr for LogLevel {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct MarionetteSettings {
|
||||
pub port: Option<u16>,
|
||||
#[derive(Default)]
|
||||
pub struct FirefoxOptions {
|
||||
pub binary: Option<PathBuf>,
|
||||
pub connect_existing: bool,
|
||||
|
||||
/// Optionally increase Marionette's verbosity by providing a log
|
||||
/// level. The Gecko default is LogLevel::Info for optimised
|
||||
/// builds and LogLevel::Debug for debug builds.
|
||||
pub log_level: Option<LogLevel>,
|
||||
pub profile: Option<Profile>,
|
||||
pub args: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
pub struct MarionetteHandler {
|
||||
connection: Mutex<Option<MarionetteConnection>>,
|
||||
binary: Option<PathBuf>,
|
||||
connect_existing: bool,
|
||||
browser: Option<FirefoxRunner>,
|
||||
port: Option<u16>,
|
||||
log_level: Option<LogLevel>,
|
||||
}
|
||||
|
||||
impl MarionetteHandler {
|
||||
pub fn new(settings: MarionetteSettings) -> MarionetteHandler {
|
||||
MarionetteHandler {
|
||||
connection: Mutex::new(None),
|
||||
binary: settings.binary,
|
||||
connect_existing: settings.connect_existing,
|
||||
browser: None,
|
||||
port: settings.port,
|
||||
log_level: settings.log_level,
|
||||
}
|
||||
}
|
||||
|
||||
fn create_connection(&mut self, session_id: &Option<String>,
|
||||
capabilities: &NewSessionParameters) -> WebDriverResult<()> {
|
||||
let profile = try!(self.load_profile(capabilities));
|
||||
let args = try!(self.load_browser_args(capabilities));
|
||||
let port = match self.port {
|
||||
Some(x) => x,
|
||||
None => try!(get_free_port())
|
||||
};
|
||||
|
||||
let launcher = if self.connect_existing {
|
||||
BrowserLauncher::None
|
||||
impl FirefoxOptions {
|
||||
pub fn from_capabilities(capabilities: &mut NewSessionParameters) -> WebDriverResult<FirefoxOptions> {
|
||||
if let Some(options) = capabilities.consume("firefoxOptions") {
|
||||
let firefox_options = try!(options
|
||||
.as_object()
|
||||
.ok_or(WebDriverError::new(
|
||||
ErrorStatus::InvalidArgument,
|
||||
"'firefoxOptions' capability was not an object")));
|
||||
let binary = try!(FirefoxOptions::load_binary(&firefox_options));
|
||||
let profile = try!(FirefoxOptions::load_profile(&firefox_options));
|
||||
let args = try!(FirefoxOptions::load_args(&firefox_options));
|
||||
Ok(FirefoxOptions {
|
||||
binary: binary,
|
||||
profile: profile,
|
||||
args: args,
|
||||
})
|
||||
} else {
|
||||
let binary = try!(self.binary_path(capabilities));
|
||||
if let Some(path) = binary {
|
||||
BrowserLauncher::BinaryLauncher(path)
|
||||
} else {
|
||||
return Err(WebDriverError::new(ErrorStatus::UnknownError,
|
||||
"Expected browser binary location, \
|
||||
but unable to find binary in default location, \
|
||||
no 'firefox_binary' capability provided, \
|
||||
and no binary flag set on the command line"));
|
||||
}
|
||||
};
|
||||
match self.start_browser(launcher, port, profile, args) {
|
||||
Err(e) => {
|
||||
return Err(WebDriverError::new(ErrorStatus::UnknownError,
|
||||
e.description().to_owned()));
|
||||
},
|
||||
Ok(_) => {}
|
||||
Ok(Default::default())
|
||||
}
|
||||
|
||||
let mut connection = MarionetteConnection::new(port, session_id.clone());
|
||||
try!(connection.connect());
|
||||
self.connection = Mutex::new(Some(connection));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start_browser(&mut self, launcher: BrowserLauncher, port: u16, profile: Option<Profile>, args: Option<Vec<String>>) -> Result<(), RunnerError> {
|
||||
let custom_profile = profile.is_some();
|
||||
|
||||
match launcher {
|
||||
BrowserLauncher::BinaryLauncher(ref binary) => {
|
||||
let mut runner = try!(FirefoxRunner::new(&binary, profile));
|
||||
if let Some(cmd_args) = args {
|
||||
runner.args().extend(cmd_args);
|
||||
};
|
||||
|
||||
try!(self.set_prefs(port, &mut runner.profile, custom_profile));
|
||||
|
||||
info!("Starting browser {}", binary.to_string_lossy());
|
||||
try!(runner.start());
|
||||
|
||||
self.browser = Some(runner);
|
||||
},
|
||||
BrowserLauncher::None => {}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn set_prefs(&self, port: u16, profile: &mut Profile, custom_profile: bool)
|
||||
-> Result<(), RunnerError> {
|
||||
let prefs = try!(profile.user_prefs());
|
||||
prefs.insert("marionette.defaultPrefs.port", Pref::new(port as i64));
|
||||
|
||||
prefs.insert_slice(&FIREFOX_REQUIRED_PREFERENCES[..]);
|
||||
if !custom_profile {
|
||||
prefs.insert_slice(&FIREFOX_DEFAULT_PREFERENCES[..]);
|
||||
};
|
||||
if let Some(ref l) = self.log_level {
|
||||
prefs.insert("marionette.logging", Pref::new(l.to_string()));
|
||||
};
|
||||
|
||||
try!(prefs.write());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn binary_path(&self, capabilities: &NewSessionParameters) -> WebDriverResult<Option<PathBuf>> {
|
||||
if let Some(binary_capability) = capabilities.get("firefox_binary") {
|
||||
Ok(Some(PathBuf::from(try!(binary_capability
|
||||
fn load_binary(options: &BTreeMap<String, Json>) -> WebDriverResult<Option<PathBuf>> {
|
||||
if let Some(path) = options.get("binary") {
|
||||
Ok(Some(PathBuf::from(try!(path
|
||||
.as_string()
|
||||
.ok_or(WebDriverError::new(
|
||||
ErrorStatus::InvalidArgument,
|
||||
"'firefox_binary' capability was not a string"))))))
|
||||
} else if self.binary.is_some() {
|
||||
Ok(self.binary.as_ref().map(|x| x.clone()))
|
||||
"'binary' capability was not a string"))))))
|
||||
} else {
|
||||
Ok(firefox_default_path())
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_profile(&self, capabilities: &NewSessionParameters) -> WebDriverResult<Option<Profile>> {
|
||||
let profile_opt = capabilities.get("firefox_profile");
|
||||
if profile_opt.is_none() {
|
||||
return Ok(None);
|
||||
fn load_profile(options: &BTreeMap<String, Json>) -> WebDriverResult<Option<Profile>> {
|
||||
if let Some(profile_json) = options.get("profile") {
|
||||
let profile_base64 = try!(profile_json
|
||||
.as_string()
|
||||
.ok_or(
|
||||
WebDriverError::new(ErrorStatus::UnknownError,
|
||||
"Profile was not a string")));
|
||||
let profile_zip = &*try!(profile_base64.from_base64());
|
||||
|
||||
// Create an emtpy profile directory
|
||||
let profile = try!(Profile::new(None));
|
||||
try!(unzip_buffer(profile_zip,
|
||||
profile.temp_dir
|
||||
.as_ref()
|
||||
.expect("Profile doesn't have a path")
|
||||
.path()));
|
||||
|
||||
Ok(Some(profile))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
debug!("Using custom profile");
|
||||
|
||||
let profile_json = profile_opt.unwrap();
|
||||
let profile_base64 = try!(profile_json.as_string().ok_or(
|
||||
WebDriverError::new(ErrorStatus::UnknownError,"Profile was not a string")));
|
||||
let profile_zip = &*try!(profile_base64.from_base64());
|
||||
|
||||
// Create an emtpy profile directory
|
||||
let profile = try!(Profile::new(None));
|
||||
try!(unzip_buffer(profile_zip,
|
||||
profile.temp_dir.as_ref().expect("Profile doesn't have a path").path()));
|
||||
|
||||
Ok(Some(profile))
|
||||
}
|
||||
|
||||
pub fn load_browser_args(&self, capabilities: &NewSessionParameters) -> WebDriverResult<Option<Vec<String>>> {
|
||||
if let Some(args_json) = capabilities.get("firefox_args") {
|
||||
fn load_args(options: &BTreeMap<String, Json>) -> WebDriverResult<Option<Vec<String>>> {
|
||||
if let Some(args_json) = options.get("args") {
|
||||
let args_array = try!(args_json.as_array()
|
||||
.ok_or(WebDriverError::new(ErrorStatus::UnknownError,
|
||||
"Arguments was not an array")));
|
||||
"Arguments were not an array")));
|
||||
let args = try!(args_array
|
||||
.iter()
|
||||
.map(|x| x.as_string().map(|x| x.to_owned()))
|
||||
|
@ -435,6 +349,118 @@ impl MarionetteHandler {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct MarionetteSettings {
|
||||
pub port: Option<u16>,
|
||||
pub binary: Option<PathBuf>,
|
||||
pub connect_existing: bool,
|
||||
|
||||
/// Optionally increase Marionette's verbosity by providing a log
|
||||
/// level. The Gecko default is LogLevel::Info for optimised
|
||||
/// builds and LogLevel::Debug for debug builds.
|
||||
pub log_level: Option<LogLevel>,
|
||||
}
|
||||
|
||||
impl Default for MarionetteSettings {
|
||||
fn default() -> MarionetteSettings {
|
||||
MarionetteSettings {
|
||||
port: None,
|
||||
binary: None,
|
||||
connect_existing: false,
|
||||
log_level: Some(LogLevel::Info),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct MarionetteHandler {
|
||||
connection: Mutex<Option<MarionetteConnection>>,
|
||||
settings: MarionetteSettings,
|
||||
browser: Option<FirefoxRunner>,
|
||||
}
|
||||
|
||||
impl MarionetteHandler {
|
||||
pub fn new(settings: MarionetteSettings) -> MarionetteHandler {
|
||||
MarionetteHandler {
|
||||
connection: Mutex::new(None),
|
||||
settings: settings,
|
||||
browser: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn create_connection(&mut self, session_id: &Option<String>,
|
||||
capabilities: &mut NewSessionParameters) -> WebDriverResult<()> {
|
||||
|
||||
let options = try!(FirefoxOptions::from_capabilities(capabilities));
|
||||
|
||||
let port = self.settings.port.unwrap_or(try!(get_free_port()));
|
||||
|
||||
if !self.settings.connect_existing {
|
||||
try!(self.start_browser(port, options));
|
||||
};
|
||||
|
||||
let mut connection = MarionetteConnection::new(port, session_id.clone());
|
||||
try!(connection.connect());
|
||||
self.connection = Mutex::new(Some(connection));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn start_browser(&mut self, port: u16, mut options: FirefoxOptions) -> WebDriverResult<()> {
|
||||
let binary = try!(self.binary_path(&mut options)
|
||||
.ok_or(WebDriverError::new(ErrorStatus::UnknownError,
|
||||
"Expected browser binary location, \
|
||||
but unable to find binary in default location, \
|
||||
no 'firefoxOptions.binary' capability provided, \
|
||||
and no binary flag set on the command line")));
|
||||
|
||||
let custom_profile = options.profile.is_some();
|
||||
|
||||
let mut runner = try!(FirefoxRunner::new(&binary, options.profile.take())
|
||||
.map_err(|e| WebDriverError::new(ErrorStatus::UnknownError,
|
||||
e.description().to_owned())));
|
||||
if let Some(args) = options.args.take() {
|
||||
runner.args().extend(args);
|
||||
};
|
||||
|
||||
try!(self.set_prefs(port, &mut runner.profile, custom_profile)
|
||||
.map_err(|e| WebDriverError::new(ErrorStatus::UnknownError,
|
||||
format!("Failed to set preferences:\n{}",
|
||||
e.description()))));
|
||||
|
||||
info!("Starting browser {}", binary.to_string_lossy());
|
||||
try!(runner.start()
|
||||
.map_err(|e| WebDriverError::new(ErrorStatus::UnknownError,
|
||||
format!("Failed to start browser:\n{}",
|
||||
e.description()))));
|
||||
|
||||
self.browser = Some(runner);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn binary_path(&self, options: &mut FirefoxOptions) -> Option<PathBuf> {
|
||||
options.binary.take()
|
||||
.or_else(|| self.settings.binary.as_ref().map(|x| x.clone()))
|
||||
.or_else(|| firefox_default_path())
|
||||
}
|
||||
|
||||
pub fn set_prefs(&self, port: u16, profile: &mut Profile, custom_profile: bool)
|
||||
-> Result<(), RunnerError> {
|
||||
let prefs = try!(profile.user_prefs());
|
||||
prefs.insert("marionette.defaultPrefs.port", Pref::new(port as i64));
|
||||
|
||||
prefs.insert_slice(&FIREFOX_REQUIRED_PREFERENCES[..]);
|
||||
if !custom_profile {
|
||||
prefs.insert_slice(&FIREFOX_DEFAULT_PREFERENCES[..]);
|
||||
};
|
||||
if let Some(ref l) = self.settings.log_level {
|
||||
prefs.insert("marionette.logging", Pref::new(l.to_string()));
|
||||
};
|
||||
|
||||
try!(prefs.write());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn unzip_buffer(buf: &[u8], dest_dir: &Path) -> WebDriverResult<()> {
|
||||
let reader = Cursor::new(buf);
|
||||
let mut zip = try!(zip::ZipArchive::new(reader).map_err(|_| {
|
||||
|
@ -484,37 +510,39 @@ fn unzip_buffer(buf: &[u8], dest_dir: &Path) -> WebDriverResult<()> {
|
|||
}
|
||||
|
||||
impl WebDriverHandler<GeckoExtensionRoute> for MarionetteHandler {
|
||||
fn handle_command(&mut self, _: &Option<Session>, msg: &WebDriverMessage<GeckoExtensionRoute>) -> WebDriverResult<WebDriverResponse> {
|
||||
let mut new_capabilities = None;
|
||||
match self.connection.lock() {
|
||||
Ok(ref mut connection) => {
|
||||
if connection.is_none() {
|
||||
match msg.command {
|
||||
NewSession(ref capabilities) => {
|
||||
new_capabilities = Some(capabilities)
|
||||
},
|
||||
_ => {
|
||||
return Err(WebDriverError::new(
|
||||
ErrorStatus::UnknownError,
|
||||
"Tried to run command without establishing a connection"));
|
||||
fn handle_command(&mut self, _: &Option<Session>, mut msg: WebDriverMessage<GeckoExtensionRoute>) -> WebDriverResult<WebDriverResponse> {
|
||||
{
|
||||
let mut new_capabilities = None;
|
||||
match self.connection.lock() {
|
||||
Ok(ref connection) => {
|
||||
if connection.is_none() {
|
||||
match msg.command {
|
||||
NewSession(ref mut capabilities) => {
|
||||
new_capabilities = Some(capabilities);
|
||||
},
|
||||
_ => {
|
||||
return Err(WebDriverError::new(
|
||||
ErrorStatus::UnknownError,
|
||||
"Tried to run command without establishing a connection"));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Err(_) => {
|
||||
return Err(WebDriverError::new(
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to aquire Marionette connection"))
|
||||
}
|
||||
},
|
||||
Err(_) => {
|
||||
return Err(WebDriverError::new(
|
||||
ErrorStatus::UnknownError,
|
||||
"Failed to aquire Marionette connection"))
|
||||
}
|
||||
if let Some(capabilities) = new_capabilities {
|
||||
try!(self.create_connection(&msg.session_id, capabilities));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(capabilities) = new_capabilities {
|
||||
try!(self.create_connection(&msg.session_id, &capabilities));
|
||||
}
|
||||
match self.connection.lock() {
|
||||
Ok(ref mut connection) => {
|
||||
match connection.as_mut() {
|
||||
Some(conn) => conn.send_command(msg),
|
||||
Some(conn) => conn.send_command(&msg),
|
||||
None => panic!()
|
||||
}
|
||||
},
|
||||
|
@ -606,7 +634,7 @@ impl MarionetteSession {
|
|||
self.command_id
|
||||
}
|
||||
|
||||
pub fn response(&mut self, message: &WebDriverMessage<GeckoExtensionRoute>,
|
||||
pub fn response(&mut self, msg: &WebDriverMessage<GeckoExtensionRoute>,
|
||||
resp: MarionetteResponse) -> WebDriverResult<WebDriverResponse> {
|
||||
|
||||
if resp.id != self.command_id {
|
||||
|
@ -621,9 +649,9 @@ impl MarionetteSession {
|
|||
return Err(WebDriverError::new(status, error.message));
|
||||
}
|
||||
|
||||
try!(self.update(message, &resp));
|
||||
try!(self.update(msg, &resp));
|
||||
|
||||
Ok(match message.command {
|
||||
Ok(match msg.command {
|
||||
//Everything that doesn't have a response value
|
||||
Get(_) | GoBack | GoForward | Refresh | Close | SetTimeouts(_) |
|
||||
SetWindowSize(_) | MaximizeWindow | SwitchToWindow(_) | SwitchToFrame(_) |
|
||||
|
|
Загрузка…
Ссылка в новой задаче