viewpoint_core/page/locator/builders/
check.rs1use tracing::{debug, instrument};
4
5use super::click::ClickBuilder;
6use super::super::Locator;
7use crate::error::LocatorError;
8use crate::wait::NavigationWaiter;
9
10#[derive(Debug)]
14pub struct CheckBuilder<'l, 'a> {
15 locator: &'l Locator<'a>,
16 check: bool,
18 force: bool,
20 no_wait_after: bool,
22}
23
24impl<'l, 'a> CheckBuilder<'l, 'a> {
25 pub(crate) fn new_check(locator: &'l Locator<'a>) -> Self {
26 Self {
27 locator,
28 check: true,
29 force: false,
30 no_wait_after: false,
31 }
32 }
33
34 pub(crate) fn new_uncheck(locator: &'l Locator<'a>) -> Self {
35 Self {
36 locator,
37 check: false,
38 force: false,
39 no_wait_after: false,
40 }
41 }
42
43 #[must_use]
45 pub fn force(mut self, force: bool) -> Self {
46 self.force = force;
47 self
48 }
49
50 #[must_use]
52 pub fn no_wait_after(mut self, no_wait_after: bool) -> Self {
53 self.no_wait_after = no_wait_after;
54 self
55 }
56
57 #[instrument(level = "debug", skip(self), fields(selector = ?self.locator.selector, check = self.check))]
59 pub async fn send(self) -> Result<(), LocatorError> {
60 let navigation_waiter = if self.no_wait_after {
62 None
63 } else {
64 Some(NavigationWaiter::new(
65 self.locator.page.connection().subscribe_events(),
66 self.locator.page.session_id().to_string(),
67 self.locator.page.frame_id().to_string(),
68 ))
69 };
70
71 self.perform_check().await?;
73
74 if let Some(waiter) = navigation_waiter {
76 if let Err(e) = waiter.wait_for_navigation_if_triggered().await {
77 debug!(error = ?e, "Navigation wait failed after check");
78 return Err(LocatorError::WaitError(e));
79 }
80 }
81
82 Ok(())
83 }
84
85 async fn perform_check(&self) -> Result<(), LocatorError> {
87 let is_checked = self.locator.is_checked().await?;
88
89 if self.check {
90 if is_checked {
92 debug!("Element already checked");
93 } else {
94 debug!("Checking element");
95 ClickBuilder::new(self.locator)
97 .force(self.force)
98 .no_wait_after(true)
99 .send()
100 .await?;
101 }
102 } else {
103 if is_checked {
105 debug!("Unchecking element");
106 ClickBuilder::new(self.locator)
107 .force(self.force)
108 .no_wait_after(true)
109 .send()
110 .await?;
111 } else {
112 debug!("Element already unchecked");
113 }
114 }
115
116 Ok(())
117 }
118}
119
120impl<'l> std::future::IntoFuture for CheckBuilder<'l, '_> {
121 type Output = Result<(), LocatorError>;
122 type IntoFuture =
123 std::pin::Pin<Box<dyn std::future::Future<Output = Self::Output> + Send + 'l>>;
124
125 fn into_future(self) -> Self::IntoFuture {
126 Box::pin(self.send())
127 }
128}