操控浏览器-切换窗口

一、窗口和标签页

WebDriver 没有区分窗口和标签页,每个窗口都有一个唯一的标识符:

driver.current_window_handle

web 是异步的,webdriver 是阻塞的,需要浏览器与驱动同步。
单击 <a href="#" target=”_blank"> 在新窗口中打开链接,浏览器会聚焦在新窗口或新标签页上,WebDriver 需要找到新窗口句柄(window_handle)并切换到新窗口。

from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

# 启动驱动程序
with webdriver.Firefox() as driver:
	# 打开网址
	driver.get("https://seleniumhq.github.io")

    # 设置等待
    wait = WebDriverWait(driver, 10)

    # 存储原始窗口的 ID
    original_window = driver.current_window_handle

    # 检查一下,我们还没有打开其他的窗口
    assert len(driver.window_handles) == 1

    # 单击在新窗口中打开的链接
    driver.find_element(By.LINK_TEXT, "new window").click()

    # 等待新窗口或标签页
    wait.until(EC.number_of_windows_to_be(2))

    # 循环执行,直到找到一个新的窗口句柄
    for window_handle in driver.window_handles:
        if window_handle != original_window:
            driver.switch_to.window(window_handle)
            break

    # 等待新标签页完成加载内容
    wait.until(EC.title_is("SeleniumHQ Browser Automation"))

	#关闭标签页或窗口
	driver.close()
	
	#切回到之前的标签页或窗口
	driver.switch_to.window(original_window)

## 注意: 以下特性适用于 Selenium 4 及其后续版本。

driver.switch_to.new_window('tab') # 打开新标签页并切换到新标签页
driver.switch_to.new_window('window') # 打开一个新窗口并切换到新窗口

二、Frames and Iframes

switch_to.frame(reference)

reference:WebElement、id、name、index。

# 存储网页元素
iframe = driver.find_element_by_id('myframe')

driver.switch_to.frame(iframe) 	# 切换到选择的 iframe
# driver.switch_to.frame('myframe') # 通过 id 切换框架
# driver.switch_to.frame(1)	# 切换到第 2 个框架

离开 iframe 或 frameset,切换回默认内容:
driver.switch_to.default_content()	# 切回到默认内容
driver.switch_to.parent_frame()		# 切换回父帧

三、JavaScript 警告框、提示框和确认框

WebDriver提供了一个API,用于处理JavaScript提供的三种类型的原生弹窗消息。这些弹窗由浏览器提供限定的样式。

1、Alerts 警告框

其中最基本的称为警告框,它显示一条自定义消息, 以及一个用于关闭该警告的按钮,在大多数浏览器中标记为"确定”(OK)。在大多数浏览器中,也可以通过按"关闭”(close)按钮将其关闭,但这始终与“确定”按钮具有相同的作用。查看样例警告框。
See an example alert
WebDriver 可以从弹窗获取文本并接受或关闭这些警告。

# Click the link to activate the alert
driver.find_element(By.LINK_TEXT, "See an example alert").click()

# Wait for the alert to be displayed and store it in a variable
alert = wait.until(expected_conditions.alert_is_present())

# Store the alert text in a variable
text = alert.text

# Press the OK button
alert.accept()

2、Confirm 确认框

确认框类似于警告框,不同之处在于用户还可以选择取消消息。查看样例确认框。
See a sample confirm
此示例还呈现了警告的另一种实现:

# Click the link to activate the alert
driver.find_element(By.LINK_TEXT, "See a sample confirm").click()

# Wait for the alert to be displayed
wait.until(expected_conditions.alert_is_present())

# Store the alert in a variable for reuse
alert = driver.switch_to.alert

# Store the alert text in a variable
text = alert.text

# Press the Cancel button
alert.dismiss()

3、Prompt 提示框

提示框与确认框相似,不同之处在于它们还包括文本输入。与处理表单元素类似,您可以使用WebDriver 的 sendKeys 来填写响应。这将完全替换占位符文本。按下取消按钮将不会提交任何文本。查看样例提示框。
See a sample prompt

# Click the link to activate the alert
driver.find_element(By.LINK_TEXT, "See a sample prompt").click()

# Wait for the alert to be displayed
wait.until(expected_conditions.alert_is_present())

# Store the alert in a variable for reuse
alert = Alert(driver)

# Type your message
alert.send_keys("Selenium")

# Press the OK button
alert.accept()

测试文档 test_alert.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试 alert</title>  
</head>
<body>
    <div>
        <p>alert 测试</p>
        <!-- <input name="alert_bt" type="button" onClick="rec()" value="点击我,弹出对话框" />   -->
        <input type="button" name="alert_bt" onclick="window.alert('Sample alert')" value="See an example alert">
    </div>
    <div>
        <p>Confirm 测试</p>       
        <input type="button" name="confirm_bt" onclick="window.confirm('Are you sure?')" value="See a sample Confirm">    
    </div>
    <div>
        <p>Prompt 测试</p>       
        <input type="button" name="prompt_bt" onclick="window.prompt('What is your tool of choice?,navigator.appName')" value="See a sample Prompt">
    </div>
</body>
</html>

测试代码

from selenium import webdriver
from selenium.webdriver.common.alert import Alert
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
import os

driver =webdriver.Chrome()
test_path = os.path.join(os.getcwd(),'test_alert.html')
driver.get(test_path)
wait = WebDriverWait(driver,10,poll_frequency=0.5,ignored_exceptions=None)

# alert 测试

# Click the link to activate the alert
driver.find_element_by_name('alert_bt').click()

# Wait for the alert to be displayed and store it in a variable
alert = wait.until(EC.alert_is_present())

# Store the alert text in a variable
print(alert.text)

# Press the OK button
alert.accept()

# Confirm 测试
print('-'*100)

driver.find_element_by_name('confirm_bt').click()
wait.until(EC.alert_is_present())
alert = driver.switch_to.alert # alert = Alert(driver)
print(alert.text)
alert.dismiss()

# Prompt 测试
print('-'*100)

driver.find_element_by_name('prompt_bt').click()
wait.until(EC.alert_is_present())
alert = Alert(driver)
print(alert.text)
alert.send_keys("Selenium")
alert.accept()
driver.close()