332 lines
9.1 KiB
Rust
332 lines
9.1 KiB
Rust
/* 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/. */
|
||
|
||
use crate::common::{Cookie, CredentialParameters};
|
||
use serde::ser::{Serialize, Serializer};
|
||
use serde_json::Value;
|
||
|
||
#[derive(Debug, PartialEq, Serialize)]
|
||
#[serde(untagged, remote = "Self")]
|
||
pub enum WebDriverResponse {
|
||
NewWindow(NewWindowResponse),
|
||
CloseWindow(CloseWindowResponse),
|
||
Cookie(CookieResponse),
|
||
Cookies(CookiesResponse),
|
||
DeleteSession,
|
||
ElementRect(ElementRectResponse),
|
||
Generic(ValueResponse),
|
||
WebAuthnAddVirtualAuthenticator(u64),
|
||
WebAuthnGetCredentials(GetCredentialsResponse),
|
||
NewSession(NewSessionResponse),
|
||
Timeouts(TimeoutsResponse),
|
||
Void,
|
||
WindowRect(WindowRectResponse),
|
||
}
|
||
|
||
impl Serialize for WebDriverResponse {
|
||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||
where
|
||
S: Serializer,
|
||
{
|
||
#[derive(Serialize)]
|
||
struct Wrapper<'a> {
|
||
#[serde(with = "WebDriverResponse")]
|
||
value: &'a WebDriverResponse,
|
||
}
|
||
|
||
Wrapper { value: self }.serialize(serializer)
|
||
}
|
||
}
|
||
|
||
#[derive(Debug, PartialEq, Serialize)]
|
||
pub struct NewWindowResponse {
|
||
pub handle: String,
|
||
#[serde(rename = "type")]
|
||
pub typ: String,
|
||
}
|
||
|
||
#[derive(Debug, PartialEq, Serialize)]
|
||
pub struct CloseWindowResponse(pub Vec<String>);
|
||
|
||
#[derive(Clone, Debug, PartialEq, Serialize)]
|
||
pub struct CookieResponse(pub Cookie);
|
||
|
||
#[derive(Debug, PartialEq, Serialize)]
|
||
pub struct CookiesResponse(pub Vec<Cookie>);
|
||
|
||
#[derive(Debug, PartialEq, Serialize)]
|
||
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, PartialEq, Serialize)]
|
||
pub struct GetCredentialsResponse(pub Vec<CredentialParameters>);
|
||
|
||
#[derive(Debug, PartialEq, Serialize)]
|
||
pub struct NewSessionResponse {
|
||
#[serde(rename = "sessionId")]
|
||
pub session_id: String,
|
||
pub capabilities: Value,
|
||
}
|
||
|
||
impl NewSessionResponse {
|
||
pub fn new(session_id: String, capabilities: Value) -> NewSessionResponse {
|
||
NewSessionResponse {
|
||
session_id,
|
||
capabilities,
|
||
}
|
||
}
|
||
}
|
||
|
||
#[derive(Debug, PartialEq, Serialize)]
|
||
pub struct TimeoutsResponse {
|
||
pub script: Option<u64>,
|
||
#[serde(rename = "pageLoad")]
|
||
pub page_load: u64,
|
||
pub implicit: u64,
|
||
}
|
||
|
||
impl TimeoutsResponse {
|
||
pub fn new(script: Option<u64>, page_load: u64, implicit: u64) -> TimeoutsResponse {
|
||
TimeoutsResponse {
|
||
script,
|
||
page_load,
|
||
implicit,
|
||
}
|
||
}
|
||
}
|
||
|
||
#[derive(Debug, PartialEq, Serialize)]
|
||
pub struct ValueResponse(pub Value);
|
||
|
||
#[derive(Debug, PartialEq, Serialize)]
|
||
pub struct WindowRectResponse {
|
||
/// `WindowProxy`’s [screenX] attribute.
|
||
///
|
||
/// [screenX]: https://drafts.csswg.org/cssom-view/#dom-window-screenx
|
||
pub x: i32,
|
||
|
||
/// `WindowProxy`’s [screenY] attribute.
|
||
///
|
||
/// [screenY]: https://drafts.csswg.org/cssom-view/#dom-window-screeny
|
||
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: 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: i32,
|
||
}
|
||
|
||
#[cfg(test)]
|
||
mod tests {
|
||
use serde_json::{json, Map};
|
||
|
||
use super::*;
|
||
use crate::common::Date;
|
||
use crate::test::assert_ser;
|
||
|
||
#[test]
|
||
fn test_json_new_window_response() {
|
||
let json = json!({"value": {"handle": "42", "type": "window"}});
|
||
let response = WebDriverResponse::NewWindow(NewWindowResponse {
|
||
handle: "42".into(),
|
||
typ: "window".into(),
|
||
});
|
||
|
||
assert_ser(&response, json);
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_close_window_response() {
|
||
assert_ser(
|
||
&WebDriverResponse::CloseWindow(CloseWindowResponse(vec!["1234".into()])),
|
||
json!({"value": ["1234"]}),
|
||
);
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_cookie_response_with_optional() {
|
||
let json = json!({"value": {
|
||
"name": "foo",
|
||
"value": "bar",
|
||
"path": "/",
|
||
"domain": "foo.bar",
|
||
"secure": true,
|
||
"httpOnly": false,
|
||
"expiry": 123,
|
||
"sameSite": "Strict",
|
||
}});
|
||
let response = WebDriverResponse::Cookie(CookieResponse(Cookie {
|
||
name: "foo".into(),
|
||
value: "bar".into(),
|
||
path: Some("/".into()),
|
||
domain: Some("foo.bar".into()),
|
||
expiry: Some(Date(123)),
|
||
secure: true,
|
||
http_only: false,
|
||
same_site: Some("Strict".into()),
|
||
}));
|
||
|
||
assert_ser(&response, json);
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_cookie_response_without_optional() {
|
||
let json = json!({"value": {
|
||
"name": "foo",
|
||
"value": "bar",
|
||
"path": "/",
|
||
"domain": null,
|
||
"secure": true,
|
||
"httpOnly": false,
|
||
}});
|
||
let response = WebDriverResponse::Cookie(CookieResponse(Cookie {
|
||
name: "foo".into(),
|
||
value: "bar".into(),
|
||
path: Some("/".into()),
|
||
domain: None,
|
||
expiry: None,
|
||
secure: true,
|
||
http_only: false,
|
||
same_site: None,
|
||
}));
|
||
|
||
assert_ser(&response, json);
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_cookies_response() {
|
||
let json = json!({"value": [{
|
||
"name": "name",
|
||
"value": "value",
|
||
"path": "/",
|
||
"domain": null,
|
||
"secure": true,
|
||
"httpOnly": false,
|
||
"sameSite": "None",
|
||
}]});
|
||
let response = WebDriverResponse::Cookies(CookiesResponse(vec![Cookie {
|
||
name: "name".into(),
|
||
value: "value".into(),
|
||
path: Some("/".into()),
|
||
domain: None,
|
||
expiry: None,
|
||
secure: true,
|
||
http_only: false,
|
||
same_site: Some("None".into()),
|
||
}]));
|
||
|
||
assert_ser(&response, json);
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_delete_session_response() {
|
||
assert_ser(&WebDriverResponse::DeleteSession, json!({ "value": null }));
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_element_rect_response() {
|
||
let json = json!({"value": {
|
||
"x": 0.0,
|
||
"y": 1.0,
|
||
"width": 2.0,
|
||
"height": 3.0,
|
||
}});
|
||
let response = WebDriverResponse::ElementRect(ElementRectResponse {
|
||
x: 0f64,
|
||
y: 1f64,
|
||
width: 2f64,
|
||
height: 3f64,
|
||
});
|
||
|
||
assert_ser(&response, json);
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_generic_value_response() {
|
||
let response = {
|
||
let mut value = Map::new();
|
||
value.insert(
|
||
"example".into(),
|
||
Value::Array(vec![Value::String("test".into())]),
|
||
);
|
||
WebDriverResponse::Generic(ValueResponse(Value::Object(value)))
|
||
};
|
||
assert_ser(&response, json!({"value": {"example": ["test"]}}));
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_new_session_response() {
|
||
let response =
|
||
WebDriverResponse::NewSession(NewSessionResponse::new("id".into(), json!({})));
|
||
assert_ser(
|
||
&response,
|
||
json!({"value": {"sessionId": "id", "capabilities": {}}}),
|
||
);
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_timeouts_response() {
|
||
assert_ser(
|
||
&WebDriverResponse::Timeouts(TimeoutsResponse::new(Some(1), 2, 3)),
|
||
json!({"value": {"script": 1, "pageLoad": 2, "implicit": 3}}),
|
||
);
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_timeouts_response_with_null_script_timeout() {
|
||
assert_ser(
|
||
&WebDriverResponse::Timeouts(TimeoutsResponse::new(None, 2, 3)),
|
||
json!({"value": {"script": null, "pageLoad": 2, "implicit": 3}}),
|
||
);
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_void_response() {
|
||
assert_ser(&WebDriverResponse::Void, json!({ "value": null }));
|
||
}
|
||
|
||
#[test]
|
||
fn test_json_window_rect_response() {
|
||
let json = json!({"value": {
|
||
"x": 0,
|
||
"y": 1,
|
||
"width": 2,
|
||
"height": 3,
|
||
}});
|
||
let response = WebDriverResponse::WindowRect(WindowRectResponse {
|
||
x: 0i32,
|
||
y: 1i32,
|
||
width: 2i32,
|
||
height: 3i32,
|
||
});
|
||
|
||
assert_ser(&response, json);
|
||
}
|
||
}
|