--- a/testing/geckodriver/CHANGES.md
+++ b/testing/geckodriver/CHANGES.md
@@ -2,30 +2,24 @@
All notable changes to this program is documented in this file.
## Unreleased
### Added
- Added crashreporter environment variables to better control the browser in case of crashes.
- Added preference `dom.file.createInChild` set to true to allow file object creation in content processes.
-- New window `state` field on the window rect response object, returned from [`GetWindowRect`], [`SetWindowRect`], [`MinimizeWindow`], [`MaximizeWindow`], and [`FullscreenWindow`] commands
-
-[`FullscreenWindow`]: https://docs.rs/webdriver/0.29.0/webdriver/command/enum.WebDriverCommand.html#variant.FullscreenWindow
-[`GetWindowRect`]: https://docs.rs/webdriver/0.29.0/webdriver/command/enum.WebDriverCommand.html#variant.GetWindowRect
-[`MaximizeWindow`]: https://docs.rs/webdriver/0.29.0/webdriver/command/enum.WebDriverCommand.html#variant.MaximizeWindow
-[`MinimizeWindow`]: https://docs.rs/webdriver/0.29.0/webdriver/command/enum.WebDriverCommand.html#variant.MinimizeWindow
-[`SetWindowRect`]: https://docs.rs/webdriver/0.29.0/webdriver/command/enum.WebDriverCommand.html#variant.SetWindowRect
### Changed
- Removed deprecated `socksProxyVersion` in favor of `socksVersion`.
- Removed `ftpProxyPort`, `httpProxyPort`, `sslProxyPort`, and `socksProxyPort` because _ports_ have to be set for `ftpProxy`, `httpProxy`, `sslProxy`, and `socksProxy` using ":<PORT>".
- To make sure no browser process is left behind when the [`New Session` command](https://docs.rs/webdriver/0.27.0/webdriver/command/enum.WebDriverCommand.html#variant.NewSession) fails, the process is closed immediately now.
- The `proxyType` `noproxy` has been replaced with `direct` in accordance with recent WebDriver specification changes
- `/moz/addon/install` command accepts an `addon` parameter, in lieu of `path`, containing an addon as a Base64 string
+- The [`WindowRectParameters`](https://docs.rs/webdriver/0.30.0/webdriver/command/struct.WindowRectParameters.html have been updated to return signed 32-bit integers in accordance with the CSS and WebDriver specifications, and to be more liberal with the input types
- [webdriver crate](https://crates.io/crates/webdriver) upgraded to version 0.30.0
- [mozrunner crate](https://crates.io/crates/mozrunner) upgraded to version 0.4.2
## 0.18.0 (2017-07-10)
### Changed
- [`RectResponse`](https://docs.rs/webdriver/0.27.0/webdriver/response/struct.RectResponse.html) permits returning floats for `width` and `height` fields
- New type [`CookieResponse`](https://docs.rs/webdriver/0.27.0/webdriver/response/struct.CookieResponse.html) for the [`GetNamedCookie` command](https://docs.rs/webdriver/0.27.0/webdriver/command/enum.WebDriverCommand.html#variant.GetNamedCookie) returns a single cookie, as opposed to an array of a single cookie
--- a/testing/geckodriver/src/marionette.rs
+++ b/testing/geckodriver/src/marionette.rs
@@ -774,42 +774,47 @@ impl MarionetteSession {
let rect = ElementRectResponse { x, y, width, height };
WebDriverResponse::ElementRect(rect)
},
FullscreenWindow | MinimizeWindow | MaximizeWindow | GetWindowRect |
SetWindowRect(_) => {
let width = try_opt!(
try_opt!(resp.result.find("width"),
ErrorStatus::UnknownError,
- "Failed to find width field").as_f64(),
+ "Failed to find width field").as_u64(),
ErrorStatus::UnknownError,
- "Failed to interpret width as float");
+ "Failed to interpret width as positive integer");
let height = try_opt!(
try_opt!(resp.result.find("height"),
ErrorStatus::UnknownError,
- "Failed to find height field").as_f64(),
+ "Failed to find heigenht field").as_u64(),
ErrorStatus::UnknownError,
- "Failed to interpret height as float");
+ "Failed to interpret height as positive integer");
let x = try_opt!(
try_opt!(resp.result.find("x"),
ErrorStatus::UnknownError,
- "Failed to find x field").as_f64(),
+ "Failed to find x field").as_i64(),
ErrorStatus::UnknownError,
- "Failed to interpret x as float");
+ "Failed to interpret x as integer");
let y = try_opt!(
try_opt!(resp.result.find("y"),
ErrorStatus::UnknownError,
- "Failed to find y field").as_f64(),
+ "Failed to find y field").as_i64(),
ErrorStatus::UnknownError,
- "Failed to interpret y as float");
+ "Failed to interpret y as integer");
- let rect = WindowRectResponse { x, y, width, height };
+ let rect = WindowRectResponse {
+ x: x as i32,
+ y: y as i32,
+ width: width as i32,
+ height: height as i32,
+ };
WebDriverResponse::WindowRect(rect)
},
GetCookies => {
let cookies = try!(self.process_cookies(&resp.result));
WebDriverResponse::Cookies(CookiesResponse { value: cookies })
},
GetNamedCookie(ref name) => {
let mut cookies = try!(self.process_cookies(&resp.result));
--- a/testing/web-platform/tests/webdriver/tests/contexts/maximize_window.py
+++ b/testing/web-platform/tests/webdriver/tests/contexts/maximize_window.py
@@ -186,33 +186,60 @@ def test_maximize(session):
response = maximize(session)
assert_success(response)
assert before_size != session.window.size
def test_payload(session):
+ """
+ 7. Return success with the JSON serialization of the current top-level
+ browsing context's window rect.
+
+ [...]
+
+ A top-level browsing context's window rect is defined as a
+ dictionary of the screenX, screenY, width and height attributes of
+ the WindowProxy. Its JSON representation is the following:
+
+ "x"
+ WindowProxy's screenX attribute.
+
+ "y"
+ WindowProxy's screenY attribute.
+
+ "width"
+ Width of the top-level browsing context's outer dimensions,
+ including any browser chrome and externally drawn window
+ decorations in CSS reference pixels.
+
+ "height"
+ Height of the top-level browsing context's outer dimensions,
+ including any browser chrome and externally drawn window
+ decorations in CSS reference pixels.
+
+ """
before_size = session.window.size
response = maximize(session)
# step 5
assert response.status == 200
assert isinstance(response.body["value"], dict)
value = response.body["value"]
assert "width" in value
assert "height" in value
assert "x" in value
assert "y" in value
- assert isinstance(value["width"], (int, float))
- assert isinstance(value["height"], (int, float))
- assert isinstance(value["x"], (int, float))
- assert isinstance(value["y"], (int, float))
+ assert isinstance(value["width"], int)
+ assert isinstance(value["height"], int)
+ assert isinstance(value["x"], int)
+ assert isinstance(value["y"], int)
assert before_size != session.window.size
def test_maximize_twice_is_idempotent(session):
first_response = maximize(session)
assert_success(first_response)
max_size = session.window.size
--- a/testing/web-platform/tests/webdriver/tests/fullscreen_window.py
+++ b/testing/web-platform/tests/webdriver/tests/fullscreen_window.py
@@ -146,81 +146,59 @@ def test_fullscreen(session):
context's active document's document element.
"""
response = fullscreen(session)
assert_success(response)
assert session.execute_script("return window.fullScreen") is True
-# 5. Return success with the JSON serialization of the current top-level
-# browsing context's window rect.
-#
-# [...]
-#
-# A top-level browsing context's window rect is defined as a
-# dictionary of the screenX, screenY, width and height attributes of the
-# WindowProxy. Its JSON representation is the following:
-#
-# x
-# WindowProxy's screenX attribute.
-#
-# y
-# WindowProxy's screenY attribute.
-#
-# width
-# Width of the top-level browsing context's outer dimensions,
-# including any browser chrome and externally drawn window
-# decorations in CSS reference pixels.
-#
-# height
-# Height of the top-level browsing context's outer dimensions,
-# including any browser chrome and externally drawn window decorations
-# in CSS reference pixels.
-#
-# state
-# The top-level browsing context's window state.
-#
-# [...]
-#
-# The top-level browsing context has an associated window state which
-# describes what visibility state its OS widget window is in. It can be
-# in one of the following states:
-#
-# "maximized"
-# The window is maximized.
-#
-# "minimized"
-# The window is iconified.
-#
-# "normal"
-# The window is shown normally.
-#
-# "fullscreen"
-# The window is in full screen mode.
-#
-# If for whatever reason the top-level browsing context's OS window
-# cannot enter either of the window states, or if this concept is not
-# applicable on the current system, the default state must be normal.
def test_payload(session):
+ """
+ 5. Return success with the JSON serialization of the current top-level
+ browsing context's window rect.
+
+ [...]
+
+ A top-level browsing context's window rect is defined as a
+ dictionary of the screenX, screenY, width and height attributes of
+ the WindowProxy. Its JSON representation is the following:
+
+ "x"
+ WindowProxy's screenX attribute.
+
+ "y"
+ WindowProxy's screenY attribute.
+
+ "width"
+ Width of the top-level browsing context's outer dimensions,
+ including any browser chrome and externally drawn window
+ decorations in CSS reference pixels.
+
+ "height"
+ Height of the top-level browsing context's outer dimensions,
+ including any browser chrome and externally drawn window
+ decorations in CSS reference pixels.
+
+ """
response = fullscreen(session)
# step 5
assert response.status == 200
assert isinstance(response.body["value"], dict)
- rect = response.body["value"]
- assert "width" in rect
- assert "height" in rect
- assert "x" in rect
- assert "y" in rect
- assert isinstance(rect["width"], (int, float))
- assert isinstance(rect["height"], (int, float))
- assert isinstance(rect["x"], (int, float))
- assert isinstance(rect["y"], (int, float))
+ value = response.body["value"]
+ assert "width" in value
+ assert "height" in value
+ assert "x" in value
+ assert "y" in value
+ assert isinstance(value["width"], int)
+ assert isinstance(value["height"], int)
+ assert isinstance(value["x"], int)
+ assert isinstance(value["y"], int)
def test_fullscreen_twice_is_idempotent(session):
assert session.execute_script("return window.fullScreen") is False
first_response = fullscreen(session)
assert_success(first_response)
assert session.execute_script("return window.fullScreen") is True
--- a/testing/web-platform/tests/webdriver/tests/minimize_window.py
+++ b/testing/web-platform/tests/webdriver/tests/minimize_window.py
@@ -161,33 +161,59 @@ def test_minimize(session):
response = minimize(session)
assert_success(response)
assert session.execute_script("return document.hidden")
def test_payload(session):
+ """
+ 6. Return success with the JSON serialization of the current top-level
+ browsing context's window rect.
+
+ [...]
+
+ A top-level browsing context's window rect is defined as a
+ dictionary of the screenX, screenY, width and height attributes of
+ the WindowProxy. Its JSON representation is the following:
+
+ "x"
+ WindowProxy's screenX attribute.
+
+ "y"
+ WindowProxy's screenY attribute.
+
+ "width"
+ Width of the top-level browsing context's outer dimensions,
+ including any browser chrome and externally drawn window
+ decorations in CSS reference pixels.
+
+ "height"
+ Height of the top-level browsing context's outer dimensions,
+ including any browser chrome and externally drawn window
+ decorations in CSS reference pixels.
+
+ """
assert not session.execute_script("return document.hidden")
response = minimize(session)
- # step 5
assert response.status == 200
assert isinstance(response.body["value"], dict)
value = response.body["value"]
assert "width" in value
assert "height" in value
assert "x" in value
assert "y" in value
- assert isinstance(value["width"], (int, float))
- assert isinstance(value["height"], (int, float))
- assert isinstance(value["x"], (int, float))
- assert isinstance(value["y"], (int, float))
+ assert isinstance(value["width"], int)
+ assert isinstance(value["height"], int)
+ assert isinstance(value["x"], int)
+ assert isinstance(value["y"], int)
assert session.execute_script("return document.hidden")
def test_minimize_twice_is_idempotent(session):
assert not session.execute_script("return document.hidden")
first_response = minimize(session)
--- a/testing/web-platform/tests/webdriver/tests/set_window_rect.py
+++ b/testing/web-platform/tests/webdriver/tests/set_window_rect.py
@@ -1,31 +1,33 @@
+# META: timeout=long
+
import pytest
-from support.inline import inline
-from support.fixtures import create_dialog
-from support.asserts import assert_error, assert_dialog_handled, assert_success
+from tests.support.asserts import assert_error, assert_dialog_handled, assert_success
+from tests.support.fixtures import create_dialog
+from tests.support.inline import inline
alert_doc = inline("<script>window.alert()</script>")
def set_window_rect(session, rect):
return session.transport.send("POST", "session/%s/window/rect" % session.session_id, rect)
# 10.7.2 Set Window Rect
def test_current_top_level_browsing_context_no_longer_open(session, create_window):
"""
1. If the current top-level browsing context is no longer open,
return error with error code no such window.
+
"""
-
session.window_handle = create_window()
session.close()
response = set_window_rect(session, {})
assert_error(response, "no such window")
def test_handle_prompt_dismiss():
"""TODO"""
@@ -46,37 +48,36 @@ def test_handle_prompt_accept(new_sessio
user prompt handler:
[...]
- accept state
Accept the current user prompt.
"""
-
_, session = new_session(
{"alwaysMatch": {"unhandledPromptBehavior": "accept"}})
original = session.window.rect
# step 2
create_dialog(session)("alert", text="dismiss #1", result_var="dismiss1")
- result = set_window_rect(session, {"x": int(original["x"]),
- "y": int(original["y"])})
+ result = set_window_rect(session, {"x": original["x"],
+ "y": original["y"]})
assert result.status == 200
assert_dialog_handled(session, "dismiss #1")
create_dialog(session)("confirm", text="dismiss #2", result_var="dismiss2")
- result = set_window_rect(session, {"x": int(original["x"]),
- "y": int(original["y"])})
+ result = set_window_rect(session, {"x": original["x"],
+ "y": original["y"]})
assert result.status == 200
assert_dialog_handled(session, "dismiss #2")
create_dialog(session)("prompt", text="dismiss #3", result_var="dismiss3")
- result = set_window_rect(session, {"x": int(original["x"]),
- "y": int(original["y"])})
+ result = set_window_rect(session, {"x": original["x"],
+ "y": original["y"]})
assert_success(result)
assert_dialog_handled(session, "dismiss #3")
def test_handle_prompt_dismiss_and_notify():
"""TODO"""
@@ -110,32 +111,32 @@ def test_handle_prompt_missing_value(ses
"""
original = session.window.rect
# step 2
create_dialog("alert", text="dismiss #1", result_var="dismiss1")
- result = set_window_rect(session, {"x": int(original["x"]),
- "y": int(original["y"])})
+ result = set_window_rect(session, {"x": original["x"],
+ "y": original["y"]})
assert_error(result, "unexpected alert open")
assert_dialog_handled(session, "dismiss #1")
create_dialog("confirm", text="dismiss #2", result_var="dismiss2")
- result = set_window_rect(session, {"x": int(original["x"]),
- "y": int(original["y"])})
+ result = set_window_rect(session, {"x": original["x"],
+ "y": original["y"]})
assert_error(result, "unexpected alert open")
assert_dialog_handled(session, "dismiss #2")
create_dialog("prompt", text="dismiss #3", result_var="dismiss3")
- result = set_window_rect(session, {"x": int(original["x"]),
- "y": int(original["y"])})
+ result = set_window_rect(session, {"x": original["x"],
+ "y": original["y"]})
assert_error(result, "unexpected alert open")
assert_dialog_handled(session, "dismiss #3")
@pytest.mark.parametrize("rect", [
{"width": "a"},
{"height": "b"},
{"width": "a", "height": "b"},
@@ -165,75 +166,75 @@ def test_handle_prompt_missing_value(ses
{"height": {}, "width": {}},
{"x": {}},
{"y": {}},
{"x": {}, "y": {}},
{"width": {}, "height": {}, "x": {}, "y": {}},
])
def test_invalid_types(session, rect):
"""
- 8. If width or height is neither null nor a Number from 0 to 2^64 -
+ 8. If width or height is neither null nor a Number from 0 to 2^31 -
1, return error with error code invalid argument.
- 9. If x or y is neither null nor a Number from -(263) to 263 - 1,
+ 9. If x or y is neither null nor a Number from -(2^31) to 2^31 - 1,
return error with error code invalid argument.
"""
response = set_window_rect(session, rect)
assert_error(response, "invalid argument")
@pytest.mark.parametrize("rect", [
{"width": -1},
{"height": -2},
{"width": -1, "height": -2},
])
def test_out_of_bounds(session, rect):
"""
- 8. If width or height is neither null nor a Number from 0 to 2^64 -
+ 8. If width or height is neither null nor a Number from 0 to 2^31 -
1, return error with error code invalid argument.
- 9. If x or y is neither null nor a Number from -(263) to 263 - 1,
+ 9. If x or y is neither null nor a Number from -(2^31) to 2^31 - 1,
return error with error code invalid argument.
"""
response = set_window_rect(session, rect)
assert_error(response, "invalid argument")
def test_width_height_floats(session):
"""
- 8. If width or height is neither null nor a Number from 0 to 2^64 -
+ 8. If width or height is neither null nor a Number from 0 to 2^31 -
1, return error with error code invalid argument.
"""
- response = set_window_rect(session, {"width": 200.5, "height": 400})
+ response = set_window_rect(session, {"width": 500.5, "height": 420})
value = assert_success(response)
- assert value["width"] == 200.2
- assert value["height"] == 400
+ assert value["width"] == 500
+ assert value["height"] == 420
- response = set_window_rect(session, {"width": 300, "height": 450.5})
+ response = set_window_rect(session, {"width": 500, "height": 450.5})
value = assert_success(response)
- assert value["width"] == 300
- assert value["height"] == 450.5
+ assert value["width"] == 500
+ assert value["height"] == 450
def test_x_y_floats(session):
"""
- 9. If x or y is neither null nor a Number from -(263) to 263 - 1,
+ 9. If x or y is neither null nor a Number from -(2^31) to 2^31 - 1,
return error with error code invalid argument.
"""
- response = set_window_rect(session, {"x": 200.5, "y": 400})
+ response = set_window_rect(session, {"x": 0.5, "y": 420})
value = assert_success(response)
- assert value["x"] == 200.2
- assert value["y"] == 400
+ assert value["x"] == 0
+ assert value["y"] == 420
- response = set_window_rect(session, {"x": 300, "y": 450.5})
+ response = set_window_rect(session, {"x": 100, "y": 450.5})
value = assert_success(response)
- assert value["x"] == 300
- assert value["y"] == 450.5
+ assert value["x"] == 100
+ assert value["y"] == 450
@pytest.mark.parametrize("rect", [
{},
{"width": None},
{"height": None},
{"width": None, "height": None},
@@ -389,32 +390,32 @@ def test_height_width_larger_than_max(se
assert rect["width"] >= max["width"]
assert rect["height"] >= max["height"]
def test_height_width_as_current(session):
original = session.window.rect
# step 12
- response = set_window_rect(session, {"width": int(original["width"]),
- "height": int(original["height"])})
+ response = set_window_rect(session, {"width": original["width"],
+ "height": original["height"]})
# step 14
assert_success(response, {"x": original["x"],
"y": original["y"],
"width": original["width"],
"height": original["height"]})
def test_x_y(session):
original = session.window.rect
# step 13
- response = set_window_rect(session, {"x": int(original["x"]) + 10,
- "y": int(original["y"]) + 10})
+ response = set_window_rect(session, {"x": original["x"] + 10,
+ "y": original["y"] + 10})
# step 14
assert_success(response, {"x": original["x"] + 10,
"y": original["y"] + 10,
"width": original["width"],
"height": original["height"]})
@@ -449,57 +450,57 @@ def test_negative_x_y(session):
assert_success(response, {"x": -8,
"y": -8,
"width": original["width"],
"height": original["height"]})
def test_move_to_same_position(session):
original_position = session.window.position
- position = session.window.position = (int(original_position[0]), int(original_position[1]))
+ position = session.window.position = original_position
assert position == original_position
def test_move_to_same_x(session):
original_x = session.window.position[0]
- position = session.window.position = (int(original_x), 345)
+ position = session.window.position = (original_x, 345)
assert position == (original_x, 345)
def test_move_to_same_y(session):
original_y = session.window.position[1]
- position = session.window.position = (456, int(original_y))
+ position = session.window.position = (456, original_y)
assert position == (456, original_y)
def test_resize_to_same_size(session):
original_size = session.window.size
- size = session.window.size = (int(original_size[0]), int(original_size[1]))
+ size = session.window.size = original_size
assert size == original_size
def test_resize_to_same_width(session):
original_width = session.window.size[0]
- size = session.window.size = (int(original_width), 345)
+ size = session.window.size = (original_width, 345)
assert size == (original_width, 345)
def test_resize_to_same_height(session):
original_height = session.window.size[1]
- size = session.window.size = (456, int(original_height))
+ size = session.window.size = (456, original_height)
assert size == (456, original_height)
def test_payload(session):
# step 14
response = set_window_rect(session, {"x": 400, "y": 400})
assert response.status == 200
assert isinstance(response.body["value"], dict)
- rect = response.body["value"]
- assert "width" in rect
- assert "height" in rect
- assert "x" in rect
- assert "y" in rect
- assert isinstance(rect["width"], (int, float))
- assert isinstance(rect["height"], (int, float))
- assert isinstance(rect["x"], (int, float))
- assert isinstance(rect["y"], (int, float))
+ value = response.body["value"]
+ assert "width" in value
+ assert "height" in value
+ assert "x" in value
+ assert "y" in value
+ assert isinstance(value["width"], int)
+ assert isinstance(value["height"], int)
+ assert isinstance(value["x"], int)
+ assert isinstance(value["y"], int)
--- a/testing/webdriver/src/command.rs
+++ b/testing/webdriver/src/command.rs
@@ -578,77 +578,112 @@ impl ToJson for TimeoutsParameters {
}
if let Some(ms) = self.implicit {
data.insert("implicit".into(), ms.to_json());
}
Json::Object(data)
}
}
+/// A top-level browsing context’s window rect is a dictionary of the
+/// [`screenX`], [`screenY`], `width`, and `height` attributes of the
+/// `WindowProxy`.
+///
+/// In some user agents the operating system’s window dimensions, including
+/// decorations, are provided by the proprietary `window.outerWidth` and
+/// `window.outerHeight` DOM properties.
+///
+/// [`screenX`]: https://w3c.github.io/webdriver/webdriver-spec.html#dfn-screenx
+/// [`screenY`]: https://w3c.github.io/webdriver/webdriver-spec.html#dfn-screeny
#[derive(Debug, PartialEq)]
pub struct WindowRectParameters {
- pub x: Nullable<i64>,
- pub y: Nullable<i64>,
- pub width: Nullable<u64>,
- pub height: Nullable<u64>,
+ pub x: Nullable<i32>,
+ pub y: Nullable<i32>,
+ pub width: Nullable<i32>,
+ pub height: Nullable<i32>,
}
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");
+ ErrorStatus::InvalidArgument, "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")))
- }))
- }
+ Some(json) => try!(Nullable::from_json(json, |n| {
+ let x = try_opt!(
+ n.as_f64(),
+ ErrorStatus::InvalidArgument,
+ "'x' is not a number"
+ ) as i64;
+ if x < i32::min_value() as i64 || x > i32::max_value() as i64 {
+ return Err(WebDriverError::new(
+ ErrorStatus::InvalidArgument,
+ "'x' is larger than i32",
+ ));
+ }
+ Ok(x as i32)
+ })),
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")))
- }))
- }
+ Some(json) => try!(Nullable::from_json(json, |n| {
+ let y = try_opt!(
+ n.as_f64(),
+ ErrorStatus::InvalidArgument,
+ "'y' is not a number"
+ ) as i64;
+ if y < i32::min_value() as i64 || y > i32::max_value() as i64 {
+ return Err(WebDriverError::new(
+ ErrorStatus::InvalidArgument,
+ "'y' is larger than i32",
+ ));
+ }
+ Ok(y as i32)
+ })),
None => Nullable::Null,
};
- Ok(WindowRectParameters {
- x: x,
- y: y,
- width: width,
- height: height,
- })
+ let width = match data.get("width") {
+ Some(json) => try!(Nullable::from_json(json, |n| {
+ let width = try_opt!(
+ n.as_f64(),
+ ErrorStatus::InvalidArgument,
+ "'width' is not a number"
+ ) as i64;
+ if width < 0 || width > i32::max_value() as i64 {
+ return Err(WebDriverError::new(
+ ErrorStatus::InvalidArgument,
+ "'width' is larger than i32",
+ ));
+ }
+ Ok(width as i32)
+ })),
+ None => Nullable::Null,
+ };
+
+ let height = match data.get("height") {
+ Some(json) => try!(Nullable::from_json(json, |n| {
+ let height = try_opt!(
+ n.as_f64(),
+ ErrorStatus::InvalidArgument,
+ "'height' is not a positive integer"
+ ) as i64;
+ if height < 0 || height > i32::max_value() as i64 {
+ return Err(WebDriverError::new(
+ ErrorStatus::InvalidArgument,
+ "'height' is larger than i32",
+ ));
+ }
+ Ok(height as i32)
+ })),
+ None => Nullable::Null,
+ };
+
+ Ok(WindowRectParameters { x, y, width, 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());
@@ -1703,41 +1738,53 @@ impl ToJson for PointerMoveAction {
#[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),
+ x: Nullable::Value(0i32),
+ y: Nullable::Value(1i32),
+ width: Nullable::Value(2i32),
+ height: Nullable::Value(3i32),
};
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),
+ x: Nullable::Value(0i32),
y: Nullable::Null,
- width: Nullable::Value(2u64),
+ width: Nullable::Value(2i32),
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),
+ x: Nullable::Value(0i32),
y: Nullable::Null,
- width: Nullable::Value(2u64),
+ width: Nullable::Value(2i32),
height: Nullable::Null,
};
let actual = Json::from_str(r#"{"x": 0, "width": 2}"#).unwrap();
assert_eq!(expected, Parameters::from_json(&actual).unwrap());
}
+
+ #[test]
+ fn test_window_rect_floats() {
+ let expected = WindowRectParameters {
+ x: Nullable::Value(1i32),
+ y: Nullable::Value(2i32),
+ width: Nullable::Value(3i32),
+ height: Nullable::Value(4i32),
+ };
+ let actual = Json::from_str(r#"{"x": 1.1, "y": 2.2, "width": 3.3, "height": 4.4}"#).unwrap();
+ assert_eq!(expected, Parameters::from_json(&actual).unwrap());
+ }
}
--- a/testing/webdriver/src/response.rs
+++ b/testing/webdriver/src/response.rs
@@ -138,32 +138,32 @@ pub struct ElementRectResponse {
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,
+ pub x: i32,
/// `WindowProxy`’s [screenY] attribute.
///
/// [screenY]: https://drafts.csswg.org/cssom-view/#dom-window-screeny
- pub y: f64,
+ pub y: i32,
/// 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,
+ pub width: i32,
/// 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,
+ pub height: i32,
}
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());
@@ -286,23 +286,23 @@ mod tests {
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,
+ x: 0i32,
+ y: 1i32,
+ width: 2i32,
+ height: 3i32,
};
let resp = WebDriverResponse::WindowRect(rect);
- let expected = r#"{"value": {"x": 0.0, "y": 1.0, "width": 2.0, "height": 3.0}}"#;
+ let expected = r#"{"value": {"x": 0, "y": 1, "width": 2, "height": 3}}"#;
test(resp, expected);
}
#[test]
fn test_new_session() {
let resp = WebDriverResponse::NewSession(
NewSessionResponse::new("test".into(),
Json::Object(BTreeMap::new())));