网页 frames 与多窗口处理
同学们大家好,今天我们继续来学习 Web 自动化测试中,网页 frames 与 多窗口处理的内容。
简介
要定位一个元素时,怎么都定位不到的时候就要考虑是不是浏览器内嵌了一个 frame 窗口或者要找的元素在新打开的窗口里。这时候就需要进行 frame 的切换或者窗口的切换。
frame 类似于在原有主 HTML 的基础上又嵌套一个 HTML,而且嵌套的 HTML 是独立使用的,互不影响。 当打开一个页面时,光标的定位是在主页面中,如果页面是由多个 frame 组成的,那么无法直接定位到具体的元素,需要切换到自己所需要的 frame 中,再查找该元素。
iframe 解析
如图可以看到带有 iframe
的标签。
iframe 的多种切换方式
<iframe src="1.html" id="hogwarts_id" name="hogwarts_name"></iframe>
# index:传入整型的参数,从 0 开始,这里的 0 就是第一个 frame
driver.switch_to.frame(0)
#id:iframe 的 id
driver.switch_to.frame("hogwarts_id")
#name: iframe 的 name
driver.switch_to.frame("hogwarts_name")
#WebElement: 传入 `selenium.webelement` 对象
driver.switch_to.frame(driver.find_element(By.TAG_NAME,"iframe"))
切换frame的方式有多种,比如我们传入一个数字,他就会找到iframe并切换,我们还可以填入frame的id和name属性,我们也可以直接传入这个frame的元素对象
iframe 切换回默认页面
在切换页面之后,如果还想操作原页面,则可以使用:
# python
driver.switch_to.default_content()
# java
driver.switchTo().defaultContent();
我们直接调用default content即可
iframe 多层切换
driver.switch_to.frame("iframe1")
driver.switch_to.frame("iframe2")
如图所示多层嵌套的 iframe。从最外部 iframe 切换到 iframe2 则需要层层切换
从 iframe2 切换回 iframe1 可以使用父子切换:
# 从 iframe2 切换到上一级 iframe1
driver.switch_to.parent_frame()
# 从 iframe1 切换到上一级 iframe,如果 iframe 已经是最上级,则保持不变
driver.switch_to.parent_frame()
从 iframe2 切换回 iframe1 可以使用 parent frame 方法进行父子切换,这个方法是 Selenium 提供的直接从子 frame 切换到父 frame,可以使用在嵌套的 frame 框架中。
多窗口处理
元素有属性,浏览器的窗口其实也有属性的,浏览器窗口的属性用句柄(handle)来识别。 当浏览器打开一个窗口时,如果要在新的窗口操作就需要句柄切换。
元素有属性,浏览器的窗口其实也有属性的,浏览器窗口的属性用句柄(handle)来识别。 当浏览器打开一个窗口时,如果要在新的窗口操作就需要句柄切换。
句柄的获取
driver = webdriver.Chrome()
handles = driver.window_handles
print(handles)
['CDwindow-8012E9EF4DC788A58DC1588E7B8A7C44', 'CDwindow-11D52927C71E7C2B9984F2D1E2856049']
当有多个窗口时,可以用 window_handles 打印句柄,如图所示,他返回的是一个列表
句柄的切换
from selenium import webdriver
driver = webdriver.Chrome()
handles = driver.window_handles
print(handles)
driver.switch_to.window(handles[-1])
从上面源代码中的说明可以看出,switch_to.window()
需要提供一个 windows_name,可以是 name 也可以是 windows handle。
实战演示(Python)
必应搜索“霍格沃兹测试开发”,点击“霍格沃兹测试开发学社”。
from selenium import webdriver
class TestHogwartsDemo:
def setup_method(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
def teardown_method(self):
self.driver.quit()
def test_switch_window(self):
# 进入必应搜索
self.driver.get("https://cn.bing.com/")
# 输入关键词
self.driver.find_element(By.CSS_SELECTOR, "#sb_form_q").send_keys("霍格沃兹测试开发")
# 点击搜索按钮
self.driver.find_element(By.CSS_SELECTOR, "#search_icon").click()
# 点击霍格沃兹测试开发学社官网
self.driver.find_element(By.XPATH,
"//*[@class='b_algo']//*[contains(text(),'测试开发训练营 大厂私教职场守护')]/../../h2/a").click()
# 将获取到的 window_handles 赋值给一个变量 handles
handles = self.driver.window_handles
# 切换句柄
self.driver.switch_to.window(handles[-1])
assert len(self.driver.find_elements(By.CSS_SELECTOR, '.navbar-brand')) == 1
实战演示(Java)
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.edge.EdgeDriver;
public class demoTest {
static WebDriver driver;
@AfterAll
static void teardown(){
driver.quit();
}
@BeforeAll
static void setup(){
driver = new EdgeDriver();
}
@Test
void demo(){
# 进入必应搜索
driver.get("https://cn.bing.com/")
# 输入关键词
driver.findElement(By.CSS_SELECTOR, "#sb_form_q").send_keys("霍格沃兹测试开发")
# 点击搜索按钮
driver.find_element(By.cssSelector( "#search_icon")).click()
# 点击霍格沃兹测试开发学社官网
driver.findElement(By.xpath(
"//*[@class='b_algo']//*[contains(text(),'测试开发训练营 大厂私教职场守护')]/../../h2/a")).click()
# 将获取到的 window_handles 赋值给一个变量 handles
handles = driver.getWindowHandles();
# 切换句柄
driver.switchTo().window(handles[-1])
assert len(self.driver.findElements(By.cssSelector( '.navbar-brand'))) == 1
}
}
总结
- frame
- window_handle
在上面我们学习到了如何操控 frame 和 window,详细大家有了初步的了解,好的本堂课就到这里。