From b31b6ce779d547acc20512ce2ff758aa224b1b41 Mon Sep 17 00:00:00 2001 From: Jason Boatman Date: Thu, 27 Apr 2023 16:45:20 -0500 Subject: [PATCH] Implement wheel support. --- Cargo.lock | 4 +- Cargo.toml | 2 +- src/actions.rs | 119 ++++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 116 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a3b4317..7b0ff831 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1085,9 +1085,9 @@ dependencies = [ [[package]] name = "webdriver" -version = "0.46.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9973cb72c8587d5ad5efdb91e663d36177dc37725e6c90ca86c626b0cc45c93f" +checksum = "cf9ae70f0cb12332fe144def990a9e62b20db2361b8784f879bb2814aad6c763" dependencies = [ "base64", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 63c1bbf8..30e3d1f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,7 +23,7 @@ native-tls = ["hyper-tls"] rustls-tls = ["hyper-rustls"] [dependencies] -webdriver = { version = "0.46", default-features = false } +webdriver = { version = "0.48", default-features = false } url = "2.2.2" serde = { version = "1.0.103", features = ["derive"] } serde_json = "1.0.25" diff --git a/src/actions.rs b/src/actions.rs index 91bc5a23..05ce786a 100644 --- a/src/actions.rs +++ b/src/actions.rs @@ -190,8 +190,8 @@ impl PointerAction { WDActions::PointerAction::Move(WDActions::PointerMoveAction { duration: duration.map(|x| x.as_millis() as u64), origin: WDActions::PointerOrigin::Pointer, - x: Some(x), - y: Some(y), + x, + y, ..Default::default() }), ), @@ -199,8 +199,8 @@ impl PointerAction { WDActions::PointerAction::Move(WDActions::PointerMoveAction { duration: duration.map(|x| x.as_millis() as u64), origin: WDActions::PointerOrigin::Viewport, - x: Some(x), - y: Some(y), + x, + y, ..Default::default() }), ), @@ -213,8 +213,8 @@ impl PointerAction { WDActions::PointerMoveAction { duration: duration.map(|x| x.as_millis() as u64), origin: WDActions::PointerOrigin::Element(element.element), - x: Some(x), - y: Some(y), + x, + y, ..Default::default() }, )), @@ -404,6 +404,100 @@ impl From for ActionSequence { } } +/// A sequence containing [`Wheel` actions](WheelAction) for a wheel device. +#[derive(Debug, Clone)] +pub struct WheelActions { + /// A unique identifier to distinguish this input source from others. + /// + /// Choose a meaningful string as it may be useful for debugging. + id: String, + /// The list of actions for this sequence. + actions: Vec, +} + +impl WheelActions { + /// Create a new `WheelActions` sequence. + /// + /// The id can be any string but must uniquely identify this input source. + pub fn new(id: String) -> Self { + Self { + id, + actions: Vec::new(), + } + } + + /// Pushes a new action. + pub fn push(&mut self, action: WheelAction) { + self.actions.push(action); + } +} + +impl From for ActionSequence { + fn from(wa: WheelActions) -> Self { + ActionSequence(WDActions::ActionSequence { + id: wa.id, + actions: WDActions::ActionsType::Wheel { + actions: wa.actions.into_iter().map(|x| x.into_item()).collect(), + }, + }) + } +} + +/// An action performed with a wheel device. +/// +/// See [15.4.4 Wheel Actions](https://www.w3.org/TR/webdriver/#wheel-actions) of the +/// WebDriver standard. +#[derive(Debug, Clone)] +pub enum WheelAction { + /// Pause action. + /// Useful for adding pauses between other key actions. + Pause { + /// The pause duration, given in milliseconds. + duration: Duration, + }, + /// Wheel scroll event. + Scroll { + /// The scroll duration. + duration: Option, + /// `x` offset of the scroll origin, in pixels. + x: i64, + /// `y` offset of the scroll origin, in pixels. + y: i64, + /// The change of the number of pixels to be scrolled on the `x`-axis. + delta_x: i64, + /// The change of the number of pixels to be scrolled on the `y`-axis. + delta_y: i64, + }, +} + +impl WheelAction { + fn into_item(self) -> WDActions::WheelActionItem { + match self { + WheelAction::Pause { duration } => WDActions::WheelActionItem::General( + WDActions::GeneralAction::Pause(WDActions::PauseAction { + duration: Some(duration.as_millis() as u64), + }), + ), + WheelAction::Scroll { + x, + y, + delta_x, + delta_y, + duration, + } => WDActions::WheelActionItem::Wheel(WDActions::WheelAction::Scroll( + WDActions::WheelScrollAction { + duration: duration.map(|d| d.as_millis() as u64), + origin: WDActions::PointerOrigin::Viewport, + x: Some(x), + y: Some(y), + deltaX: Some(delta_x), + deltaY: Some(delta_y), + }, + )), + } + } +} + /// A sequence of actions to be performed. /// /// See the documentation for [`Actions`] for more details. @@ -495,6 +589,19 @@ impl InputSource for TouchActions { } } +impl InputSource for WheelActions { + type Action = WheelAction; + + fn pause(self, duration: Duration) -> Self { + self.then(WheelAction::Pause { duration }) + } + + fn then(mut self, action: Self::Action) -> Self { + self.actions.push(action); + self + } +} + /// A list of action sequences to be performed via [`Client::perform_actions()`] /// /// An [`ActionSequence`] is a sequence of actions of a specific type.