chromedriver_api/session/
tab.rs1use crate::prelude::*;
2use super::SessionManager;
3
4use reqwest::Client;
5use serde_json::{ json, Value };
6
7#[derive(Clone)]
9pub struct Tab {
10 pub(crate) client: Client,
11 pub(crate) port: u16,
12 pub(crate) session_id: String,
13 pub(crate) tab_id: String,
14 pub(crate) url: String,
15 pub(crate) manager: Arc<SessionManager>
16}
17
18impl Tab {
19 pub fn get_port(&self) -> u16 {
21 self.port
22 }
23
24 pub fn get_id(&self) -> &str {
26 &self.tab_id
27 }
28
29 async fn active_without_lock(&self) -> Result<()> {
31 self.client
32 .post(&fmt!("http://127.0.0.1:{}/session/{}/window", self.port, self.session_id))
33 .json(&json!({"handle": self.tab_id }))
34 .send()
35 .await?;
36
37 Ok(())
38 }
39
40 pub async fn active(&self) -> Result<()> {
42 self.manager.lock().await;
44
45 self.active_without_lock().await?;
47
48 self.manager.unlock().await;
50
51 Ok(())
52 }
53
54 pub async fn open<S>(&mut self, url: S) -> Result<()>
56 where
57 S: Into<String>
58 {
59 let url = url.into();
60
61 self.manager.lock().await;
63
64 self.active_without_lock().await?;
66
67 self.client
69 .post(&fmt!("http://127.0.0.1:{}/session/{}/url", self.port, self.session_id))
70 .json(&json!({ "url": url }))
71 .send()
72 .await?;
73
74 self.url = url;
76
77 self.manager.unlock().await;
79
80 Ok(())
81 }
82
83 pub async fn inject<D: serde::de::DeserializeOwned>(&self, script: &str) -> Result<D> {
85 self.manager.lock().await;
87
88 self.active_without_lock().await?;
90
91 let url = fmt!("http://127.0.0.1:{}/session/{}/execute/sync", self.port, self.session_id);
93 let response = self.client
94 .post(&url)
95 .json(&json!({
96 "script": script,
97 "args": []
98 }))
99 .send()
100 .await?
101 .json::<Value>()
102 .await?;
103
104 self.manager.unlock().await;
106
107 let value = response.get("value")
108 .ok_or(Error::UnexpectedResponse)?
109 .to_owned();
110
111 Ok(serde_json::from_value::<D>(value)?)
112 }
113
114 pub async fn close(&self) -> Result<()> {
116 self.manager.lock().await;
118
119 self.active_without_lock().await?;
121
122 loop {
124 if let Err(_) = self.active_without_lock().await {
126 break;
127 }
128
129 self.client
131 .delete(&fmt!("http://127.0.0.1:{}/session/{}/window", self.port, self.session_id))
132 .send()
133 .await?;
134
135 let handles = self.get_tabs_ids().await?;
137
138 if !handles.contains(&self.tab_id) {
140 break;
141 }
142 }
143
144 self.manager.unlock().await;
146
147 Ok(())
148 }
149
150 async fn get_tabs_ids(&self) -> Result<Vec<String>> {
152 let handles_url = fmt!("http://127.0.0.1:{}/session/{}/window/handles", self.port, self.session_id);
153
154 let response = self.client
155 .get(&handles_url)
156 .send()
157 .await?
158 .error_for_status()?
159 .json::<Value>()
160 .await?;
161
162 let handles = response["value"]
163 .as_array()
164 .ok_or(Error::IncorrectWindowHandles)?
165 .iter()
166 .map(|v| {
167 v.as_str()
168 .ok_or(Error::IncorrectWindowHandles)
169 .map(|s| s.to_string())
170 .map_err(|e| e.into())
171 })
172 .collect::<Result<Vec<_>>>()?;
173
174 Ok(handles)
175 }
176}