summaryrefslogtreecommitdiffstats
path: root/testing/geckodriver/marionette/src/webdriver.rs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--testing/geckodriver/marionette/src/webdriver.rs512
1 files changed, 512 insertions, 0 deletions
diff --git a/testing/geckodriver/marionette/src/webdriver.rs b/testing/geckodriver/marionette/src/webdriver.rs
new file mode 100644
index 0000000000..fa1a48927c
--- /dev/null
+++ b/testing/geckodriver/marionette/src/webdriver.rs
@@ -0,0 +1,512 @@
+/* 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 serde::{Deserialize, Serialize};
+use serde_json::Value;
+
+use crate::common::{from_cookie, from_name, to_cookie, to_name, Cookie, Frame, Timeouts, Window};
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct Url {
+ pub url: String,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct Locator {
+ pub using: Selector,
+ pub value: String,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub enum Selector {
+ #[serde(rename = "css selector")]
+ Css,
+ #[serde(rename = "link text")]
+ LinkText,
+ #[serde(rename = "partial link text")]
+ PartialLinkText,
+ #[serde(rename = "tag name")]
+ TagName,
+ #[serde(rename = "xpath")]
+ XPath,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct NewWindow {
+ #[serde(rename = "type", skip_serializing_if = "Option::is_none")]
+ pub type_hint: Option<String>,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct WindowRect {
+ #[serde(default, skip_serializing_if = "Option::is_none")]
+ pub x: Option<i32>,
+ #[serde(default, skip_serializing_if = "Option::is_none")]
+ pub y: Option<i32>,
+ #[serde(default, skip_serializing_if = "Option::is_none")]
+ pub width: Option<i32>,
+ #[serde(default, skip_serializing_if = "Option::is_none")]
+ pub height: Option<i32>,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct Keys {
+ pub text: String,
+ pub value: Vec<String>,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+#[serde(default, rename_all = "camelCase")]
+pub struct PrintParameters {
+ pub orientation: PrintOrientation,
+ pub scale: f64,
+ pub background: bool,
+ pub page: PrintPage,
+ pub margin: PrintMargins,
+ pub page_ranges: Vec<String>,
+ pub shrink_to_fit: bool,
+}
+
+impl Default for PrintParameters {
+ fn default() -> Self {
+ PrintParameters {
+ orientation: PrintOrientation::default(),
+ scale: 1.0,
+ background: false,
+ page: PrintPage::default(),
+ margin: PrintMargins::default(),
+ page_ranges: Vec::new(),
+ shrink_to_fit: true,
+ }
+ }
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+#[serde(rename_all = "lowercase")]
+pub enum PrintOrientation {
+ Landscape,
+ Portrait,
+}
+
+impl Default for PrintOrientation {
+ fn default() -> Self {
+ PrintOrientation::Portrait
+ }
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct PrintPage {
+ pub width: f64,
+ pub height: f64,
+}
+
+impl Default for PrintPage {
+ fn default() -> Self {
+ PrintPage {
+ width: 21.59,
+ height: 27.94,
+ }
+ }
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct PrintMargins {
+ pub top: f64,
+ pub bottom: f64,
+ pub left: f64,
+ pub right: f64,
+}
+
+impl Default for PrintMargins {
+ fn default() -> Self {
+ PrintMargins {
+ top: 1.0,
+ bottom: 1.0,
+ left: 1.0,
+ right: 1.0,
+ }
+ }
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct ScreenshotOptions {
+ pub id: Option<String>,
+ pub highlights: Vec<Option<String>>,
+ pub full: bool,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub struct Script {
+ pub script: String,
+ pub args: Option<Vec<Value>>,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+pub enum Command {
+ #[serde(rename = "WebDriver:AcceptAlert")]
+ AcceptAlert,
+ #[serde(
+ rename = "WebDriver:AddCookie",
+ serialize_with = "to_cookie",
+ deserialize_with = "from_cookie"
+ )]
+ AddCookie(Cookie),
+ #[serde(rename = "WebDriver:CloseWindow")]
+ CloseWindow,
+ #[serde(
+ rename = "WebDriver:DeleteCookie",
+ serialize_with = "to_name",
+ deserialize_with = "from_name"
+ )]
+ DeleteCookie(String),
+ #[serde(rename = "WebDriver:DeleteAllCookies")]
+ DeleteCookies,
+ #[serde(rename = "WebDriver:DeleteSession")]
+ DeleteSession,
+ #[serde(rename = "WebDriver:DismissAlert")]
+ DismissAlert,
+ #[serde(rename = "WebDriver:ElementClear")]
+ ElementClear { id: String },
+ #[serde(rename = "WebDriver:ElementClick")]
+ ElementClick { id: String },
+ #[serde(rename = "WebDriver:ElementSendKeys")]
+ ElementSendKeys {
+ id: String,
+ text: String,
+ value: Vec<String>,
+ },
+ #[serde(rename = "WebDriver:ExecuteAsyncScript")]
+ ExecuteAsyncScript(Script),
+ #[serde(rename = "WebDriver:ExecuteScript")]
+ ExecuteScript(Script),
+ #[serde(rename = "WebDriver:FindElement")]
+ FindElement(Locator),
+ #[serde(rename = "WebDriver:FindElements")]
+ FindElements(Locator),
+ #[serde(rename = "WebDriver:FindElement")]
+ FindElementElement {
+ element: String,
+ using: Selector,
+ value: String,
+ },
+ #[serde(rename = "WebDriver:FindElements")]
+ FindElementElements {
+ element: String,
+ using: Selector,
+ value: String,
+ },
+ #[serde(rename = "WebDriver:FindElementFromShadowRoot")]
+ FindShadowRootElement {
+ #[serde(rename = "shadowRoot")]
+ shadow_root: String,
+ using: Selector,
+ value: String,
+ },
+ #[serde(rename = "WebDriver:FindElementsFromShadowRoot")]
+ FindShadowRootElements {
+ #[serde(rename = "shadowRoot")]
+ shadow_root: String,
+ using: Selector,
+ value: String,
+ },
+ #[serde(rename = "WebDriver:FullscreenWindow")]
+ FullscreenWindow,
+ #[serde(rename = "WebDriver:Navigate")]
+ Get(Url),
+ #[serde(rename = "WebDriver:GetActiveElement")]
+ GetActiveElement,
+ #[serde(rename = "WebDriver:GetAlertText")]
+ GetAlertText,
+ #[serde(rename = "WebDriver:GetComputedLabel")]
+ GetComputedLabel { id: String },
+ #[serde(rename = "WebDriver:GetComputedRole")]
+ GetComputedRole { id: String },
+ #[serde(rename = "WebDriver:GetCookies")]
+ GetCookies,
+ #[serde(rename = "WebDriver:GetElementCSSValue")]
+ GetCSSValue {
+ id: String,
+ #[serde(rename = "propertyName")]
+ property: String,
+ },
+ #[serde(rename = "WebDriver:GetCurrentURL")]
+ GetCurrentUrl,
+ #[serde(rename = "WebDriver:GetElementAttribute")]
+ GetElementAttribute { id: String, name: String },
+ #[serde(rename = "WebDriver:GetElementProperty")]
+ GetElementProperty { id: String, name: String },
+ #[serde(rename = "WebDriver:GetElementRect")]
+ GetElementRect { id: String },
+ #[serde(rename = "WebDriver:GetElementTagName")]
+ GetElementTagName { id: String },
+ #[serde(rename = "WebDriver:GetElementText")]
+ GetElementText { id: String },
+ #[serde(rename = "WebDriver:GetPageSource")]
+ GetPageSource,
+ #[serde(rename = "WebDriver:GetShadowRoot")]
+ GetShadowRoot { id: String },
+ #[serde(rename = "WebDriver:GetTimeouts")]
+ GetTimeouts,
+ #[serde(rename = "WebDriver:GetTitle")]
+ GetTitle,
+ #[serde(rename = "WebDriver:GetWindowHandle")]
+ GetWindowHandle,
+ #[serde(rename = "WebDriver:GetWindowHandles")]
+ GetWindowHandles,
+ #[serde(rename = "WebDriver:GetWindowRect")]
+ GetWindowRect,
+ #[serde(rename = "WebDriver:Back")]
+ GoBack,
+ #[serde(rename = "WebDriver:Forward")]
+ GoForward,
+ #[serde(rename = "WebDriver:IsElementDisplayed")]
+ IsDisplayed { id: String },
+ #[serde(rename = "WebDriver:IsElementEnabled")]
+ IsEnabled { id: String },
+ #[serde(rename = "WebDriver:IsElementSelected")]
+ IsSelected { id: String },
+ #[serde(rename = "WebDriver:MaximizeWindow")]
+ MaximizeWindow,
+ #[serde(rename = "WebDriver:MinimizeWindow")]
+ MinimizeWindow,
+ #[serde(rename = "WebDriver:NewWindow")]
+ NewWindow(NewWindow),
+ #[serde(rename = "WebDriver:Print")]
+ Print(PrintParameters),
+ #[serde(rename = "WebDriver:Refresh")]
+ Refresh,
+ #[serde(rename = "WebDriver:ReleaseActions")]
+ ReleaseActions,
+ #[serde(rename = "WebDriver:SendAlertText")]
+ SendAlertText(Keys),
+ #[serde(rename = "WebDriver:SetTimeouts")]
+ SetTimeouts(Timeouts),
+ #[serde(rename = "WebDriver:SetWindowRect")]
+ SetWindowRect(WindowRect),
+ #[serde(rename = "WebDriver:SwitchToFrame")]
+ SwitchToFrame(Frame),
+ #[serde(rename = "WebDriver:SwitchToParentFrame")]
+ SwitchToParentFrame,
+ #[serde(rename = "WebDriver:SwitchToWindow")]
+ SwitchToWindow(Window),
+ #[serde(rename = "WebDriver:TakeScreenshot")]
+ TakeElementScreenshot(ScreenshotOptions),
+ #[serde(rename = "WebDriver:TakeScreenshot")]
+ TakeFullScreenshot(ScreenshotOptions),
+ #[serde(rename = "WebDriver:TakeScreenshot")]
+ TakeScreenshot(ScreenshotOptions),
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::common::Date;
+ use crate::test::{assert_ser, assert_ser_de};
+ use serde_json::json;
+
+ #[test]
+ fn test_json_screenshot() {
+ let data = ScreenshotOptions {
+ id: None,
+ highlights: vec![],
+ full: false,
+ };
+ let json = json!({"full":false,"highlights":[],"id":null});
+ assert_ser_de(&data, json);
+ }
+
+ #[test]
+ fn test_json_selector_css() {
+ assert_ser_de(&Selector::Css, json!("css selector"));
+ }
+
+ #[test]
+ fn test_json_selector_link_text() {
+ assert_ser_de(&Selector::LinkText, json!("link text"));
+ }
+
+ #[test]
+ fn test_json_selector_partial_link_text() {
+ assert_ser_de(&Selector::PartialLinkText, json!("partial link text"));
+ }
+
+ #[test]
+ fn test_json_selector_tag_name() {
+ assert_ser_de(&Selector::TagName, json!("tag name"));
+ }
+
+ #[test]
+ fn test_json_selector_xpath() {
+ assert_ser_de(&Selector::XPath, json!("xpath"));
+ }
+
+ #[test]
+ fn test_json_selector_invalid() {
+ assert!(serde_json::from_value::<Selector>(json!("foo")).is_err());
+ }
+
+ #[test]
+ fn test_json_locator() {
+ let json = json!({
+ "using": "partial link text",
+ "value": "link text",
+ });
+ let data = Locator {
+ using: Selector::PartialLinkText,
+ value: "link text".into(),
+ };
+
+ assert_ser_de(&data, json);
+ }
+
+ #[test]
+ fn test_json_keys() {
+ let data = Keys {
+ text: "Foo".into(),
+ value: vec!["F".into(), "o".into(), "o".into()],
+ };
+ let json = json!({"text": "Foo", "value": ["F", "o", "o"]});
+ assert_ser_de(&data, json);
+ }
+
+ #[test]
+ fn test_json_new_window() {
+ let data = NewWindow {
+ type_hint: Some("foo".into()),
+ };
+ assert_ser_de(&data, json!({ "type": "foo" }));
+ }
+
+ #[test]
+ fn test_json_window_rect() {
+ let data = WindowRect {
+ x: Some(123),
+ y: None,
+ width: None,
+ height: None,
+ };
+ assert_ser_de(&data, json!({"x": 123}));
+ }
+
+ #[test]
+ fn test_command_with_params() {
+ let locator = Locator {
+ using: Selector::Css,
+ value: "value".into(),
+ };
+ let json = json!({"WebDriver:FindElement": {"using": "css selector", "value": "value"}});
+ assert_ser_de(&Command::FindElement(locator), json);
+ }
+
+ #[test]
+ fn test_command_with_wrapper_params() {
+ let cookie = Cookie {
+ name: "hello".into(),
+ value: "world".into(),
+ path: None,
+ domain: None,
+ secure: false,
+ http_only: false,
+ expiry: Some(Date(1564488092)),
+ same_site: None,
+ };
+ let json = json!({"WebDriver:AddCookie": {"cookie": {"name": "hello", "value": "world", "secure": false, "httpOnly": false, "expiry": 1564488092}}});
+ assert_ser_de(&Command::AddCookie(cookie), json);
+ }
+
+ #[test]
+ fn test_empty_commands() {
+ assert_ser_de(&Command::GetTimeouts, json!("WebDriver:GetTimeouts"));
+ }
+
+ #[test]
+ fn test_json_command_invalid() {
+ assert!(serde_json::from_value::<Command>(json!("foo")).is_err());
+ }
+
+ #[test]
+ fn test_json_delete_cookie_command() {
+ let json = json!({"WebDriver:DeleteCookie": {"name": "foo"}});
+ assert_ser_de(&Command::DeleteCookie("foo".into()), json);
+ }
+
+ #[test]
+ fn test_json_new_window_command() {
+ let data = NewWindow {
+ type_hint: Some("foo".into()),
+ };
+ let json = json!({"WebDriver:NewWindow": {"type": "foo"}});
+ assert_ser_de(&Command::NewWindow(data), json);
+ }
+
+ #[test]
+ fn test_json_new_window_command_with_none_value() {
+ let data = NewWindow { type_hint: None };
+ let json = json!({"WebDriver:NewWindow": {}});
+ assert_ser_de(&Command::NewWindow(data), json);
+ }
+
+ #[test]
+ fn test_json_command_as_struct() {
+ assert_ser(
+ &Command::FindElementElement {
+ element: "foo".into(),
+ using: Selector::XPath,
+ value: "bar".into(),
+ },
+ json!({"WebDriver:FindElement": {"element": "foo", "using": "xpath", "value": "bar" }}),
+ );
+ }
+
+ #[test]
+ fn test_json_get_computed_label_command() {
+ assert_ser_de(
+ &Command::GetComputedLabel { id: "foo".into() },
+ json!({"WebDriver:GetComputedLabel": {"id": "foo"}}),
+ );
+ }
+
+ #[test]
+ fn test_json_get_computed_role_command() {
+ assert_ser_de(
+ &Command::GetComputedRole { id: "foo".into() },
+ json!({"WebDriver:GetComputedRole": {"id": "foo"}}),
+ );
+ }
+
+ #[test]
+ fn test_json_get_css_value() {
+ assert_ser_de(
+ &Command::GetCSSValue {
+ id: "foo".into(),
+ property: "bar".into(),
+ },
+ json!({"WebDriver:GetElementCSSValue": {"id": "foo", "propertyName": "bar"}}),
+ );
+ }
+
+ #[test]
+ fn test_json_find_shadow_root_element() {
+ assert_ser_de(
+ &Command::FindShadowRootElement {
+ shadow_root: "foo".into(),
+ using: Selector::Css,
+ value: "bar".into(),
+ },
+ json!({"WebDriver:FindElementFromShadowRoot": {"shadowRoot": "foo", "using": "css selector", "value": "bar"}}),
+ );
+ }
+
+ #[test]
+ fn test_json_find_shadow_root_elements() {
+ assert_ser_de(
+ &Command::FindShadowRootElements {
+ shadow_root: "foo".into(),
+ using: Selector::Css,
+ value: "bar".into(),
+ },
+ json!({"WebDriver:FindElementsFromShadowRoot": {"shadowRoot": "foo", "using": "css selector", "value": "bar"}}),
+ );
+ }
+}