chromedriver_api/session/
tab.rs

1use crate::{ prelude::*, TaskManager };
2
3use reqwest::Client;
4use serde_json::{ json, Value };
5
6// The window tab
7#[derive(Debug)]
8pub struct Tab {
9    pub(crate) client: Client,
10    pub(crate) port: String,
11    pub(crate) session_id: String,
12    pub(crate) window_handle: String,
13    pub(crate) url: String,
14    pub(crate) manager: Arc<TaskManager>
15}
16
17impl Tab {
18    /// Do tab active without locking other tasks
19    async fn active_without_lock(&mut self) -> Result<()> {
20        self.client
21            .post(&format!("http://127.0.0.1:{}/session/{}/window", self.port, self.session_id))
22            .json(&json!({"handle": self.window_handle }))
23            .send()
24            .await?
25            .error_for_status()?;
26
27        Ok(())
28    }
29
30    /// Do tab active
31    pub async fn active(&mut self) -> Result<()> {
32        // lock other tasks:
33        self.manager.lock().await;
34        
35        // do tab active:
36        self.active_without_lock().await?;
37
38        // unlock other tasks:
39        self.manager.unlock().await;
40
41        Ok(())
42    }
43    
44    /// Open URL-address
45    pub async fn open<S>(&mut self, url: S) -> Result<()>
46    where
47        S: Into<String>
48    {       
49        let url = url.into();
50
51        // lock other tasks:
52        self.manager.lock().await;
53
54        // do tab active:
55        self.active_without_lock().await?;
56
57        // loading URL:
58        self.client
59            .post(&format!("http://127.0.0.1:{}/session/{}/url", self.port, self.session_id))
60            .json(&json!({ "url": url }))
61            .send()
62            .await?
63            .error_for_status()?;
64
65        // update url:
66        self.url = url;
67
68        // unlock other tasks:
69        self.manager.unlock().await;
70
71        Ok(())
72    }
73
74    /// Inject JavaScript to window tab
75    pub async fn inject<D: serde::de::DeserializeOwned>(&mut self, script: &str) -> Result<D> {
76        // lock other tasks:
77        self.manager.lock().await;
78        
79        // do tab active:
80        self.active_without_lock().await?;
81
82        // execute script:
83        let url = format!("http://127.0.0.1:{}/session/{}/execute/sync", self.port, self.session_id);
84        let response = self.client
85            .post(&url)
86            .json(&json!({
87                "script": script,
88                "args": []
89            }))
90            .send()
91            .await?
92            .error_for_status()?
93            .json::<Value>()
94            .await?;
95
96        // unlock other tasks:
97        self.manager.unlock().await;
98
99        let value = response.get("value")
100            .ok_or(Error::UnexpectedResponse)?
101            .to_owned();
102        
103        Ok(serde_json::from_value::<D>(value)?)
104    }
105
106    /// Close window tab
107    pub async fn close(&mut self) -> Result<()> {
108        // lock other tasks:
109        self.manager.lock().await;
110
111        // do tab active:
112        self.active_without_lock().await?;
113
114        // close tab:
115        self.client
116            .delete(&format!("http://127.0.0.1:{}/session/{}/window", self.port, self.session_id))
117            .send()
118            .await?
119            .error_for_status()?;
120
121        // unlock other tasks:
122        self.manager.unlock().await;
123
124        Ok(())
125    }
126}