一.selenium简介
1.什么是selenium
Selenium是一个用于Web应用程序测试的工具。Selenium测试直接运行在浏览器中,就像真正的用户在操作一样。支持的浏览器包括IE(7, 8, 9, 10, 11),Mozilla Firefox,Safari,Google Chrome,Opera,Edge等。
2.selenium三大组件
-
WebDriver:是selenium提供的一个API,用于操作浏览器。
-
IDE:是selenium提供的一个插件,可以录制用户的操作
-
Grid:是selenium分布式的工具,实现在多个浏览器操作。使用Grid可以轻松实现用例的分布式执行。
-
我们编写自动化主要使用WebDriver来实现,我们后面所指的selenium默认也是WebDriver
3.selenium的工作原理
4.selenium环境准备
- 在python中安装selenium
pip install selenium
- 配置浏览器驱动
下载driver:https://npm.taobao.org/mirrors/,选择对应的浏览器driver已经对应的版本,下载zip包。
将浏览器driver配置待环境变量,或者使用driver时指定路径。
5.selenium编写测试用例的步骤
(1)导入依赖
(2)生成driver
(3)执行测试步骤
(4)断言
import time
from selenium import webdriver # 导入selenium
# 使用webdriver,生成一个对应浏览器的driver。该driver提供了许多操作浏览器的API。
# 使用executable_path来指定chromedriver路径,如果将chromedriver.exe配置在了环境变量中,则不需要指定。
driver = webdriver.Chrome(executable_path='./etc/chromedriver.exe')
# 使用driver的api执行测试步骤
driver.get('https://www.baidu.com/') # 打开浏览器
driver.find_element_by_id('kw').send_keys('selenium') # 定位元素,并输入内容
driver.find_element_by_id('su').click() # 定位并点击元素
time.sleep(3)
# 断言
assert 'selenium' in driver.title
二.selenium的webdriver的常用API
1.webdriver访问网站API
from selenium import webdriver # 导入selenium
driver = webdriver.Chrome(executable_path='./etc/chromedriver.exe')
driver.get('https://www.baidu.com/') # 访问网站
2.元素定位API
selenium中提供了八种元素定位的方式。
(1)id定位
通过id属性来定位元素,定位唯一.
格式:
# 找到界面上id为'kw'的元素,以下两种方式效果一样.
1.driver.find_element_by_id('kw')
2.driver.find_element(By.ID,'kw')
(2)name定位
通过 name 属性来定位元素,定位唯一
# 找到界面上name为'sss'的单个元素,以下两种方式效果一样.
driver.find_element_by_name('sss')
driver.find_element(By.NAME,'sss')
# 找到界面上name为'sss'的所有元素,以下两种方式效果一样.
driver.find_elements_by_name('sss')
driver.find_elements(By.NAME,'sss')
(3)class name 定位
通过元素的 class 属性来定位元素,name和id在所有元素中是唯一的
# 找到界面上class为'sss'的单个元素,以下两种方式效果一样.
driver.find_element_by_class_name('sss')
driver.find_element(By.CLASS_NAME,'sss')
# 找到界面上class为'sss'的所有元素,以下两种方式效果一样.
driver.find_elements_by_class_name('sss')
driver.find_elements(By.CLASS_NAME,'sss')
(4)link_text定位
通过链接文本信息来定位,只能用于a标签
driver.find_element_by_link_text('内容')
driver.find_element(By.LINK_TEXT,'内容')
(5)partial link text 定位
对 link text 定位的补充,有些文本链接比较长,或者这些文本链接其中有一部分文本信息是动态生成的,这个时候,可以选择文本链接的一部分进行定位,只要这部分信息可以唯一的标识这个链接。
driver.find_element_by_partial_link_text('内容')
driver.find_element(By.PARTIAL_LINK_TEXT,'内容')
(6)tag 定位
通过元素的标签名来定位元素
driver.find_element_by_tag_name('内容')
driver.find_element(By.TAG_NAME,'内容')
(7)xpath定位
格式:
1.driver.find_element_by_xpath('xpath路径')
2.driver.find_elements(By.XPATH,'xpath路径')
xpath详解:
练习:
//div[@id="wraf"] #定位到id=wraf的div元素
//*[@id="wraf"] #定位到id=wraf的元素,*表示类型不限
//*[@id="wraf"]/* #定位到id=wraf的元素的所有子集元素,*表示类型不限
//*[@id="wraf"]/div #定位到id=wraf的元素的所有子集div元素
//*[@id="wraf"]//a #定位到id=wraf的元素的所有子集以及子集的子集(无论差几级)中的所有的a元素
//*[contains(@id,"kw")] #定位到id包含wraf的元素
//*[text()="wraf"] # 定位到文本内容为wraf的元素
//*[contains(text(),"wraf")] # 定位到文本内容包含wraf的元素
//*[@id="wraf" and @class="asdff"] # 定位id为wraf且class为asdff的元素
(8)css_selector定位
格式:
1.driver.find_element_by_css_selector('css路径')
2.driver.find_element(By.CSS_SELECTOR,'css路径')
css详解:
练习:
#wraf #定位id为wraf的元素
#wraf>div #定位id为wraf的元素的子集中的所有div元素
#wraf a #定位id为wraf的元素的子子孙孙集中的所有a元素
#wraf a:nth-child(2) #定位id为wraf的元素的子子孙孙集中的所有a元素,且这些a元素属于它父级的第二个子元素。
3.鼠标点击:定位元素后.click()
driver.find_element_by_id('su').click()
4.输入内容:定位元素后.send_keys(“内容”)
driver.find_element_by_id('kw').send_keys('自动化测试')
5.清空内容:定位元素后.clear()
element = driver.find_element(By.ID,'kw')
element.send_keys('自动化测试')
sleep(2)
element.clear()
6.退出浏览器
driver.quit()
7.获取页面title
s = driver.title
8.最大化浏览器窗口
driver.maximize_window()
9.等待方式
9.1 页面元素加载顺序
9.2 直接等待
from time import sleep
sleep(3) # 线程休眠3秒
9.3 隐式等待
driver.implicitly_wait(5)
# 在5秒内不断检测元素是否出现,出现就结束等待,执行下一步。如果5秒内没有出现就抛出异常
# 隐式等待是作用在全局的,一般放在setup中
# 隐式等待有一个缺点:因为隐式等待是针对全局的元素而言的,而每个元素的加载时间是不一样的。所以隐式等待的等待时间是不能很好的兼容所有元素。
# 使用隐式等待会有这个bug,就是元素已经出现,但不能被点击。所以导致用例失败。这是因为浏览器加载时,会先加载DOM节点,然后再加载js等静态文件,所以会出现元素已经出现,但无法点击的问题。
9.4 显示等待
格式:
# 在规定的时间内不断的调用方法1,直到方法1返回True,结束等待。超时抛出异常
WebDriverWait(driver驱动,等待时间).until(方法1)
# 在规定的时间内不断的调用方法1,直到方法1返回False,结束等待。超时抛出异常
WebDriverWait(driver驱动,等待时间).until_not(方法1)
until后的方法,selenium中有许多。我们介绍几种常用的:
- expected_conditions.presence_of_element_located----判断某个元素是否被加到了 dom 树里,并不代表该元素一定可见
from selenium import webdriver # 导入依赖
from time import sleep
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
element = WebDriverWait(driver,10).until(EC.presence_of_element_located((By.ID,'kw')))
# 显式等待:直到对应的元素出现,就结束等待。并且定位到该元素
element.send_keys('selenium')
-
expected_conditions.visibility_of_element_located-----判断某个元素是否可见. 可见代表元素非隐藏,并且元素的宽和高都不等于 0
-
expected_conditions.presence_of_all_elements_located—判断是否至少有 1 个元素存在于 dom 树中。举个例子,如果页面上有 n 个元素的 class 都是’column-md-3’,那么只要有 1 个元素存在,这个方法就返回 True
-
expected_conditions.text_to_be_present_in_element—判断某个元素中的 text 是否 包含 了预期的字符串
-
expected_conditions.text_to_be_present_in_element_value----判断某个元素中的 value 属性是否包含 了预期的字符串
-
expected_conditions.invisibility_of_element_located----判断某个元素中是否不存在于dom树或不可见
-
expected_conditions.element_to_be_clickable—判断某个元素中是否可见并且是 enable 的,这样的话才叫 clickable
-
expected_conditions.element_to_be_selected—判断某个元素是否被选中了,一般用在下拉列表
10.action接口
10.1 简介
selenium给我们提供了两种操作浏览器控件的actions接口:
10.2 ActionChains
(1).鼠标单击,双击,左键操作
from selenium import webdriver
from selenium.webdriver import ActionChains
import pytest
class TestSelenium:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.get("http://sahitest.com/demo/clicks.htm")
self.driver.implicitly_wait(5)
def teardown(self):
self.driver.close()
def test_selenium(self):
# 定位元素
element_click = self.driver.find_element_by_xpath("//*[@value='click me']")
element_double_click = self.driver.find_element_by_xpath("//*[@value='dbl click me']")
element_right_click = self.driver.find_element_by_xpath("//*[@value='right click me']")
# 创建一个action
action = ActionChains(self.driver)
# 给action添加需要执行的方法
action.click(element_click) # 鼠标左键单击
action.double_click(element_double_click) # 鼠标左键双击
action.context_click(element_right_click) #鼠标右键点击
# 执行action
action.perform()
(2).鼠标移动到某个元素上
from selenium import webdriver
from selenium.webdriver import ActionChains
import pytest
from time import sleep
class TestSelenium:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.driver.maximize_window() #最大化窗口
def teardown(self):
self.driver.close()
def test_move(self):
self.driver.get("https://www.baidu.com/")
# 定位元素
ele = self.driver.find_element_by_id("s-usersetting-top")
# 创建action
action = ActionChains(self.driver)
# 给action添加操作方法
action.move_to_element(ele) # 移动到元素上,但不点击
# 执行action
action.perform()
(3).拖拽一个元素到另一个元素上
方法一:
from selenium import webdriver
from selenium.webdriver import ActionChains
import pytest
from time import sleep
class TestSelenium:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.driver.maximize_window() #最大化窗口
def teardown(self):
self.driver.close()
def test_drag_drop(self):
self.driver.get("http://sahitest.com/demo/dragDropMooTools.htm")
# 定位元素
drag_ele = self.driver.find_element_by_id("dragger")
drop_ele = self.driver.find_element_by_xpath("/html/body/div[2]")
# 创建action
action = ActionChains(self.driver)
# 给action添加操作方法
action.drag_and_drop(drag_ele,drop_ele) # 拖拽并移动,传入两个参数,第一个为需要退拽的元素,第二个为释放位置的元素
# 执行action
action.perform()
方法二:
from selenium import webdriver
from selenium.webdriver import ActionChains
import pytest
from time import sleep
class TestSelenium:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.driver.maximize_window() #最大化窗口
def teardown(self):
self.driver.close()
def test_drag_drop(self):
self.driver.get("http://sahitest.com/demo/dragDropMooTools.htm")
# 定位元素
drag_ele = self.driver.find_element_by_id("dragger")
drop_ele = self.driver.find_element_by_xpath("/html/body/div[2]")
# 创建action
action = ActionChains(self.driver)
# 给action添加操作方法
action.click_and_hold(drag_ele) # 按下不放手
action.release(drop_ele) # 释放鼠标
# 执行action
action.perform()
(4).模拟键盘操作
from selenium import webdriver
from selenium.webdriver import ActionChains
import pytest
from time import sleep
from selenium.webdriver.common.keys import Keys
class TestSelenium:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.driver.maximize_window() #最大化窗口
def teardown(self):
self.driver.close()
def test_keys(self):
self.driver.get("http://sahitest.com/demo/label.htm")
# 定位元素
ele1 = self.driver.find_element_by_xpath("/html/body/label[1]/input")
ele2 = self.driver.find_element_by_xpath("/html/body/label[2]/table/tbody/tr/td[2]/input")
# 创建action
action = ActionChains(self.driver)
# 给action添加操作方法
ele1.click()
action.send_keys("ouyi1") # 输入内容
action.send_keys(Keys.SPACE) #输入空格
action.send_keys("ouyi2") # 输入内容
action.send_keys(Keys.CONTROL,'a') #全选
action.send_keys(Keys.CONTROL, 'c') # 复制
ele2.click()
action.send_keys(Keys.CONTROL, 'v') # 粘贴
# 执行action
action.perform()
10.3 TouchActions
注意:在web端使用TouchActions时,需要修改谷歌浏览器的启动options
(1)实现滑动
方式一:scroll_from_element----从某个元素开始滑动
from selenium import webdriver
from selenium.webdriver import ActionChains,TouchActions
import pytest
from time import sleep
from selenium.webdriver.common.keys import Keys
class TestSelenium:
def setup(self):
# 设置谷歌的启动配置options
option = webdriver.ChromeOptions()
option.add_experimental_option('w3c',False) #设置谷歌启动方式不要为w3c
self.driver = webdriver.Chrome(options=option)
self.driver.implicitly_wait(5)
self.driver.maximize_window() #最大化窗口
def teardown(self):
self.driver.quit()
def test_touch1(self):
self.driver.get("https://www.taobao.com/")
# 定位元素
ele = self.driver.find_element_by_id("J_TSearchForm")
# 创建action
action = TouchActions(self.driver)
# 给action添加操作方法
"""从某个元素开始滑动。传入三个参数,第一个为开始作为滑动起点的元素,第一个为X偏移量,第三个为y偏移量"""
action.scroll_from_element(ele,0,10000)
# 执行action
action.perform()
方式二:action.scroll(x偏移量,y偏移量)------从当前位置滑动指定的偏移量
action.scroll(0,1000)
11.多窗口的处理
11.1多窗口的识别
(1)获取当前窗口的句柄
driver.current_window_handle #返回当前的窗口句柄
(2)获取所有窗口的句柄
self.driver.window_handles # 返回一个包含所有窗口句柄的列表
11.2多窗口的切换
self.driver.switch_to_window(对应的窗口句柄) #切换到对应的窗口
12.frame处理
12.1 frame简介
12.2 frame的切换
13.selenium多浏览器的处理
我们可以将浏览器作为一个参数,传递给参数用例。来做浏览器的兼容性处理
from selenium import webdriver
from selenium.webdriver import ActionChains,TouchActions
import pytest
from time import sleep
from selenium.webdriver.common.keys import Keys
import os
class TestBroswer:
def setup(self):
# 获取执行测试用例时传入的broswer的值,来判断使用哪个浏览器
broswer = os.getenv('broswer')
if broswer == 'firefox':
self.driver = webdriver.Firefox()
elif broswer == 'chrome':
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.driver.maximize_window() # 最大化窗口
def teardown(self):
self.driver.quit()
def test_broswer(self):
self.driver.get("https://www.baidu.com/")
self.driver.find_element_by_id('kw').send_keys('selenium')
self.driver.find_element_by_id('su').click()
这样我们在执行测试用例时,只需要传入broswer对应的值,就可以使用对应的浏览器了。
broswer=chrome pytest -v test_selenium.py
14.selenium执行JavaScript
在自动化测试中,经常会有一些组件无法定位到。这时需要使用js来进行定位操作。因此我们可以所以selenium中提供的接口来执行JavaScript命令。
14.1 selenium执行JavaScript命令
方式一:执行js命令:driver.execute_script(‘js命令’)
from selenium import webdriver
from time import sleep
class TestJs:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.driver.maximize_window()
def teardown(self):
self.driver.quit()
def test_js(self):
self.driver.get("https://www.baidu.com/")
# 使用selenium执行js脚本
self.driver.execute_script('alert("selenium")')
sleep(3)
方式二:执行js命令,并将结果返回给selenium代码:driver.execute_script(‘return js命令’)
from selenium import webdriver
from time import sleep
class TestJs:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.driver.maximize_window()
def teardown(self):
self.driver.quit()
def test_js(self):
self.driver.get("https://www.baidu.com/")
# 使用selenium执行js脚本
ele1 = self.driver.execute_script('return document.getElementById("kw")')
ele1.send_keys("selenium")
ele2 = self.driver.execute_script('return document.getElementById("su")')
ele2.click()
sleep(3)
14.2使用js处理时间控件
from selenium import webdriver
from time import sleep
class TestJs:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.driver.maximize_window()
def teardown(self):
self.driver.quit()
def test_js(self):
self.driver.get("https://www.12306.cn/index/")
# 使用selenium执行js脚本
# 定位到时间控件元素,并移除时间控件的readonly属性
self.driver.execute_script('a = document.getElementById("train_date");a.removeAttribute("readonly")')
self.driver.execute_script('a.value="2020-12-22"') #给时间控件的value赋值
sleep(3)
15.selenium处理文件上传
from time import sleep
from selenium import webdriver
class Test_File:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.driver.maximize_window()
def teardown(self):
self.driver.quit()
def test_file(self):
self.driver.get('https://www.baidu.com/')
self.driver.find_element_by_xpath('//*[@id="form"]/span[1]/span[1]').click() #点击按图片搜索按钮
ele = self.driver.find_element_by_xpath('//*[@id="form"]/div/div[2]/div[2]/input') #定位到上传文件按钮
ele.send_keys('/home/ouyi/goods02.jpg') #上传图片
注意:如果文件上传控件不是input等浏览器元素,那么使用selenium是无法定位到的。我们需要使用其他工具,例如AUTOIT等来定位,这里不做具体讲解。
16.selenium处理弹窗
案例:
from time import sleep
from selenium import webdriver
from selenium.webdriver import ActionChains
class TestAlert:
"""
打开网页:https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable
将frame页面的元素1拖拽到元素2
这时会有一个alert弹窗,操作接受alert弹窗
点击界面的运行按钮
"""
def setup(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.driver.maximize_window()
def teardown(self):
self.driver.quit()
def test_alter(self):
self.driver.get('https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable') #打开网页
self.driver.switch_to_frame('iframeResult') #切换到frame窗口
drag_ele = self.driver.find_element_by_id('draggable') #定位元素1
drop_ele = self.driver.find_element_by_id('droppable') #定位元素2
action = ActionChains(self.driver) #创建action
action.drag_and_drop(drag_ele,drop_ele) #添加拖拽方法
action.perform() #执行action的方法
sleep(2)
alert_ele = self.driver.switch_to_alert() #获取界面弹窗对象
alert_ele.accept() #接受弹窗
self.driver.switch_to.parent_frame() #退出frame窗口
self.driver.find_element_by_id('submitBTN').click() #点击运行按钮
sleep(2)
17.selenium实现浏览器的复用
我们在selenium中如果以默认的self.driver = webdriver.Chrome()来打开一个浏览器,这种方式是打开一个全新的浏览器。我们可以给 webdriver.Chrome()传入option参数,来实现浏览器的复用。从而保存下浏览器已经有的状态和数据。
例如:我们要测试一个网站,它的许多测试点都需要登录后才能操作的。而它的登录不能实现自动化,那么我们可以启动浏览器,将其登录完成。然后在其他的测试用例中,就可以使用这个已经登录的浏览器,而不是去启动一个全新的浏览器。
以登录企业微信为例
第一步:确保chrome程序的启动文件已经配置到环境变量(usr/bin中)
第二步:在终端以端口(9222,也可以是其他未占用的端口),启动一个chrome程序。
google-chrome --remote-debugging-port=9222
然后手动打开企业微信网站:https://work.weixin.qq.com/wework_admin/frame
手动扫码登录
第三步:编写selenium自动化脚本:使用options方法,指定要打开的浏览器程序。
from time import sleep
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
class Testbroswer:
def setup(self):
option = Options() #创建一个option对象
option.debugger_address = '127.0.0.1:9222' #option使用指定的浏览器程序
self.driver = webdriver.Chrome(options=option) #使用指定的option生成driver
self.driver.implicitly_wait(5)
self.driver.maximize_window()
def teardown(self):
self.driver.quit()
def test_broswer(self):
self.driver.get("https://work.weixin.qq.com/wework_admin/frame") #此时进入企业微信网页时,就已经是登录状态了
self.driver.find_element_by_id('menu_contacts').click() #点击通讯录按钮
sleep(10)
18.selenium使用cookie
上面的案例,我们想要实现企业微信的跳过登录。除了可以复用浏览器外,还可以使用cookie功能。
第一步:打开浏览器,
第二步:获取cookie:self.driver.get_cookies()
登录企业微信。使用代码 self.driver.get_cookies() 获取页面的cookies
第二步:编写测试用例,在新的浏览器打开企业微信页面,使用传入cookie()
from selenium import webdriver
from time import sleep
class TestCookie:
def setup(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(5)
self.driver.maximize_window()
def teardown(self):
self.driver.quit()
def test_cookie(self):
# 将cookies放入变量中
cookies = [
{'domain': '.work.weixin.qq.com', 'httpOnly': False, 'name': 'wwrtx.vid', 'path': '/', 'secure': False,
'value': '1688850814799304'},
{'domain': '.work.weixin.qq.com', 'httpOnly': True, 'name': 'wwrtx.vst', 'path': '/', 'secure': False,
'value': 't9WeHiLQAywSBmGmI12gOsE0ilqI3OJIxMS66KYmvznSI4VRY3ZxzJbFifXMg5f_QmSTOcfJ-1CesO3czeqYLiBwe7PMQttF54rA2hSBCXMNbVnb42PLJOco1ntRxj2f927lX2RRoj4sPH0gkB7QKglF-4TAAwwWXOSDXHx2j4Z7cS0yjmikvvsvb0E50u99c9t0zHJJ4AC9rsufkv-YWn_Zp7PGiLFeSP1upcN2xOSw2vP_lgJ4p4LtHvRMJK6nEXMJkliTZ7a8qwRROS8r2w'},
{'domain': '.work.weixin.qq.com', 'httpOnly': False, 'name': 'wxpay.vid', 'path': '/', 'secure': False,
'value': '1688850814799304'},
{'domain': '.work.weixin.qq.com', 'httpOnly': False, 'name': 'wxpay.corpid', 'path': '/', 'secure': False,
'value': '1970325100191509'}, {'domain': '.work.weixin.qq.com', 'expiry': 1636300223, 'httpOnly': False,
'name': 'Hm_lvt_9364e629af24cb52acc78b43e8c9f77d', 'path': '/',
'secure': False, 'value': '1604758667,1604758842,1604764224'},
{'domain': '.work.weixin.qq.com', 'httpOnly': True, 'name': 'wwrtx.ref', 'path': '/', 'secure': False,
'value': 'direct'},
{'domain': '.work.weixin.qq.com', 'httpOnly': True, 'name': 'wwrtx.ltype', 'path': '/', 'secure': False,
'value': '1'},
{'domain': '.work.weixin.qq.com', 'httpOnly': False, 'name': 'wwrtx.d2st', 'path': '/', 'secure': False,
'value': 'a8686426'},
{'domain': '.work.weixin.qq.com', 'httpOnly': True, 'name': 'wwrtx.sid', 'path': '/', 'secure': False,
'value': 'XpgcPt60DeBa2-FcophxYISeXtHo4nMqsljZ5C7mKq1OfUBAg0klxY7ixrRkKe2m'},
{'domain': '.work.weixin.qq.com', 'httpOnly': True, 'name': 'wwrtx.refid', 'path': '/', 'secure': False,
'value': '2298449271234700'},
{'domain': '.qq.com', 'expiry': 1604851539, 'httpOnly': False, 'name': '_gid', 'path': '/', 'secure': False,
'value': 'GA1.2.1592559454.1604758667'},
{'domain': 'work.weixin.qq.com', 'expiry': 1604790194, 'httpOnly': True, 'name': 'ww_rtkey', 'path': '/',
'secure': False, 'value': '1iqo9pj'},
{'domain': '.qq.com', 'expiry': 1667837139, 'httpOnly': False, 'name': '_ga', 'path': '/', 'secure': False,
'value': 'GA1.2.1580179371.1604758667'},
{'domain': '.work.weixin.qq.com', 'expiry': 1636294658, 'httpOnly': False, 'name': 'wwrtx.c_gdpr',
'path': '/', 'secure': False, 'value': '0'},
{'domain': '.work.weixin.qq.com', 'expiry': 1607357565, 'httpOnly': False, 'name': 'wwrtx.i18n_lan',
'path': '/', 'secure': False, 'value': 'zh'}]
self.driver.get("https://work.weixin.qq.com/wework_admin/frame#contacts") #第一次打开网页
# 传入cookie
for cookie in cookies:
self.driver.add_cookie(cookie)
self.driver.get("https://work.weixin.qq.com/wework_admin/frame#contacts") #再次打开网页,此时变为了登录状态
sleep(5)
注意:使用cookie登录时,一定要先打开网址,再添加cookie,再打开网址
19.selenium截图
方法:bage._driver.get_screenshot_as_file(‘path’)
# 截取当前页面并保存为'./afdsg.png'文件
bage._driver.get_screenshot_as_file('./afdsg.png')
20.selenium断言方式
ui自动化中,我们一般通过以下方式来断言用例是否成功
(1)通过title
通过title标题来断言用例是否通过
方式1:driver.title----获取当前浏览器的标题,再对title做判定
方式2:expected_conditions.title_is(‘预期title’)—判断当前title是否等于预期title
import time
from selenium import webdriver
from selenium.webdriver.support import expected_conditions
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
time.sleep(5)
assert_title = expected_conditions.title_is('百度一下,你就知道') #返回一个object
print(assert_title(driver)) # 返回一个布尔值,如果当前title == '百度一下,你就知道',则返回True
driver.quit()
方式三:expected_conditions.title_contains(‘预期title部分内容’)—判断当前title是否包含预期title
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
time.sleep(5)
assert_title = expected_conditions.title_contains('百度一下') #返回一个object
print(assert_title(driver)) # 返回一个布尔值,如果当前title 包含 '百度一下',则返回True
driver.quit()
(2)通过文本
通过某个元素的文本内容来断言用例是否通过
方式1:element.text----来获取元素element的文本内容,再对文本进行判断
方式2:element.get_attribute(‘innerHTML’)—获取元素element的文本内容,再对文本进行判断
方式3:expected_conditions.text_to_be_present_in_element(locator,text)------ # locator参数是定位方法;text是期望值
用来判断查找的元素的text属性是否包含期望的字符串
driver = webdriver.Chrome()
driver.get('https://www.baidu.com/')
# element = driver.find_element_by_id('s-usersetting-top')
# print(element.text)
assert_text = expected_conditions.text_to_be_present_in_element((By.ID,'s-usersetting-top'),'设置') # 返回一个object对象
print(assert_text(driver)) # 返回一个布尔值,如果查找的元素text包含‘设置’,则返回true
time.sleep(5)
driver.quit()
(3)通过元素其他属性值来判断
方式1:element.get_attribute
我们可以使用element.get_attribute(‘属性名’)来获取元素的属性值,再通过对属性值进行判断,来决定用例是否通过
方式2:expected_conditions的一些常用方法来判断
- visibility_of_element_located : 判断某个元素是否可见. 可见代表元素非隐藏,并且元素的宽和高都不等于0.
- presence_of_all_elements_located : 判断是否至少有1个元素存在于dom树中。举个例子,如果页面上有n个元素的class都是’column-md-3’,那么只要有1个元素存在,这个方法就返回True
- frame_to_be_available_and_switch_to_it: 判断该frame是否可以switch进去,如果可以的话,返回True并且switch进去,否则返回False
- invisibility_of_element_located : 判断某个元素中是否不存在于dom树或不可见
- element_to_be_clickable : 判断某个元素中是否可见并且是enable的,这样的话才叫clickable
- staleness_of :等某个元素从dom树中移除,注意,这个方法也是返回True或False
- element_to_be_selected:判断某个元素是否被选中了,一般用在下拉列表
>* element_selection_state_to_be:判断某个元素的选中状态是否符合预期 - element_located_selection_state_to_be:跟上面的方法作用一样,只是上面的方法传入定位到的element,而这个方法传入locator
- alert_is_present : 判断页面上是否存在alert