#[cfg(doc)]
use crate::client::Client;
use crate::elements::Element;
#[cfg(doc)]
use crate::key::Key;
use std::fmt::Debug;
use std::time::Duration;
use webdriver::actions as WDActions;
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum NullAction {
Pause {
duration: Duration,
},
}
impl NullAction {
fn into_item(self) -> WDActions::NullActionItem {
match self {
NullAction::Pause { duration } => WDActions::NullActionItem::General(
WDActions::GeneralAction::Pause(WDActions::PauseAction {
duration: Some(duration.as_millis() as u64),
}),
),
}
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum KeyAction {
Pause {
duration: Duration,
},
Up {
value: char,
},
Down {
value: char,
},
}
impl KeyAction {
fn into_item(self) -> WDActions::KeyActionItem {
use webdriver::actions::{KeyAction as WDKeyAction, KeyDownAction, KeyUpAction};
match self {
KeyAction::Pause { duration } => WDActions::KeyActionItem::General(
WDActions::GeneralAction::Pause(WDActions::PauseAction {
duration: Some(duration.as_millis() as u64),
}),
),
KeyAction::Up { value } => {
WDActions::KeyActionItem::Key(WDKeyAction::Up(KeyUpAction {
value: value.to_string(),
}))
}
KeyAction::Down { value } => {
WDActions::KeyActionItem::Key(WDKeyAction::Down(KeyDownAction {
value: value.to_string(),
}))
}
}
}
}
pub const MOUSE_BUTTON_LEFT: u64 = 0;
pub const MOUSE_BUTTON_MIDDLE: u64 = 1;
pub const MOUSE_BUTTON_RIGHT: u64 = 2;
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum PointerAction {
Pause {
duration: Duration,
},
Down {
button: u64,
},
Up {
button: u64,
},
MoveBy {
duration: Option<Duration>,
x: i64,
y: i64,
},
MoveTo {
duration: Option<Duration>,
x: i64,
y: i64,
},
MoveToElement {
element: Element,
duration: Option<Duration>,
x: i64,
y: i64,
},
Cancel,
}
impl PointerAction {
fn into_item(self) -> WDActions::PointerActionItem {
match self {
PointerAction::Pause { duration } => WDActions::PointerActionItem::General(
WDActions::GeneralAction::Pause(WDActions::PauseAction {
duration: Some(duration.as_millis() as u64),
}),
),
PointerAction::Down { button } => WDActions::PointerActionItem::Pointer(
WDActions::PointerAction::Down(WDActions::PointerDownAction {
button,
..Default::default()
}),
),
PointerAction::Up { button } => WDActions::PointerActionItem::Pointer(
WDActions::PointerAction::Up(WDActions::PointerUpAction {
button,
..Default::default()
}),
),
PointerAction::MoveBy { duration, x, y } => WDActions::PointerActionItem::Pointer(
WDActions::PointerAction::Move(WDActions::PointerMoveAction {
duration: duration.map(|x| x.as_millis() as u64),
origin: WDActions::PointerOrigin::Pointer,
x: Some(x),
y: Some(y),
..Default::default()
}),
),
PointerAction::MoveTo { duration, x, y } => WDActions::PointerActionItem::Pointer(
WDActions::PointerAction::Move(WDActions::PointerMoveAction {
duration: duration.map(|x| x.as_millis() as u64),
origin: WDActions::PointerOrigin::Viewport,
x: Some(x),
y: Some(y),
..Default::default()
}),
),
PointerAction::MoveToElement {
element,
duration,
x,
y,
} => WDActions::PointerActionItem::Pointer(WDActions::PointerAction::Move(
WDActions::PointerMoveAction {
duration: duration.map(|x| x.as_millis() as u64),
origin: WDActions::PointerOrigin::Element(element.element),
x: Some(x),
y: Some(y),
..Default::default()
},
)),
PointerAction::Cancel => {
WDActions::PointerActionItem::Pointer(WDActions::PointerAction::Cancel)
}
}
}
}
#[derive(Debug, Clone)]
pub struct NullActions {
id: String,
actions: Vec<NullAction>,
}
impl NullActions {
pub fn new(id: String) -> Self {
Self {
id,
actions: Vec::new(),
}
}
}
impl From<NullActions> for ActionSequence {
fn from(na: NullActions) -> Self {
ActionSequence(WDActions::ActionSequence {
id: na.id,
actions: WDActions::ActionsType::Null {
actions: na.actions.into_iter().map(|x| x.into_item()).collect(),
},
})
}
}
#[derive(Debug, Clone)]
pub struct KeyActions {
id: String,
actions: Vec<KeyAction>,
}
impl KeyActions {
pub fn new(id: String) -> Self {
Self {
id,
actions: Vec::new(),
}
}
}
impl From<KeyActions> for ActionSequence {
fn from(ka: KeyActions) -> Self {
ActionSequence(WDActions::ActionSequence {
id: ka.id,
actions: WDActions::ActionsType::Key {
actions: ka.actions.into_iter().map(|x| x.into_item()).collect(),
},
})
}
}
#[derive(Debug, Clone)]
pub struct MouseActions {
id: String,
actions: Vec<PointerAction>,
}
impl MouseActions {
pub fn new(id: String) -> Self {
Self {
id,
actions: Vec::new(),
}
}
}
impl From<MouseActions> for ActionSequence {
fn from(ma: MouseActions) -> Self {
ActionSequence(WDActions::ActionSequence {
id: ma.id,
actions: WDActions::ActionsType::Pointer {
parameters: WDActions::PointerActionParameters {
pointer_type: WDActions::PointerType::Mouse,
},
actions: ma.actions.into_iter().map(|x| x.into_item()).collect(),
},
})
}
}
#[derive(Debug, Clone)]
pub struct PenActions {
id: String,
actions: Vec<PointerAction>,
}
impl PenActions {
pub fn new(id: String) -> Self {
Self {
id,
actions: Vec::new(),
}
}
}
impl From<PenActions> for ActionSequence {
fn from(pa: PenActions) -> Self {
ActionSequence(WDActions::ActionSequence {
id: pa.id,
actions: WDActions::ActionsType::Pointer {
parameters: WDActions::PointerActionParameters {
pointer_type: WDActions::PointerType::Pen,
},
actions: pa.actions.into_iter().map(|x| x.into_item()).collect(),
},
})
}
}
#[derive(Debug, Clone)]
pub struct TouchActions {
id: String,
actions: Vec<PointerAction>,
}
impl TouchActions {
pub fn new(id: String) -> Self {
Self {
id,
actions: Vec::new(),
}
}
}
impl From<TouchActions> for ActionSequence {
fn from(ta: TouchActions) -> Self {
ActionSequence(WDActions::ActionSequence {
id: ta.id,
actions: WDActions::ActionsType::Pointer {
parameters: WDActions::PointerActionParameters {
pointer_type: WDActions::PointerType::Touch,
},
actions: ta.actions.into_iter().map(|x| x.into_item()).collect(),
},
})
}
}
#[derive(Debug)]
pub struct ActionSequence(pub(crate) WDActions::ActionSequence);
pub trait InputSource: Into<ActionSequence> {
type Action;
#[must_use]
fn pause(self, duration: Duration) -> Self;
#[must_use]
fn then(self, action: Self::Action) -> Self;
}
impl InputSource for NullActions {
type Action = NullAction;
fn pause(self, duration: Duration) -> Self {
self.then(NullAction::Pause { duration })
}
fn then(mut self, action: Self::Action) -> Self {
self.actions.push(action);
self
}
}
impl InputSource for KeyActions {
type Action = KeyAction;
fn pause(self, duration: Duration) -> Self {
self.then(KeyAction::Pause { duration })
}
fn then(mut self, action: Self::Action) -> Self {
self.actions.push(action);
self
}
}
impl InputSource for MouseActions {
type Action = PointerAction;
fn pause(self, duration: Duration) -> Self {
self.then(PointerAction::Pause { duration })
}
fn then(mut self, action: Self::Action) -> Self {
self.actions.push(action);
self
}
}
impl InputSource for PenActions {
type Action = PointerAction;
fn pause(self, duration: Duration) -> Self {
self.then(PointerAction::Pause { duration })
}
fn then(mut self, action: Self::Action) -> Self {
self.actions.push(action);
self
}
}
impl InputSource for TouchActions {
type Action = PointerAction;
fn pause(self, duration: Duration) -> Self {
self.then(PointerAction::Pause { duration })
}
fn then(mut self, action: Self::Action) -> Self {
self.actions.push(action);
self
}
}
#[derive(Debug, Default)]
pub struct Actions {
pub(crate) sequences: Vec<ActionSequence>,
}
impl Actions {
#[must_use]
pub fn and(mut self, sequence: impl Into<ActionSequence>) -> Self {
self.sequences.push(sequence.into());
self
}
}
impl<T> From<T> for Actions
where
T: Into<ActionSequence>,
{
fn from(sequence: T) -> Self {
Self {
sequences: vec![sequence.into()],
}
}
}
impl<T> From<Vec<T>> for Actions
where
T: Into<ActionSequence>,
{
fn from(sequences: Vec<T>) -> Self {
Self {
sequences: sequences.into_iter().map(|x| x.into()).collect(),
}
}
}