viewpoint_core/page/locator/builders/
tap.rs1use tracing::{debug, instrument};
4
5use super::super::Locator;
6use crate::error::LocatorError;
7
8#[derive(Debug)]
12pub struct TapBuilder<'l, 'a> {
13 locator: &'l Locator<'a>,
14 position: Option<(f64, f64)>,
15 force: bool,
16 modifiers: i32,
17}
18
19impl<'l, 'a> TapBuilder<'l, 'a> {
20 pub(crate) fn new(locator: &'l Locator<'a>) -> Self {
21 Self {
22 locator,
23 position: None,
24 force: false,
25 modifiers: 0,
26 }
27 }
28
29 #[must_use]
31 pub fn position(mut self, x: f64, y: f64) -> Self {
32 self.position = Some((x, y));
33 self
34 }
35
36 #[must_use]
38 pub fn force(mut self, force: bool) -> Self {
39 self.force = force;
40 self
41 }
42
43 #[must_use]
45 pub fn modifiers(mut self, modifiers: i32) -> Self {
46 self.modifiers = modifiers;
47 self
48 }
49
50 #[instrument(level = "debug", skip(self), fields(selector = ?self.locator.selector))]
52 pub async fn send(self) -> Result<(), LocatorError> {
53 let (x, y) = if self.force {
54 let info = self.locator.query_element_info().await?;
55 if !info.found {
56 return Err(LocatorError::NotFound(format!(
57 "{:?}",
58 self.locator.selector
59 )));
60 }
61
62 if let Some((offset_x, offset_y)) = self.position {
63 (
64 info.x.unwrap_or(0.0) + offset_x,
65 info.y.unwrap_or(0.0) + offset_y,
66 )
67 } else {
68 (
69 info.x.unwrap_or(0.0) + info.width.unwrap_or(0.0) / 2.0,
70 info.y.unwrap_or(0.0) + info.height.unwrap_or(0.0) / 2.0,
71 )
72 }
73 } else {
74 let info = self.locator.wait_for_actionable().await?;
75
76 if let Some((offset_x, offset_y)) = self.position {
77 (
78 info.x.expect("visible element has x") + offset_x,
79 info.y.expect("visible element has y") + offset_y,
80 )
81 } else {
82 (
83 info.x.expect("visible element has x")
84 + info.width.expect("visible element has width") / 2.0,
85 info.y.expect("visible element has y")
86 + info.height.expect("visible element has height") / 2.0,
87 )
88 }
89 };
90
91 debug!(x, y, modifiers = self.modifiers, "Tapping element");
92
93 if self.modifiers != 0 {
94 self.locator
95 .page
96 .touchscreen()
97 .tap_with_modifiers(x, y, self.modifiers)
98 .await
99 } else {
100 self.locator.page.touchscreen().tap(x, y).await
101 }
102 }
103}