From 2fa004067b385072eb48b3fff0f9020a1fd52a9e Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 20 Nov 2017 14:47:27 -0500 Subject: [PATCH 1/4] Build the webdriver server by default. --- ports/servo/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/servo/Cargo.toml b/ports/servo/Cargo.toml index 4376a0accd0..4cd1b65037c 100644 --- a/ports/servo/Cargo.toml +++ b/ports/servo/Cargo.toml @@ -32,7 +32,7 @@ style_tests = {path = "../../tests/unit/style"} default = ["unstable", "default-except-unstable"] default-except-unstable = ["webdriver", "max_log_level"] max_log_level = ["log/release_max_level_info"] -webdriver = ["libservo/webdriver_server"] +webdriver = ["libservo/webdriver"] energy-profiling = ["libservo/energy-profiling"] debugmozjs = ["libservo/debugmozjs"] googlevr = ["libservo/googlevr"] From 6797c2f7c59415ad567e8b947a50f8fb415408f8 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 20 Nov 2017 14:47:54 -0500 Subject: [PATCH 2/4] Display full output when running individual webdriver tests. --- tests/wpt/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/wpt/run.py b/tests/wpt/run.py index 80bee213c5f..92a3a45ded8 100644 --- a/tests/wpt/run.py +++ b/tests/wpt/run.py @@ -35,7 +35,7 @@ def run_tests(paths=None, **kwargs): use_mach_logging = False if len(kwargs["test_list"]) == 1: file_ext = os.path.splitext(kwargs["test_list"][0])[1].lower() - if file_ext in [".htm", ".html", ".js", ".xhtml", ".xht"]: + if file_ext in [".htm", ".html", ".js", ".xhtml", ".xht", ".py"]: use_mach_logging = True if use_mach_logging: From 8761f53391b5bc79427ec1d5f099571c47c059e9 Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 20 Nov 2017 14:48:33 -0500 Subject: [PATCH 3/4] Use most recent webdriver test harness. --- tests/wpt/run.py | 1 + .../wptrunner/wptrunner/browsers/servo.py | 2 + .../wptrunner/executors/executorservo.py | 81 +------------------ .../wptrunner/wptrunner/webdriver_server.py | 5 +- 4 files changed, 10 insertions(+), 79 deletions(-) diff --git a/tests/wpt/run.py b/tests/wpt/run.py index 92a3a45ded8..46b5b1fab6f 100644 --- a/tests/wpt/run.py +++ b/tests/wpt/run.py @@ -65,6 +65,7 @@ def set_defaults(paths, kwargs): bin_path = servo_path("target", bin_dir, bin_name) kwargs["binary"] = bin_path + kwargs["webdriver_binary"] = bin_path if kwargs["processes"] is None: kwargs["processes"] = multiprocessing.cpu_count() diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/servo.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/servo.py index 89d69ab9e54..3738ce4bddc 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/servo.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/browsers/servo.py @@ -42,6 +42,8 @@ def executor_kwargs(test_type, server_config, cache_manager, run_info_data, rv = base_executor_kwargs(test_type, server_config, cache_manager, **kwargs) rv["pause_after_test"] = kwargs["pause_after_test"] + if test_type == "wdspec": + rv["capabilities"] = {} return rv diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorservo.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorservo.py index 97fe304305e..33ff10df928 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorservo.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/executors/executorservo.py @@ -18,7 +18,7 @@ from .base import (ExecutorException, RefTestImplementation, testharness_result_converter, reftest_result_converter, - WdspecExecutor) + WdspecExecutor, WebDriverProtocol) from .process import ProcessTestExecutor from ..browsers.base import browser_command from ..wpttest import WdspecResult, WdspecSubtestResult @@ -286,82 +286,9 @@ class ServoRefTestExecutor(ProcessTestExecutor): line, " ".join(self.command)) -class ServoWdspecProtocol(Protocol): - def __init__(self, executor, browser): - self.do_delayed_imports() - Protocol.__init__(self, executor, browser) - self.session = None - self.server = None - - def setup(self, runner): - try: - self.server = ServoDriverServer(self.logger, binary=self.browser.binary, binary_args=self.browser.binary_args) - self.server.start(block=False) - self.logger.info( - "WebDriver HTTP server listening at %s" % self.server.url) - - self.logger.info( - "Establishing new WebDriver session with %s" % self.server.url) - self.session = webdriver.Session( - self.server.host, self.server.port, self.server.base_path) - except Exception: - self.logger.error(traceback.format_exc()) - self.executor.runner.send_message("init_failed") - else: - self.executor.runner.send_message("init_succeeded") - - def teardown(self): - if self.server is not None: - try: - if self.session.session_id is not None: - self.session.end() - except Exception: - pass - if self.server.is_alive: - self.server.stop() - - @property - def is_alive(self): - conn = httplib.HTTPConnection(self.server.host, self.server.port) - conn.request("HEAD", self.server.base_path + "invalid") - res = conn.getresponse() - return res.status == 404 - - def do_delayed_imports(self): - global pytestrunner, webdriver - from . import pytestrunner - import webdriver +class ServoDriverProtocol(WebDriverProtocol): + server_cls = ServoDriverServer class ServoWdspecExecutor(WdspecExecutor): - def __init__(self, browser, server_config, - timeout_multiplier=1, close_after_done=True, debug_info=None, - **kwargs): - WdspecExecutor.__init__(self, browser, server_config, - timeout_multiplier=timeout_multiplier, - debug_info=debug_info) - self.protocol = ServoWdspecProtocol(self, browser) - - def is_alive(self): - return self.protocol.is_alive - - def on_environment_change(self, new_environment): - pass - - def do_test(self, test): - timeout = test.timeout * self.timeout_multiplier + extra_timeout - - success, data = WdspecRun(self.do_wdspec, - self.protocol.session, - test.path, - timeout).run() - - if success: - return self.convert_result(test, data) - - return (test.result_cls(*data), []) - - def do_wdspec(self, session, path, timeout): - harness_result = ("OK", None) - subtest_results = pytestrunner.run(path, session, timeout=timeout) - return (harness_result, subtest_results) + protocol_cls = ServoDriverProtocol diff --git a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/webdriver_server.py b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/webdriver_server.py index 4a3c48c5800..fc853bfb97e 100644 --- a/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/webdriver_server.py +++ b/tests/wpt/web-platform-tests/tools/wptrunner/wptrunner/webdriver_server.py @@ -195,10 +195,11 @@ class GeckoDriverServer(WebDriverServer): class ServoDriverServer(WebDriverServer): - def __init__(self, logger, binary="servo", binary_args=None, host="127.0.0.1", port=None): + def __init__(self, logger, binary="servo", binary_args=None, host="127.0.0.1", + port=None, args=None): env = os.environ.copy() env["RUST_BACKTRACE"] = "1" - WebDriverServer.__init__(self, logger, binary, host=host, port=port, env=env) + WebDriverServer.__init__(self, logger, binary, host=host, port=port, env=env, args=args) self.binary_args = binary_args def make_command(self): From babefa4caed3f1e4d2c8d32ea5c1030318ceb23a Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Mon, 20 Nov 2017 15:34:57 -0500 Subject: [PATCH 4/4] Update webdriver dependency. --- Cargo.lock | 18 +++++++--- components/webdriver_server/Cargo.toml | 2 +- components/webdriver_server/keys.rs | 6 ++-- components/webdriver_server/lib.rs | 48 +++++++++++++++++--------- servo-tidy.toml | 1 + 5 files changed, 50 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f42209392b..384692b52ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -521,6 +521,14 @@ dependencies = [ "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "cookie" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "core-foundation" version = "0.4.4" @@ -3596,16 +3604,17 @@ dependencies = [ [[package]] name = "webdriver" -version = "0.22.0" +version = "0.32.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", + "cookie 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", "hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3628,7 +3637,7 @@ dependencies = [ "servo_url 0.0.1", "url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "uuid 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "webdriver 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)", + "webdriver 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -3860,6 +3869,7 @@ dependencies = [ "checksum color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a475fc4af42d83d28adf72968d9bcfaf035a1a9381642d8e85d8a04957767b0d" "checksum compiletest_rs 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "617b23d0ed4f57b3bcff6b5fe0a78f0010f1efb636298317665a960b6dbc0533" "checksum cookie 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "30b3493e12a550c2f96be785088d1da8d93189e7237c8a8d0d871bc9070334c3" +"checksum cookie 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "477eb650753e319be2ae77ec368a58c638f9f0c4d941c39bad95e950fb1d1d0d" "checksum core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "5909502e547762013619f4c4e01cc7393c20fe2d52d7fa471c1210adb2320dc7" "checksum core-foundation-sys 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bc9fb3d6cb663e6fd7cf1c63f9b144ee2b1e4a78595a0451dd34bff85b9a3387" "checksum core-graphics 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2fd47addfc77b7e574d24e5434f95bb64a863769dfd4f1d451ca4ff5530ba01a" @@ -4099,7 +4109,7 @@ dependencies = [ "checksum vec_map 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cac5efe5cb0fa14ec2f84f83c701c562ee63f6dcc680861b21d65c682adfb05f" "checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" "checksum walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bb08f9e670fab86099470b97cd2b252d6527f0b3cc1401acdb595ffc9dd288ff" -"checksum webdriver 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d548aabf87411b1b4ba91fd07eacd8b238135c7131a452b8a9f6386209167e18" +"checksum webdriver 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b982fb5fe268cc124931035ca0c4b65d39e6d9c9fed319186b7d17493bf98984" "checksum webrender 0.53.2 (git+https://github.com/servo/webrender)" = "" "checksum webrender_api 0.53.2 (git+https://github.com/servo/webrender)" = "" "checksum which 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4be6cfa54dab45266e98b5d7be2f8ce959ddd49abd141a05d52dce4b07f803bb" diff --git a/components/webdriver_server/Cargo.toml b/components/webdriver_server/Cargo.toml index 6c1cc50e560..ddd46de18e8 100644 --- a/components/webdriver_server/Cargo.toml +++ b/components/webdriver_server/Cargo.toml @@ -26,4 +26,4 @@ servo_config = {path = "../config"} servo_url = {path = "../url"} url = "1.2" uuid = {version = "0.5", features = ["v4"]} -webdriver = "0.22" +webdriver = "0.32" diff --git a/components/webdriver_server/keys.rs b/components/webdriver_server/keys.rs index b52febc2b5e..d16f8232253 100644 --- a/components/webdriver_server/keys.rs +++ b/components/webdriver_server/keys.rs @@ -168,11 +168,11 @@ fn key_from_char(key_string: &char) -> Option<(Key, bool)> { } } -pub fn keycodes_to_keys(key_codes: &[char]) -> Result, String> { +pub fn keycodes_to_keys(key_codes: &str) -> Result, String> { let mut rv = vec![]; - for char_code in key_codes.iter() { - let (key, with_shift) = key_from_char(char_code).ok_or(format!("Unsupported character code {}", char_code))?; + for char_code in key_codes.chars() { + let (key, with_shift) = key_from_char(&char_code).ok_or(format!("Unsupported character code {}", char_code))?; let modifiers = if with_shift { KeyModifiers::SHIFT } else { diff --git a/components/webdriver_server/lib.rs b/components/webdriver_server/lib.rs index 28a4885f0d4..0b75dc4669c 100644 --- a/components/webdriver_server/lib.rs +++ b/components/webdriver_server/lib.rs @@ -52,13 +52,13 @@ use webdriver::command::{AddCookieParameters, GetParameters, JavascriptCommandPa use webdriver::command::{LocatorParameters, Parameters}; use webdriver::command::{SendKeysParameters, SwitchToFrameParameters, TimeoutsParameters}; use webdriver::command::{WebDriverCommand, WebDriverExtensionCommand, WebDriverMessage}; -use webdriver::command::WindowSizeParameters; +use webdriver::command::WindowRectParameters; use webdriver::common::{Date, LocatorStrategy, Nullable, WebElement}; use webdriver::error::{ErrorStatus, WebDriverError, WebDriverResult}; use webdriver::httpapi::WebDriverExtensionRoute; -use webdriver::response::{Cookie, CookieResponse}; +use webdriver::response::{Cookie, CookieResponse, CookiesResponse}; use webdriver::response::{ElementRectResponse, NewSessionResponse, ValueResponse}; -use webdriver::response::{WebDriverResponse, WindowSizeResponse}; +use webdriver::response::{WebDriverResponse, WindowRectResponse}; use webdriver::server::{self, Session, WebDriverHandler}; fn extension_routes() -> Vec<(Method, &'static str, ServoExtensionRoute)> { @@ -402,13 +402,23 @@ impl Handler { let window_size = receiver.recv().unwrap(); let vp = window_size.initial_viewport; - let window_size_response = WindowSizeResponse::new(vp.width as u64, vp.height as u64); - Ok(WebDriverResponse::WindowSize(window_size_response)) + let window_size_response = WindowRectResponse { + x: 0, y: 0, width: vp.width as i32, height: vp.height as i32 + }; + Ok(WebDriverResponse::WindowRect(window_size_response)) } - fn handle_set_window_size(&self, params: &WindowSizeParameters) -> WebDriverResult { + fn handle_set_window_size(&self, params: &WindowRectParameters) -> WebDriverResult { let (sender, receiver) = ipc::channel().unwrap(); - let size = Size2D::new(params.width as u32, params.height as u32); + let width = match params.width { + Nullable::Value(v) => v, + Nullable::Null => 0, + }; + let height = match params.height { + Nullable::Value(v) => v, + Nullable::Null => 0, + }; + let size = Size2D::new(width as u32, height as u32); let top_level_browsing_context_id = self.session()?.top_level_browsing_context_id; let cmd_msg = WebDriverCommandMsg::SetWindowSize(top_level_browsing_context_id, size, sender.clone()); @@ -426,8 +436,10 @@ impl Handler { let window_size = receiver.recv().unwrap(); let vp = window_size.initial_viewport; - let window_size_response = WindowSizeResponse::new(vp.width as u64, vp.height as u64); - Ok(WebDriverResponse::WindowSize(window_size_response)) + let window_size_response = WindowRectResponse { + x: 0, y: 0, width: vp.width as i32, height: vp.height as i32 + }; + Ok(WebDriverResponse::WindowRect(window_size_response)) } fn handle_is_enabled(&self, element: &WebElement) -> WebDriverResult { @@ -588,8 +600,10 @@ impl Handler { self.browsing_context_script_command(cmd)?; match receiver.recv().unwrap() { Ok(rect) => { - let response = ElementRectResponse::new(rect.origin.x, rect.origin.y, - rect.size.width, rect.size.height); + let response = ElementRectResponse { + x: rect.origin.x, y: rect.origin.y, + width: rect.size.width, height: rect.size.height + }; Ok(WebDriverResponse::ElementRect(response)) }, Err(_) => Err(WebDriverError::new(ErrorStatus::StaleElementReference, @@ -657,7 +671,7 @@ impl Handler { let response = cookies.into_iter().map(|cookie| { cookie_msg_to_cookie(cookie.into_inner()) }).collect::>(); - Ok(WebDriverResponse::Cookie(CookieResponse::new(response))) + Ok(WebDriverResponse::Cookies(CookiesResponse { value: response })) } fn handle_get_cookie(&self, name: &str) -> WebDriverResult { @@ -667,8 +681,8 @@ impl Handler { let cookies = receiver.recv().unwrap(); let response = cookies.into_iter().map(|cookie| { cookie_msg_to_cookie(cookie.into_inner()) - }).collect::>(); - Ok(WebDriverResponse::Cookie(CookieResponse::new(response))) + }).next().unwrap(); + Ok(WebDriverResponse::Cookie(CookieResponse { value: response })) } fn handle_add_cookie(&self, params: &AddCookieParameters) -> WebDriverResult { @@ -779,7 +793,7 @@ impl Handler { receiver.recv().unwrap().or_else(|_| Err(WebDriverError::new( ErrorStatus::StaleElementReference, "Element not found or not focusable")))?; - let keys = keycodes_to_keys(&keys.value).or_else(|_| + let keys = keycodes_to_keys(&keys.text).or_else(|_| Err(WebDriverError::new(ErrorStatus::UnsupportedOperation, "Failed to convert keycodes")))?; // TODO: there's a race condition caused by the focus command and the @@ -880,8 +894,8 @@ impl WebDriverHandler for Handler { WebDriverCommand::AddCookie(ref parameters) => self.handle_add_cookie(parameters), WebDriverCommand::Get(ref parameters) => self.handle_get(parameters), WebDriverCommand::GetCurrentUrl => self.handle_current_url(), - WebDriverCommand::GetWindowSize => self.handle_window_size(), - WebDriverCommand::SetWindowSize(ref size) => self.handle_set_window_size(size), + WebDriverCommand::GetWindowRect => self.handle_window_size(), + WebDriverCommand::SetWindowRect(ref size) => self.handle_set_window_size(size), WebDriverCommand::IsEnabled(ref element) => self.handle_is_enabled(element), WebDriverCommand::IsSelected(ref element) => self.handle_is_selected(element), WebDriverCommand::GoBack => self.handle_go_back(), diff --git a/servo-tidy.toml b/servo-tidy.toml index b2feec6577d..19b33a3643f 100644 --- a/servo-tidy.toml +++ b/servo-tidy.toml @@ -35,6 +35,7 @@ num = [] # Ignored packages with duplicated versions packages = [ "bitflags", + "cookie", "mime", "semver", "toml",