lw_webdriver/
tab.rs

1//! Tabs allow you to control elements
2
3use json::*;
4use std::result::Result;
5use crate::elements::*;
6use crate::session::*;
7use crate::enums::*;
8use crate::error::*;
9use log::{info, error};
10use crate::elements::Element;
11use std::rc::Rc;
12use crate::http_requests::{get_selected_tab, select_tab, navigate, close_active_tab, find_element,
13    get_active_tab_url, get_active_tab_title, back, forward, refresh, execute_script_sync, get_all_cookies, set_cookie, get_page_source};
14
15/// Tabs are used to load a site and get informations.
16/// 
17/// ```rust
18/// # use lw_webdriver::{session::Session, enums::Browser};
19/// 
20/// let mut session = Session::new(Browser::Firefox, false).unwrap();
21/// 
22/// // using the default tab
23/// session.tabs[0].navigate("https://www.mozilla.org/fr/").unwrap();
24/// ```
25pub struct Tab {
26    pub(crate) id: Rc<String>,
27    pub(crate) session_id: Rc<String>
28}
29
30impl Tab {
31    pub fn new_from(id: String, session_id: Rc<String>) -> Tab {
32        Tab {
33            id: Rc::new(id),
34            session_id
35        }
36    }
37
38    pub fn get_session_id(&self) -> Rc<String> {
39        Rc::clone(&self.session_id)
40    }
41
42    /// Create a new tab in a session.
43    /// This return an immutable reference (in a Result) because the tab is stored in the session.
44    pub fn new(session: &mut Session) -> Result<&Tab, WebdriverError> {
45        let tab_id = session.open_tab()?;
46        Ok(&session.tabs[tab_id])
47    }
48
49    /// Select this tab.
50    /// Selection is done automatically by this crate when you get informations.
51    pub fn select(&self) -> Result<(), WebdriverError> {
52        // check if it is needed to select the tab
53        if let Ok(id) = get_selected_tab(&self.session_id) {
54            if id == *self.id {
55                return Ok(());
56            }
57        }
58
59        // select tab
60        select_tab(&self.session_id, &self.id)
61    }
62
63    /// Load a website
64    pub fn navigate(&mut self, url: &str) -> Result<(), WebdriverError> {
65        self.select()?;
66        navigate(&self.session_id, url)
67    }
68
69    /// Find an element in the tab, selected by a [Selector](../enums/enum.Selector.html).
70    pub fn find(&mut self, selector: Selector, tofind: &str) -> Result<Option<Element>, WebdriverError> {
71        self.select()?;
72        match find_element(&self.session_id, selector, &tofind) {
73            Ok(id) => {
74                Ok(Some(Element::new(id, Rc::clone(&self.session_id), Rc::clone(&self.id))))
75            },
76            Err(error) if error == WebdriverError::NoSuchElement => {
77                Ok(None)
78            },
79            Err(error) => {
80                return Err(error)
81            }
82        }
83    }
84
85    /// Return the url of the current web page.
86    pub fn get_url(&self) -> Result<String, WebdriverError> {
87        self.select()?;
88        get_active_tab_url(&self.session_id)
89    }
90
91    /// Return the title of the tab.
92    pub fn get_title(&self) -> Result<String, WebdriverError> {
93        self.select()?;
94        get_active_tab_title(&self.session_id)
95    }
96
97    /// Navigate to the previous page.
98    pub fn back(&mut self) -> Result<(), WebdriverError> {
99        self.select()?;
100        back(&self.session_id)
101    }
102
103    /// Navigate forward.
104    pub fn forward(&mut self) -> Result<(), WebdriverError> {
105        self.select()?;
106        forward(&self.session_id)
107    }
108
109    /// Refresh the page.
110    pub fn refresh(&mut self) -> Result<(), WebdriverError> {
111        self.select()?;
112        refresh(&self.session_id)
113    }
114
115    pub fn execute_script(&self, script: &str, args: Vec<JsonValue>) -> Result<(), WebdriverError> {
116        self.select()?;
117        execute_script_sync(&self.session_id, script, args)
118    }
119
120    pub fn get_cookies(&self) -> Result<Vec<(String, usize, bool, String, String, bool, String)>, WebdriverError> {
121        self.select()?;
122        get_all_cookies(&self.session_id)
123    }
124
125    pub fn set_cookie(&self, cookie: (String, usize, bool, String, String, bool, String)) -> Result<(), WebdriverError> {
126        self.select()?;
127        set_cookie(&self.session_id, cookie)
128    }
129
130    pub fn set_cookies(&self, cookies: Vec<(String, usize, bool, String, String, bool, String)>) -> Result<(), WebdriverError> {
131        self.select()?;
132        for cookie in cookies {
133            set_cookie(&self.session_id, cookie)?
134        }
135        Ok(())
136    }
137
138    pub fn get_page_source(&self) -> Result<String, WebdriverError> {
139        self.select()?;
140        get_page_source(&self.session_id)
141    }
142}
143
144impl PartialEq for Tab {
145    fn eq(&self, other: &Self) -> bool {
146        self.get_id() == other.get_id()
147    }
148}
149
150impl WebdriverObject for Tab {
151    fn get_id(&self) -> &String {
152        &self.id
153    }
154}
155
156impl Drop for Tab {
157    #[allow(unused_must_use)]
158    fn drop(&mut self) {
159        if let Ok(()) = self.select() {
160            close_active_tab(&self.session_id);
161        }
162    }
163}