thirtyfour_sync/
switch_to.rs

1use crate::webdrivercommands::WebDriverCommands;
2use crate::WebDriverSession;
3use crate::{
4    common::command::Command,
5    common::types::WindowHandle,
6    error::{WebDriverError, WebDriverResult},
7    {webelement::convert_element_sync, Alert, WebElement},
8};
9
10/// Struct for switching between frames/windows/alerts.
11pub struct SwitchTo<'a> {
12    session: &'a WebDriverSession,
13}
14
15impl<'a> SwitchTo<'a> {
16    /// Create a new SwitchTo struct. This is typically created internally
17    /// via a call to `WebDriver::switch_to()`.
18    pub fn new(session: &'a WebDriverSession) -> Self {
19        SwitchTo {
20            session,
21        }
22    }
23
24    ///Convenience wrapper for executing a WebDriver command.
25    fn cmd(&self, command: Command) -> WebDriverResult<serde_json::Value> {
26        self.session.cmd(command)
27    }
28
29    /// Return the element with focus, or the `<body>` element if nothing has focus.
30    ///
31    /// # Example:
32    /// ```rust
33    /// # use thirtyfour_sync::prelude::*;
34    /// # fn main() -> WebDriverResult<()> {
35    /// #     let caps = DesiredCapabilities::chrome();
36    /// #     let driver = WebDriver::new("http://localhost:4444/wd/hub", &caps)?;
37    /// #     driver.get("http://webappdemo")?;
38    /// #     // Wait for page load.
39    /// #     driver.find_element(By::Id("button1"))?;
40    /// // If no element has focus, active_element() will return the body tag.
41    /// let elem = driver.switch_to().active_element()?;
42    /// assert_eq!(elem.tag_name()?, "body");
43    /// #     driver.find_element(By::Id("pagetextinput"))?.click()?;
44    /// // Now let's manually focus an element and try active_element() again.
45    /// driver.execute_script(r#"document.getElementsByName("input1")[0].focus();"#)?;
46    /// let elem = driver.switch_to().active_element()?;
47    /// elem.send_keys("selenium")?;
48    /// #     let elem = driver.find_element(By::Name("input1"))?;
49    /// #     assert_eq!(elem.value()?, Some("selenium".to_string()));
50    /// #     driver.quit()?;
51    /// #     Ok(())
52    /// # }
53    /// ```
54    pub fn active_element(self) -> WebDriverResult<WebElement<'a>> {
55        let v = self.cmd(Command::GetActiveElement)?;
56        convert_element_sync(self.session, &v["value"])
57    }
58
59    /// Return Alert struct for processing the active alert on the page.
60    ///
61    /// See [Alert](struct.Alert.html) documentation for examples.
62    pub fn alert(self) -> Alert<'a> {
63        Alert::new(self.session)
64    }
65
66    /// Switch to the default frame.
67    ///
68    /// # Example:
69    /// ```rust
70    /// # use thirtyfour_sync::prelude::*;
71    /// # fn main() -> WebDriverResult<()> {
72    /// #     let caps = DesiredCapabilities::chrome();
73    /// #     let driver = WebDriver::new("http://localhost:4444/wd/hub", &caps)?;
74    /// #     driver.get("http://webappdemo")?;
75    /// #     driver.find_element(By::Id("pageiframe"))?.click()?;
76    /// driver.switch_to().frame_number(0)?;
77    /// // We are now inside the iframe.
78    /// driver.find_element(By::Id("button1"))?;
79    /// driver.switch_to().default_content()?;
80    /// // We are now back in the original window.
81    /// #     driver.find_element(By::Id("iframeid1"))?;
82    /// #     driver.quit()?;
83    /// #     Ok(())
84    /// # }
85    /// ```
86    pub fn default_content(self) -> WebDriverResult<()> {
87        self.cmd(Command::SwitchToFrameDefault).map(|_| ())
88    }
89
90    /// Switch to an iframe by index. The first iframe on the page has index 0.
91    ///
92    /// # Example:
93    /// ```rust
94    /// # use thirtyfour_sync::prelude::*;
95    /// # fn main() -> WebDriverResult<()> {
96    /// #     let caps = DesiredCapabilities::chrome();
97    /// #     let driver = WebDriver::new("http://localhost:4444/wd/hub", &caps)?;
98    /// #     driver.get("http://webappdemo")?;
99    /// #     driver.find_element(By::Id("pageiframe"))?.click()?;
100    /// driver.switch_to().frame_number(0)?;
101    /// // We can now search for elements within the iframe.
102    /// let elem = driver.find_element(By::Id("button1"))?;
103    /// elem.click()?;
104    /// #     let elem_result = driver.find_element(By::Id("button-result"))?;
105    /// #     assert_eq!(elem_result.text()?, "Button 1 clicked");
106    /// #     driver.quit()?;
107    /// #     Ok(())
108    /// # }
109    /// ```
110    pub fn frame_number(self, frame_number: u16) -> WebDriverResult<()> {
111        self.cmd(Command::SwitchToFrameNumber(frame_number)).map(|_| ())
112    }
113
114    /// Switch to the specified iframe element.
115    ///
116    /// # Example:
117    /// ```rust
118    /// # use thirtyfour_sync::prelude::*;
119    /// # fn main() -> WebDriverResult<()> {
120    /// #     let caps = DesiredCapabilities::chrome();
121    /// #     let driver = WebDriver::new("http://localhost:4444/wd/hub", &caps)?;
122    /// #     driver.get("http://webappdemo")?;
123    /// #     driver.find_element(By::Id("pageiframe"))?.click()?;
124    /// let elem_iframe = driver.find_element(By::Id("iframeid1"))?;
125    /// driver.switch_to().frame_element(&elem_iframe)?;
126    /// // We can now search for elements within the iframe.
127    /// let elem = driver.find_element(By::Id("button1"))?;
128    /// elem.click()?;
129    /// #     let elem_result = driver.find_element(By::Id("button-result"))?;
130    /// #     assert_eq!(elem_result.text()?, "Button 1 clicked");
131    /// #     driver.quit()?;
132    /// #     Ok(())
133    /// # }
134    /// ```
135    pub fn frame_element(self, frame_element: &WebElement) -> WebDriverResult<()> {
136        self.cmd(Command::SwitchToFrameElement(frame_element.element_id.clone())).map(|_| ())
137    }
138
139    /// Switch to the parent frame.
140    ///
141    /// # Example:
142    /// ```rust
143    /// # use thirtyfour_sync::prelude::*;
144    /// # fn main() -> WebDriverResult<()> {
145    /// #     let caps = DesiredCapabilities::chrome();
146    /// #     let driver = WebDriver::new("http://localhost:4444/wd/hub", &caps)?;
147    /// #     driver.get("http://webappdemo")?;
148    /// #     driver.find_element(By::Id("pageiframe"))?.click()?;
149    /// let elem_iframe = driver.find_element(By::Id("iframeid1"))?;
150    /// driver.switch_to().frame_element(&elem_iframe)?;
151    /// // We can now search for elements within the iframe.
152    /// let elem = driver.find_element(By::Id("button1"))?;
153    /// elem.click()?;
154    /// #     let elem_result = driver.find_element(By::Id("button-result"))?;
155    /// #     assert_eq!(elem_result.text()?, "Button 1 clicked");
156    /// // Now switch back to the parent frame.
157    /// driver.switch_to().parent_frame()?;
158    /// // We are now back in the parent document.
159    /// #     driver.find_element(By::Id("iframeid1"))?;
160    /// #     driver.quit()?;
161    /// #     Ok(())
162    /// # }
163    /// ```
164    pub fn parent_frame(self) -> WebDriverResult<()> {
165        self.cmd(Command::SwitchToParentFrame).map(|_| ())
166    }
167
168    /// Switch to the specified window.
169    ///
170    /// # Example:
171    /// ```rust
172    /// # use thirtyfour_sync::prelude::*;
173    /// # fn main() -> WebDriverResult<()> {
174    /// #     let caps = DesiredCapabilities::chrome();
175    /// #     let driver = WebDriver::new("http://localhost:4444/wd/hub", &caps)?;
176    /// #     driver.get("http://webappdemo")?;
177    /// #     driver.find_element(By::Id("pagetextinput"))?.click()?;
178    /// #     assert_eq!(driver.title()?, "Demo Web App");
179    /// // Open a new tab.
180    /// driver.execute_script(r#"window.open("about:blank", target="_blank");"#)?;
181    /// // Get window handles and switch to the new tab.
182    /// let handles = driver.window_handles()?;
183    /// driver.switch_to().window(&handles[1])?;
184    /// // We are now controlling the new tab.
185    /// driver.get("http://webappdemo")?;
186    /// #     driver.find_element(By::Id("button1"))?;
187    /// #     driver.switch_to().window(&handles[0])?;
188    /// #     driver.find_element(By::Name("input1"))?;
189    /// #     driver.quit()?;
190    /// #     Ok(())
191    /// # }
192    /// ```
193    pub fn window(self, handle: &WindowHandle) -> WebDriverResult<()> {
194        self.cmd(Command::SwitchToWindow(handle.clone())).map(|_| ())
195    }
196
197    /// Switch to the window with the specified name. This uses the `window.name` property.
198    /// You can set a window name via `WebDriver::set_window_name("someName")?`.
199    ///
200    /// # Example:
201    /// ```rust
202    /// # use thirtyfour_sync::prelude::*;
203    /// # fn main() -> WebDriverResult<()> {
204    /// #     let caps = DesiredCapabilities::chrome();
205    /// #     let driver = WebDriver::new("http://localhost:4444/wd/hub", &caps)?;
206    /// #     driver.get("http://webappdemo")?;
207    /// #     assert_eq!(driver.title()?, "Demo Web App");
208    /// // Set main window name so we can switch back easily.
209    /// driver.set_window_name("mywindow")?;
210    /// // Open a new tab.
211    /// driver.execute_script(r#"window.open("about:blank", target="_blank");"#)?;
212    /// // Get window handles and switch to the new tab.
213    /// let handles = driver.window_handles()?;
214    /// driver.switch_to().window(&handles[1])?;
215    /// // We are now controlling the new tab.
216    /// assert_eq!(driver.title()?, "");
217    /// driver.switch_to().window_name("mywindow")?;
218    /// // We are now back in the original tab.
219    /// assert_eq!(driver.title()?, "Demo Web App");
220    /// #     driver.quit()?;
221    /// #     Ok(())
222    /// # }
223    /// ```
224    pub fn window_name(self, name: &str) -> WebDriverResult<()> {
225        let original_handle = self.session.current_window_handle()?;
226        let handles = &self.session.window_handles()?;
227        for handle in handles {
228            self.session.switch_to().window(handle)?;
229            let ret = &self.session.execute_script(r#"return window.name;"#)?;
230            let current_name: String = ret.convert()?;
231            if current_name == name {
232                return Ok(());
233            }
234        }
235
236        self.window(&original_handle)?;
237        Err(WebDriverError::NotFound(
238            format!("window handle '{}'", name),
239            "No windows with the specified handle were found".to_string(),
240        ))
241    }
242}