firefox_webdriver/browser/tab/
navigation.rs1use tracing::debug;
4
5use crate::error::Result;
6use crate::protocol::{BrowsingContextCommand, Command};
7
8use super::Tab;
9
10impl Tab {
15 pub async fn goto(&self, url: &str) -> Result<()> {
25 debug!(url = %url, tab_id = %self.inner.tab_id, "Navigating");
26
27 let command = Command::BrowsingContext(BrowsingContextCommand::Navigate {
28 url: url.to_string(),
29 });
30
31 self.send_command(command).await?;
32 Ok(())
33 }
34
35 pub async fn load_html(&self, html: &str) -> Result<()> {
49 debug!(tab_id = %self.inner.tab_id, html_len = html.len(), "Loading HTML content");
50
51 let escaped_html = html
52 .replace('\\', "\\\\")
53 .replace('`', "\\`")
54 .replace("${", "\\${");
55
56 let script = format!(
57 r#"(function() {{
58 const html = `{}`;
59 const parser = new DOMParser();
60 const doc = parser.parseFromString(html, 'text/html');
61 const newTitle = doc.querySelector('title');
62 if (newTitle) {{ document.title = newTitle.textContent; }}
63 const newBody = doc.body;
64 if (newBody) {{
65 document.body.innerHTML = newBody.innerHTML;
66 for (const attr of newBody.attributes) {{
67 document.body.setAttribute(attr.name, attr.value);
68 }}
69 }}
70 const newHead = doc.head;
71 if (newHead) {{
72 for (const child of newHead.children) {{
73 if (child.tagName !== 'TITLE') {{
74 document.head.appendChild(child.cloneNode(true));
75 }}
76 }}
77 }}
78 }})();"#,
79 escaped_html
80 );
81
82 self.execute_script(&script).await?;
83 Ok(())
84 }
85
86 pub async fn reload(&self) -> Result<()> {
88 debug!(tab_id = %self.inner.tab_id, "Reloading page");
89 let command = Command::BrowsingContext(BrowsingContextCommand::Reload);
90 self.send_command(command).await?;
91 Ok(())
92 }
93
94 pub async fn back(&self) -> Result<()> {
96 debug!(tab_id = %self.inner.tab_id, "Navigating back");
97 let command = Command::BrowsingContext(BrowsingContextCommand::GoBack);
98 self.send_command(command).await?;
99 Ok(())
100 }
101
102 pub async fn forward(&self) -> Result<()> {
104 debug!(tab_id = %self.inner.tab_id, "Navigating forward");
105 let command = Command::BrowsingContext(BrowsingContextCommand::GoForward);
106 self.send_command(command).await?;
107 Ok(())
108 }
109
110 pub async fn get_title(&self) -> Result<String> {
112 debug!(tab_id = %self.inner.tab_id, "Getting page title");
113 let command = Command::BrowsingContext(BrowsingContextCommand::GetTitle);
114 let response = self.send_command(command).await?;
115
116 let title = response
117 .result
118 .as_ref()
119 .and_then(|v| v.get("title"))
120 .and_then(|v| v.as_str())
121 .unwrap_or("")
122 .to_string();
123
124 debug!(tab_id = %self.inner.tab_id, title = %title, "Got page title");
125 Ok(title)
126 }
127
128 pub async fn get_url(&self) -> Result<String> {
130 debug!(tab_id = %self.inner.tab_id, "Getting page URL");
131 let command = Command::BrowsingContext(BrowsingContextCommand::GetUrl);
132 let response = self.send_command(command).await?;
133
134 let url = response
135 .result
136 .as_ref()
137 .and_then(|v| v.get("url"))
138 .and_then(|v| v.as_str())
139 .unwrap_or("")
140 .to_string();
141
142 debug!(tab_id = %self.inner.tab_id, url = %url, "Got page URL");
143 Ok(url)
144 }
145
146 pub async fn focus(&self) -> Result<()> {
148 debug!(tab_id = %self.inner.tab_id, "Focusing tab");
149 let command = Command::BrowsingContext(BrowsingContextCommand::FocusTab);
150 self.send_command(command).await?;
151 Ok(())
152 }
153
154 pub async fn focus_window(&self) -> Result<()> {
156 debug!(tab_id = %self.inner.tab_id, "Focusing window");
157 let command = Command::BrowsingContext(BrowsingContextCommand::FocusWindow);
158 self.send_command(command).await?;
159 Ok(())
160 }
161
162 pub async fn close(&self) -> Result<()> {
164 debug!(tab_id = %self.inner.tab_id, "Closing tab");
165 let command = Command::BrowsingContext(BrowsingContextCommand::CloseTab);
166 self.send_command(command).await?;
167 Ok(())
168 }
169
170 pub async fn get_page_source(&self) -> Result<String> {
172 debug!(tab_id = %self.inner.tab_id, "Getting page source");
173 let result = self
174 .execute_script("return document.documentElement.outerHTML")
175 .await?;
176 Ok(result.as_str().unwrap_or("").to_string())
177 }
178}