在web自动化测试中,好像很少会出现多窗口和切换句柄的情景。我之前曾想过一个情景:如果我打开多个窗口,该怎样更快更好的切换句柄呢?今天做个小分享。
个人博客:https://blog.csdn.net/zyooooxie
一)切换句柄(handle)(1)
首先说明下情景:百度搜索Python,在搜索的结果中点击一个‘官网’的超链接,打开了一个新窗口(进入的是百度认证)。大家都知道 如果想对新窗口的元素进行操作,需要先切换句柄。断言句柄是否切换成功是 用打印title来判断。
def test_42a(self):
"""切换句柄"""
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.baidu.com")
baidu = driver.current_window_handle
print('--------' * 5)
print('当前句柄:', baidu)
print('当前页面的title:', driver.title)
self.xin_find_element(driver, By.ID, 'kw').send_keys('Python')
self.xin_find_element(driver, By.ID, 'su').click()
self.xin_find_element(driver, By.LINK_TEXT, '官网').click()
all_handles = driver.window_handles
print('所有的句柄: ', all_handles)
# 1.循环判断是否与首页句柄相等
# 2.如果不等,说明是新页面的句柄
# 3.获取的新页面句柄后,可以切换到新打开的页面上
# 4.打印新页面的title,看是否切换成功
for handle in all_handles:
if handle != baidu:
driver.switch_to.window(handle)
print('当前页面的title:', driver.title)
print('--------' * 5)
time.sleep(1)
driver.quit()
def test_42b(self):
"""切换句柄"""
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.baidu.com")
baidu = driver.current_window_handle
print('--------' * 5)
print('当前句柄:', baidu)
print('当前页面的title:', driver.title)
self.xin_find_element(driver, By.ID, 'kw').send_keys('Python')
self.xin_find_element(driver, By.ID, 'su').click()
self.xin_find_element(driver, By.LINK_TEXT, '官网').click()
all_handles = driver.window_handles
print('所有的句柄: ', all_handles)
# 直接获取all_h这个list数据里面第二个hand的值:all_h[1]
driver.switch_to.window(all_handles[1])
print('当前页面的title:', driver.title)
print('--------' * 5)
time.sleep(1)
driver.quit()
网上很多关于句柄的教程基本是这样,我没啥好说的。下图就是结果。
打开多个窗口,切换句柄(A)
使用js的脚本来打开新的浏览器窗口
def test_42c(self):
"""新增浏览器窗口,打印handle和title"""
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.baidu.com/")
hand11 = driver.current_window_handle
print('---------' * 5)
print('当前句柄:', hand11)
print('当前页面的title:', driver.title)
print('---------' * 5)
js1 = 'window.open("https://mail.qq.com/")'
driver.execute_script(js1)
# 此时新开一个窗口,句柄增多
hand13 = driver.current_window_handle
print('当前句柄:', hand13)
print('当前页面的title:', driver.title)
all_handles = driver.window_handles
print('所有的句柄: ', all_handles)
driver.switch_to.window(all_handles[1])
print('当前页面的title:', driver.title)
hand13 = driver.current_window_handle
print('当前句柄:', hand13)
print('---------' * 5)
# driver.get("https://mail.163.com/")
# driver.get() 只是把浏览器的网址改变。非新打开浏览器窗口
js2 = 'window.open("https://mail.163.com/")'
driver.execute_script(js2)
hand14 = driver.current_window_handle
print('当前句柄:', hand14)
print('当前页面的title:', driver.title)
all_handles = driver.window_handles
print('所有的句柄: ', all_handles)
driver.switch_to.window(all_handles[2])
print('当前页面的title:', driver.title)
hand13 = driver.current_window_handle
print('当前句柄:', hand13)
print('---------' * 5)
time.sleep(1)
driver.quit()
看结果 就知道:即使已经打开新的窗口,你的句柄和title还是前面窗口的,这就是切换句柄的原因了。
打开多个窗口,切换句柄(B)
A 好多重复代码,一点不简洁,不优雅。
下图 我把网址放进一个list,循环遍历下。
def test_42d1(self):
"""打开不同标签页面,切换句柄,打印标题"""
driver = webdriver.Chrome()
driver.maximize_window()
web = ['https://mail.163.com/', 'https://mail.qq.com/', 'https://www.baidu.com/', 'https://mail.sina.com.cn/', 'https://exmail.qq.com/login', 'http://mail.10086.cn/', 'https://www.126.com/']
for w in web:
js = 'window.open("%s")' % w
driver.execute_script(js)
print('--------------' * 6)
print(w)
print(web.index(w))
print('所有的句柄: ', driver.window_handles)
driver.switch_to.window(driver.window_handles[int(web.index(w)) + 1])
print('当前句柄:', driver.current_window_handle)
print('当前title:', driver.title)
print('--------------' * 6)
time.sleep(1)
driver.quit()
每次切换的句柄在所有句柄list的index是 列表的index + 1
我的谷歌浏览器每次新开会是空白标签,我把没切换句柄前的 打印句柄那行代码 删掉了。
打开多个窗口,切换句柄 (C )
def test_42d2(self):
"""打开不同标签页面,切换句柄,打印标题"""
driver = webdriver.Chrome()
driver.maximize_window()
web = ['https://mail.163.com/', 'https://mail.qq.com/', 'https://www.baidu.com/', 'https://mail.sina.com.cn/', 'https://exmail.qq.com/login', 'http://mail.10086.cn/', 'https://www.126.com/']
for w in web:
js = 'window.open("%s")' % w
driver.execute_script(js)
print('--------------' * 6)
print(w)
print(web.index(w))
print('当前句柄:', driver.current_window_handle)
print('所有的句柄: ', driver.window_handles)
driver.switch_to.window(driver.window_handles[-1])
print('当前句柄:', driver.current_window_handle)
print('当前title:', driver.title)
print('--------------' * 6)
time.sleep(1)
driver.quit()
没切换句柄前的打印句柄 那行代码保留了,没做修改。
每次切换的句柄实际也是 所有的句柄list的最后一个。
二)切换句柄(handle)(2)
所以根据C的经验,
一)(1) 里面的第二个脚本 driver.switch_to.window(all_handles[1])
也可以更改为: driver.switch_to.window(all_handles[-1])
实际考虑起来,好像 取list的最后一位值 更合适。
def test_42b2(self):
"""切换句柄"""
driver = webdriver.Chrome()
driver.maximize_window()
driver.get("https://www.baidu.com")
baidu = driver.current_window_handle
print('--------' * 5)
print('当前句柄:', baidu)
print('当前页面的title:', driver.title)
self.xin_find_element(driver, By.ID, 'kw').send_keys('Python')
self.xin_find_element(driver, By.ID, 'su').click()
self.xin_find_element(driver, By.LINK_TEXT, '官网').click()
all_handles = driver.window_handles
print('所有的句柄: ', all_handles)
# 直接获取all_h这个list数据里面最后一个值:all_h[-1]
driver.switch_to.window(all_handles[-1])
print('当前页面的title:', driver.title)
print('--------' * 5)
time.sleep(1)
driver.quit()
交流技术 欢迎+QQ 153132336 zy
个人博客 https://blog.csdn.net/zyooooxie