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}