viewpoint_core/page/frame/
content.rs1use tracing::{info, instrument, trace};
4use viewpoint_cdp::protocol::runtime::EvaluateParams;
5
6use super::Frame;
7use crate::error::PageError;
8
9impl Frame {
10 #[instrument(level = "debug", skip(self), fields(frame_id = %self.id))]
16 pub async fn content(&self) -> Result<String, PageError> {
17 if self.is_detached() {
18 return Err(PageError::EvaluationFailed("Frame is detached".to_string()));
19 }
20
21 let context_id = self.main_world_context_id();
23 trace!(context_id = ?context_id, "Using execution context for content()");
24
25 let result: viewpoint_cdp::protocol::runtime::EvaluateResult = self
26 .connection
27 .send_command(
28 "Runtime.evaluate",
29 Some(EvaluateParams {
30 expression: "document.documentElement.outerHTML".to_string(),
31 object_group: None,
32 include_command_line_api: None,
33 silent: Some(true),
34 context_id,
35 return_by_value: Some(true),
36 await_promise: Some(false),
37 }),
38 Some(&self.session_id),
39 )
40 .await?;
41
42 result
43 .result
44 .value
45 .and_then(|v| v.as_str().map(ToString::to_string))
46 .ok_or_else(|| PageError::EvaluationFailed("Failed to get content".to_string()))
47 }
48
49 #[instrument(level = "debug", skip(self), fields(frame_id = %self.id))]
55 pub async fn title(&self) -> Result<String, PageError> {
56 if self.is_detached() {
57 return Err(PageError::EvaluationFailed("Frame is detached".to_string()));
58 }
59
60 let context_id = self.main_world_context_id();
62 trace!(context_id = ?context_id, "Using execution context for title()");
63
64 let result: viewpoint_cdp::protocol::runtime::EvaluateResult = self
65 .connection
66 .send_command(
67 "Runtime.evaluate",
68 Some(EvaluateParams {
69 expression: "document.title".to_string(),
70 object_group: None,
71 include_command_line_api: None,
72 silent: Some(true),
73 context_id,
74 return_by_value: Some(true),
75 await_promise: Some(false),
76 }),
77 Some(&self.session_id),
78 )
79 .await?;
80
81 result
82 .result
83 .value
84 .and_then(|v| v.as_str().map(ToString::to_string))
85 .ok_or_else(|| PageError::EvaluationFailed("Failed to get title".to_string()))
86 }
87
88 #[instrument(level = "info", skip(self, html), fields(frame_id = %self.id))]
94 pub async fn set_content(&self, html: &str) -> Result<(), PageError> {
95 if self.is_detached() {
96 return Err(PageError::EvaluationFailed("Frame is detached".to_string()));
97 }
98
99 use viewpoint_cdp::protocol::page::SetDocumentContentParams;
100
101 self.connection
102 .send_command::<_, serde_json::Value>(
103 "Page.setDocumentContent",
104 Some(SetDocumentContentParams {
105 frame_id: self.id.clone(),
106 html: html.to_string(),
107 }),
108 Some(&self.session_id),
109 )
110 .await?;
111
112 info!("Frame content set");
113 Ok(())
114 }
115}