selenium知识点
selenium截屏
- 截屏方式
1. save_screenshot
2. get_screenshot_as_file # 保存网页截图
3. get_screenshot_as_png #获取二进制数据流
4.get_screenshot_as_base64 # base64编码原始数据
- 全屏截屏:截屏的是可视区域
driver.save_screenshot('baidu1.png')
- 部分截屏:指定元素截屏
image=driver.find_element(By.XPATH,'//*[@id="app"]/div/div/div[2]/div[3]/div[2]/form/div[3]/div/div/div/div/img')
time.sleep(3)
# driver.save_screenshot('baidu1.png')
image.screenshot('b.png')
eg:识别验证码
第一步:将验证码进行截图
image=self.locator_element(LoginPage.pict)
time.sleep(1)
image.screenshot('a.png')
第二步:将验证码进行灰度化
yzm = cv2.imread('a.png')
yzm = np.min(yzm, axis=2).astype(np.uint8)
cv2.imwrite('a.png', yzm)
第三步:识别验证码(ddddocr技术)
file = 'a.png'
path = str(Path(file).absolute())
ocr = ddddocr.DdddOcr()
with open(path, 'rb') as f:
img_bytes = f.read()
res = ocr.classification(img_bytes)
print(res)
eg:
import time
from pathlib import Path
import numpy as np
import cv2
import ddddocr
from selenium.webdriver.common.by import By
from base.base_page import BasePage
class LoginPage(BasePage):
def __init__(self,driver):
super(LoginPage, self).__init__(driver)
login_username = (By.XPATH, '//*[@placeholder="请输入用户名"]')
login_password = (By.XPATH, '//*[@placeholder="请输入密码"]')
pict=(By.XPATH,'//*[@id="app"]/div/div/div[2]/div[3]/div[2]/form/div[3]/div/div/div/div/img')
# 验证码框
input_pict=(By.XPATH,'//*[@placeholder="请输入验证码"]')
# 点击登录按钮
click_login=(By.XPATH,'//*[text()="登 录"]')
def login(self, username, password,):
self.set_key(LoginPage.login_username, username)
self.set_key(LoginPage.login_password, password)
# 识别验证码
# 第一步:对验证进行截图
image=self.locator_element(LoginPage.pict)
time.sleep(1)
image.screenshot('a.png')
# 第二步:将验证码进行灰度化
yzm = cv2.imread('a.png')
yzm = np.min(yzm, axis=2).astype(np.uint8)
cv2.imwrite('a.png', yzm)
# 第三步:识别验证码
file = 'a.png'
path = str(Path(file).absolute())
ocr = ddddocr.DdddOcr()
with open(path, 'rb') as f:
img_bytes = f.read()
res = ocr.classification(img_bytes)
print(res)
# 第四步:填入验证码
self.set_key(LoginPage.input_pict,res)
time.sleep(10)
# 点击登录按钮
self.click(LoginPage.click_login)
time.sleep(10)
allure报告放入失败截图
利用pytest的钩子函数,在conftest.py文件进行编写
'''
钩子函数:它在测试用例执行完毕并生成测试报告时触发,可以在此处对测试结果进行处理,
通过实现该钩子函数来对测试报告进行定制化的处理,例如记录测试用例的执行结果、截图
'''
'''
@pytest.hookimpl(hookwrapper=True, tryfirst=True):该插件作用于pytest的钩子函数上,
可以获取到测试用例不同执行阶段的结果(setup,call,teardown)
'''
@pytest.hookimpl(hookwrapper=True, tryfirst=True)
def pytest_runtest_makereport(item, call):
'''
每个测试用例执行后,制作测试报告
:param item:测试用例对象
:param call:测试用例的测试步骤
先执行when=’setup’ 返回setup 的执行结果
然后执行when=’call’ 返回call 的执行结果
最后执行when=’teardown’返回teardown 的执行结果
:return:
'''
# 获取钩子方法的调用结果,返回一个result对象
out = yield
# 获取调用结果的测试报告,返回一个report对象, reportd对象的属性包括when(steup, call, teardown三个值)、
# nodeid(测试用例的名字)、outcome(用例的执行结果,passed, failed)
report = out.get_result()
# 通过判断,测试用例失败,则进行截图
# print(report)
if report.when == "call" and report.failed:
mode = "a" if os.path.exists("failures") else "w"
with open("failures", mode) as f:
if "tmpir" in item.fixturenames:
extra = " (%s)" % item.funcargs["tmpdir"]
else:
extra = ""
f.write(report.nodeid + extra + "\n")
with allure.step('添加失败截图...'):
allure.attach(driver.get_screenshot_as_png(), "失败截图", allure.attachment_type.PNG)
selenium三种等待方式
注意:执行 sleep()后线程休眠,而另外两种线程不休眠
1.强制等待--sleep()
import time
time.sleep(1)
2.隐式等待--implicitly_wait(最大等待时长)
原理:隐式等待,就是在创建driver时,为浏览器对象创建一个等待时间,这个方法是得不到某个元素就等待一段时间,直到拿到某个元素位置。注意:在使用隐式等待的时候,实际上浏览器会在你自己设定的时间内不断的刷新页面去寻找我们需要的元素 他是全局等待。
缺点:隐式等待对于有些条件无法生效,比如url的改变,窗口的延迟新增,动态属性延迟加载……
implicitly_wait(10)//隐式等待10s,10s内查到定位,则继续,否则抛出异常
3.显示等待--WebDriverWait()
显示等待是Selenium客户可以使用的命令式过程语言。主要思想是最长等待n秒,n秒内每隔一段时间去检查需要定位的元素是否存在(默认检测频率为0.5s),若存在则提前结束等待。若超时未找到则报错。默认抛出异常为:NoSuchElementException。这种等待比隐性等待更智能了一些,无视整个页面的加载,只要需要的元素存在了,就结束等待。显示等待不仅针对元素定位有效,而且可以针对某种行为(url的改变,属性的延迟加载)看它是否具备了一定的特征,就开始有所动作了。
from selenium.webdriver.support.wait import WebDriverWait
WebDriverWait(driver,timeout,poll_frequency=0.5,ignored_exceptions=None)
#driver:浏览器驱动
#timeout:最长等待时间,默认以秒为单位
#poll_frequency:监测的时间间隔,默认为0.5秒
#ignored_exceptions:超时后的异常信息,默认情况下抛NoSuchElementException异常
#WebDriverWait一般有until和until_not方法配合使用
until(method,message='')
# 调用该方法提供的驱动程序作为一个参数,直到返回值为True。
until_not(method,message = '')
# 调用该方法提供的驱动程序作为一个参数,直到返回值为False。
#expected_conditions类提供的预期条件判断的方法
title_is #判断当前页面的标题是否等于预期
title_contains #判断当前页面的标题是否包含预期字符串
presence_of_element_located #判断元素是否被加在DOM树里,并不代表该元素一定可见
visibility_of_element_located #判断元素是否可见(可见代表元素非隐藏,并且元素的宽和高都不等于0)
visibility_of # 与上一个方法作用相同,只是上一个方法参数为定位,该方法接收的参数为定位后的元素
presence_of_all_elements_located #判断是否至少有一个元素存在于DOM树中。例如,在个页面中有n个元素的class为"wp",那么只要有一个存在就返回true
text_to_be_present_in_clement #判断某个元素中的text是否包含了预期的字符串
text_to_be_present_in_element_value #判断某个元素的value属性是否包含了预期的字符串
frame_to_be_available_and_switch_to_it #判断该表单是否可以切换进去,如果可以,返回True并且switch进去,否则返回false
invisibility_of_element_located #判断某个元素是否不存在于DOM树或不可见
element_to_be_clickable #判断元素是否可见并且是可以点击的
staleness_of #等到一个元素从DOM树中移除
element_to_be_selecte #判断某个元素是被选中,一般用在下拉列表
element_sclection_state_to_be #判断某个元素的选中状态是否符合预期
element_located_selection_state_to_be #与上一个方法作用相同,只是-上一个方法参数为定位后的元素,该方法要收的参数为定位
alert_is_presen #判断页面上是否存在alert
一般用时显示等待+隐式等待一起用:隐式等待作用于全局,确保每一个你查找的元素都能够有足够的load时长,以便找到它使脚本正常运行。显示等待作用于你当前使用函数查找的这个元素,确保它快速高效的找到,显示等待不会管其他你要查找的元素的。
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
self.driver.implicitly_wait(60)
WebDriverWait(self.driver,50,poll_frequency=0.5).until(EC.presence_of_element_located(self.click_project))
self.click(self.click_project)
模拟鼠标进行点击
模拟鼠标要用selenium的ActionChains类进行实现
1.ActionChains方法
perform(self)–执行鼠标操作方法
reset_actions()–清楚操作子令
click(on_element=None)–点击鼠标左键
click_and_hold(on_element=None):点击鼠标左键,不松开
context_click(on_element=None):点击鼠标右键
double_click(on_element=None):双击鼠标左键
drag_and_drop(source, target):拖拽到某个元素然后松开
drag_and_drop_by_offset(source, xoffset, yoffset) :拖拽到某个坐标然后松开
key_down(value, element=None):按下某个键盘上的
key_up(value, element=None) :松开某个
move_by_offset(xoffset, yoffset):鼠标从当前位置移动到某个坐标
move_to_element(to_element) :鼠标移动到某个元素
move_to_element_with_offset(to_element, xoffset, yoffset):移动到
距某个元素(左上角坐标)多少距离的位置
pause(seconds):暂停操作(秒)
release(on_element=None):在元素上释放按住的鼠标按钮
send_keys(*keys_to_send):发送某个键到当前焦点的元素
send_keys_to_element(element, *keys_to_send) :发送某个键到指定元素
2.ActionChains使用步骤
#1.实例化:actions = ActionChains(driver)
#2.调用鼠标操作方法:actions.move_to_element(menu)
#3.执行鼠标操作方法:actions.perform()
def click_mouse(self,loc):
close = self.locator_element(loc)
actions = ActionChains(self.driver)
actions.move_to_element(close).click().perform()
日志
- 日志级别:NOTSET<DEBUG < INFO < WARNING < ERROR < CRITICAL
format日志格式
%(levelno)s: 打印日志级别的数值
%(levelname)s: 打印日志级别名称
%(pathname)s: 打印当前执行程序的路径,其实就是sys.argv[0]
%(filename)s: 打印当前执行程序名
%(funcName)s: 打印日志的当前函数
%(module)s 调用日志输出函数的模块名
%(name)s : 所使用的日志名称,默认是'root',因为默认使用的是 rootLogger
%(msecs)d 日志事件发生事件的毫秒部分
%(lineno)d: 打印日志的当前行号
%(asctime)s 字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(relativeCreated)d 输出日志信息时的,自Logger创建以 来的毫秒数
%(relativeCreated)d 日志事件发生的时间相对于logging模块加载时间的相对毫秒数(目前还不知道干嘛用的)
%(thread)d: 打印线程ID
%(threadName)s: 打印线程名称
%(process)d: 打印进程ID
%(message)s: 打印日志信息
一般日志会配置在pytest.ini文件里
日志可用在控制台或者文件中进行打印
1.控制台中打印
log_cli = true
log_cli_level=DEBUG
log_cli_format= %(asctime)s %(levelname)s %(message)s
log_cli_date_format = %Y-%m-%d %H:%M:%S
'''
log_cli:表示开启控制台日志,默认是关闭的
log_cli_level:日志等级
log_cli_format:日志格式
log_cli_date_format:日志的时间格式
'''
2.日志要写在pytest.ini文件里,日志写入文件里
log_cli = 0
log_file = ./logs/test.log
log_file_level = info
log_file_format = %(levelname)-8s %(asctime)s [%(name)s:%(lineno)s] : %(message)s
log_file_date_format = %Y-%m-%d %H:%M:%S
'''
log_cli = 0 控制台实时输出日志 log_cli=True 或 log_cli=False(默认),或者 log_cli=1 或 log_cli=0
log_file = logs/pytest-logs.txt,将实时日志写入文件中
log_file_level = INFO,写入文件的日志级别
log_file_date_format = %Y-%m-%d %H:%M:%S,写入文件的日期格式
log_file_format = %(asctime)s %(levelname)s %(message)s,写入文件的日志消息格式
'''
selenium无法定位解决方法
方法一:增加睡眠时间(利用三种等待方法)
方法二:模拟鼠标进行点击(Actionchains方法)
方法三:执行JS脚本
element = driver.find_element(by, locator)
#arguments[0]代表所传值element的第一个参数
#click()代表js中的点击动作
driver.execute_script("arguments[0].click();",element)
弹出框
alert()
alert 是一个警告框,表现为直接弹出一个提示窗,该提示窗只有一个按钮确定按钮,点击 确定 按钮后无返回值
confirm()
confirm` 是确认框,它有两个按钮,确定 与 取消 ,返回 `true` 或 `false,如果用户点击确认,那么返回值为 true。如果用户点击取消,那么返回值为 false。 语法:confirm("文本")
cprompt()
prompt` 是提示框,它会返回输入框输入的消息,或者其默认值;提示框经常用于提示用户在进入页面前输入某个值。当提示框出现后,用户需要输入某个值,然后点击确认或取消按钮才能继续操纵。如果用户点击确认,那么返回值为输入的值。如果用户点击取消,那么返回值为 null。语法:`prompt("文本","默认值")
selenium 处理弹出对话框的常用方法
常用方法如下:
- text:返回
alert、confirm、prompt
里面的文字信息 - accept:接受
- dismiss:取消
- send_keys:向
prompt
里面输入文字