5-UI自动化-三大切换,iframe如何定位,窗口新开、alert弹窗如何进行元素定位
- 新开一个窗口如何定位元素
- switch_to方法
- iframe定位元素
- alert弹窗如何定位元素
上篇介绍4-UI自动化-selenium三大等待操作
web测试过程中有没有遇到以下问题:
1、测试过程中遇到点击后打开了一个新的窗口,这种要如何定位呢?
2、页面嵌套iframe,如何定位元素?
3、有些甚至有alert弹窗,(基本较少,一些银行网站可能会有),如何定位元素?
本篇就来一一介绍
♡ \color{red}{\heartsuit} ♡
新开一个窗口如何定位元素
比如我输入百度url,输入淘宝,点击打开淘宝,然后在淘宝搜索连衣裙,点击淘宝会新开一个窗口,那么这个如何定位呢?
先要了解下窗口句柄的概念。窗口句柄其实可以理解为是窗口的id。
Python的WebDriver模块中,提供了相关方法。
这里截取了current_window_handle()和window_handles()源码,从方法名其实就可以看出,current_window_handle是当前窗口句柄,返回的是一个str类型,window_handles()是返回当前会话的所有窗口,是一个列表。
@property
def current_window_handle(self) -> str:
"""
Returns the handle of the current window.
:Usage:
::
driver.current_window_handle
"""
return self.execute(Command.W3C_GET_CURRENT_WINDOW_HANDLE)['value']
@property
def window_handles(self) -> List[str]:
"""
Returns the handles of all windows within the current session.
:Usage:
::
driver.window_handles
"""
return self.execute(Command.W3C_GET_WINDOW_HANDLES)['value']
可以看到,打印出来两个窗口,第一个f75e8ddc-5367-47e2-b458-1a7681ce9e13是百度搜索窗口id,第二个是淘宝页面的窗口id,但是当前的句柄是在百度搜索页面窗口,也就是说,如果要在淘宝页面进行元素定位,需要先将窗口句柄切换到淘宝页面,才能进行元素定位。
那么如何切换窗口呢?
Python的WebDriver模块提供了switch_to方法,源码如下。注释部分已经为我们提供了几种切换用法,有切换iframe,切换窗口,退回主页面…
switch_to方法
方法 | 作用 |
---|---|
alert = driver.switch_to.alert | 切换alter弹窗 |
driver.switch_to.default_content() | 退回主页面 |
driver.switch_to.frame(‘frame_name’) | 通过窗口名切换窗口 |
driver.switch_to.frame(0) | 通过索引切换窗口 |
driver.switch_to.parent_frame() | 退回父级iframe |
@property
def switch_to(self) -> SwitchTo:
"""
:Returns:
- SwitchTo: an object containing all options to switch focus into
:Usage:
::
element = driver.switch_to.active_element
alert = driver.switch_to.alert
driver.switch_to.default_content()
driver.switch_to.frame('frame_name')
driver.switch_to.frame(1)
driver.switch_to.frame(driver.find_elements_by_tag_name("iframe")[0])
driver.switch_to.parent_frame()
driver.switch_to.window('main')
"""
return self._switch_to
我们用switch_to.window()就可以解决我们的问题,需要将窗口id传进去,但是print(self.driver.current_window_handle) handles = self.driver.window_handles
获取到的分别是当前窗口(百度页面),和所有窗口,所有窗口列表中第二个是我们想要元素定位的窗口,那么要怎么传进第二个窗口名呢?不要忘了,它是一个列表,通过列表的取值就可以获取,-1表示获取最后一个窗口,也就是我们新开的窗口。self.driver.switch_to.window(handles[-1])
切换到新窗口。
可以看到成功切换窗口了,那么接下来就回到老知识了,用之前学习过的元素定位就可以了
最终代码
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions
class SwitchSample:
def __init__(self):
self.driver = webdriver.Firefox()
# 在打开浏览器驱动等待3s,再去输入url
self.driver.implicitly_wait(3)
self.driver.get('http://baidu.com')
def switch_window(self):
self.driver.find_element(By.ID, 'kw').send_keys('淘宝')
# 在点击百度一下前先等待2s
self.driver.find_element(By.ID, 'su').click()
# 在输出浏览器的标题前,先等待3s,防止浏览器还未加载完全
time.sleep(3)
# 点击淘宝
self.driver.find_element(By.LINK_TEXT, '淘宝').click()
print(self.driver.title)
print("当前的窗口{}".format(self.driver.current_window_handle))
handles = self.driver.window_handles
print("当前所有窗口{}".format(handles))
self.driver.switch_to.window(handles[-1])
print(f"切换后新的窗口{self.driver.current_window_handle}")
time.sleep(2)
self.driver.find_element(By.ID, 'q').send_keys('连衣裙')
print(self.driver.current_url, self.driver.title)
time.sleep(2)
self.driver.close()
self.driver.quit()
if __name__ == '__main__':
ss = SwitchSample()
ss.switch_window()
♡ \color{red}{\heartsuit} ♡
iframe定位元素
IFRAME是HTML标签,作用是文档中的文档,或者浮动的框架(FRAME)。iframe元素会创建包含另外一个文档的内联框架(即行内框架)。
如果你用Selenium定位的目标元素在某个iframe里,需要先执行switch_to_frame,否则会找不到元素。
标签是一个内联框架,即用来在当前 HTML 页面中嵌入另一个文档的,且所有主流浏览器都支持iframe标签。如网易云音乐网站,https://music.163.com/,点击进入网页,F12,查看网页elements,然后点击用户登录。用户登录的id属性为"index-enter-default"。
如果直接通过定位元素driver.find_element(By.ID, "index-enter-default").click()
,会出现报错:selenium.common.exceptions.NoSuchElementException: Message: Unable to locate element: [id="index-enter-default"]
因为用户登录是在iframe中的
如果想找一个 iframe 当中的元素,不能直接查找,而是先要进入iframe当中。
我们先要定位iframe元素,进入iframe中,然后再去定位iframe当中的元素。代码实现如下:
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
class SwitchIframe:
def __init__(self):
self.driver = webdriver.Firefox()
self.driver.maximize_window()
# 在打开浏览器驱动等待3s,再去输入url
self.driver.implicitly_wait(3)
self.driver.get('https://music.163.com/')
def switch_iframe(self):
# 先定位iframe元素,然后切换进入iframe
iframe = self.driver.find_element(By.ID, "g_iframe")
# 等待iframe切换成功
wait = WebDriverWait(self.driver, 3)
wait.until(expected_conditions.frame_to_be_available_and_switch_to_it(iframe))
# 加入显式等待,让代码更智能,增强代码的健壮性
# self.driver.switch_to.frame(iframe)
# 找到用户登录,点击
self.driver.find_element(By.ID, "index-enter-default").click()
print(self.driver.title)
time.sleep(2)
self.driver.close()
self.driver.quit()
if __name__ == '__main__':
si = SwitchIframe()
si.switch_iframe()
可以用显式等待,等待直到iframe切换成功。在代码中加入这些即可,不知道显式等待的,可以看下我的上篇介绍。
# 等待iframe切换成功
wait = WebDriverWait(self.driver, 3)
wait.until(expected_conditions.frame_to_be_available_and_switch_to_it(iframe))
♡ \color{red}{\heartsuit} ♡
alert弹窗如何定位元素
alter弹窗的切换也是类似的,只是把上面的代码改吧改吧,wait.until(expected_conditions.alert_is_present())
目前alter弹窗用的也相对少了,我找不到网站来演示。暂时不介绍了。之后有相关的,再补充。
哈哈哈,终于让我找到了别人写的弹窗:web自动化测试-文件上传与弹框处理
以下摘抄了一些这位网页写的
在页面操作中有时会遇到 JavaScript 所生成的 alert、confirm 以及 prompt 弹框,可以使用 switch_to.alert () 方法定位到。然后使用 text、accept、dismiss、send_keys 等方法进行操作。
- text:返回 alert、confirm、prompt 中的文字信息。
- accept ():接受现有警告框,即点击确定。
- dismiss ():解散现有警告框,即点击取消。
send_keys (keysToSend):发送文本至警告框。keysToSend: 将文本发送至警告框。
输入一段文本点击比如提交按钮,会弹出确认内容的弹框,这种场景可以使用下面的方式处理:
通过name属性定位元素
同理,如果想要自定义输出弹窗内容,定位输入的元素,输入自定义内容即可。
import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
class AlertDemo:
def __init__(self):
self.driver = webdriver.Firefox()
self.driver.maximize_window()
self.driver.implicitly_wait(3)
def switch_alert(self):
"""Alert弹窗获取文本与确认操作"""
self.driver.get("http://sahitest.com/demo/alertTest.htm")
time.sleep(3)
# 可以自定义弹窗的输出内容
wait = WebDriverWait(self.driver, 5, 0.5)
locator = ('xpath', '//input[@name="t1"]')
wait.until(expected_conditions.visibility_of_element_located(locator)).send_keys('金聪聪,冲冲冲')
# self.driver.find_element('xpath', '//h2').send_keys("金聪聪,冲冲冲!")
self.driver.find_element(By.NAME, "b1").click()
# 添加显示等待,等待弹框的出现
WebDriverWait(self.driver, 5, 0.5).until(expected_conditions.alert_is_present())
# 切换到弹框
alert = self.driver.switch_to.alert
# 打印弹框的文本
print(alert.text)
time.sleep(3)
# 点击确定,弹窗消失
alert.accept()
# 点击取消或者关闭弹框
# alert.dismiss()
if __name__ == '__main__':
ad = AlertDemo()
ad.switch_alert()
下节分享6-UI自动化-鼠标键盘操作