viewpoint_core/page/locator/debug/
mod.rs1use std::time::Duration;
6
7use tracing::{debug, instrument};
8use viewpoint_js::js;
9
10use super::Locator;
11use crate::error::LocatorError;
12
13impl Locator<'_> {
14 #[instrument(level = "debug", skip(self), fields(selector = ?self.selector))]
39 pub async fn highlight(&self) -> Result<(), LocatorError> {
40 self.highlight_for(Duration::from_secs(2)).await
41 }
42
43 #[instrument(level = "debug", skip(self), fields(selector = ?self.selector))]
53 pub async fn highlight_for(&self, duration: Duration) -> Result<(), LocatorError> {
54 self.wait_for_actionable().await?;
55
56 debug!(?duration, "Highlighting element");
57
58 let selector_expr = self.selector.to_js_expression();
60 let highlight_js = js! {
61 (function() {
62 const elements = @{selector_expr};
63 if (elements.length === 0) return { found: false };
64
65 const el = elements[0];
66 const originalOutline = el.style.outline;
67 const originalOutlineOffset = el.style.outlineOffset;
68 const originalTransition = el.style.transition;
69
70 el.style.transition = "outline 0.2s ease-in-out";
72 el.style.outline = "3px solid #ff00ff";
73 el.style.outlineOffset = "2px";
74
75 el.__viewpoint_original_outline = originalOutline;
77 el.__viewpoint_original_outline_offset = originalOutlineOffset;
78 el.__viewpoint_original_transition = originalTransition;
79
80 return { found: true };
81 })()
82 };
83
84 let result = self.evaluate_js(&highlight_js).await?;
85 let found = result
86 .get("found")
87 .and_then(serde_json::Value::as_bool)
88 .unwrap_or(false);
89 if !found {
90 return Err(LocatorError::NotFound(format!("{:?}", self.selector)));
91 }
92
93 tokio::time::sleep(duration).await;
95
96 let cleanup_js = js! {
98 (function() {
99 const elements = @{selector_expr};
100 if (elements.length === 0) return;
101
102 const el = elements[0];
103 el.style.outline = el.__viewpoint_original_outline || "";
104 el.style.outlineOffset = el.__viewpoint_original_outline_offset || "";
105 el.style.transition = el.__viewpoint_original_transition || "";
106
107 delete el.__viewpoint_original_outline;
108 delete el.__viewpoint_original_outline_offset;
109 delete el.__viewpoint_original_transition;
110 })()
111 };
112
113 let _ = self.evaluate_js(&cleanup_js).await;
115
116 Ok(())
117 }
118}