浏览器驱动安装
# 控制台安装
pip install playwright
# 如果没有自动安装浏览器驱动或者驱动报错
playwright install chromium
# 一键录制
playwright codegen
playwright助手录制
python输入以下代码贴入要前往的链接,左边进行页面元素的操作,右边会自动生成录制代码,简单生成一个网易邮箱登录的自动化代码
playwright codegen
from playwright.sync_api import Playwright, sync_playwright, expect
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
page = context.new_page()
page.goto("https://email.163.com/")
page.frame_locator("[id=\"x-URS-iframe1716884031823\\.234\"]").get_by_placeholder("邮箱账号或手机号码").click()
page.frame_locator("[id=\"x-URS-iframe1716884031823\\.234\"]").get_by_placeholder("邮箱账号或手机号码").fill("xxx你的邮箱xxx")
page.frame_locator("[id=\"x-URS-iframe1716884031823\\.234\"]").locator("#auto-id-1716884032354").click()
page.frame_locator("[id=\"x-URS-iframe1716884031823\\.234\"]").locator("#auto-id-1716884032354").fill("xx你的密码xxx")
page.frame_locator("[id=\"x-URS-iframe1716884031823\\.234\"]").get_by_role("link", name="登 录").click()
# ---------------------
context.close()
browser.close()
with sync_playwright() as playwright:
run(playwright)
playwright的一些页面操作
#界面等待
page.wait_for_timeout(1000)
#获取元素文本内容
#获取元素内部文本
token1 = page.get_by_text("token").inner_text()
#可以获取元素隐藏文本
token2 = page.get_by_text("token").text_content()
#定位到多个元素时可以使用,返回多个元素的文本
token3 = page.get_by_text("token").all_text_contents()
#元素点击
click 单击
dbclick 双击
#元素可见判断
# 等待元素可见
page.get_by_role("button", name="跳 转").wait_for()
# 判断元素可见
page.get_by_role("button", name="跳 转").is_visible()
#输入框操作
#定位元素后输入
page.frame_locator("iframe").get_by_placeholder("输入手机号码").fill("13111110010")
#清空输入框内容
page.frame_locator("iframe").get_by_placeholder("输入手机号码").clear()
# 获取输入框内容
page.frame_locator("iframe").get_by_placeholder("输入手机号码").input_value()
#文件上传
# 先定位
lc = page.locator('input[type=file]')
# 单选一个文件
lc.set_input_files('d:/1.png')
# 或者 多选 文件
lc.set_input_files(['d:/1.png', 'd:/2.jpg'])
#页面操作
#打开网页
page.goto("xxxx")
#刷新页面
page.reload()
#页面前进
page.go_back()
#页面后退
page.go_forward()
#获取网页html
html = page.content()
#获取页面title
title = page.title()
#设置页面大小
page.set_viewport_size({"width": 640, "height": 480})
#截图
page.screenshot(path='transfer.png')部分截图不可见不截图
page.screenshot(path='ifame.png', full_page=True)全屏截图
#元素拖拽
drag_and_drop
断言方法
excep断言
assert断言
POM模式下的思路
核心思想:方法封装,将一些有共性的或者多次使用的代码提取到一个方法中,供其他地方调用,用最少的代码实现最多的功能,能够减少代码冗余,隐藏代码实现细节并且容易维护。
核心思路
pup待解决的问题:如何用例复用到pup的多个主体
解决方案:通过yaml管理多个主体的测试数据,使用pytest的parametrize驱动管理
Base:封装基础浏览器元素操作(点击、输入...)、浏览器操作(前进、后退、刷新...)、html(title、url..)等方法,统一放入base.browser_manage
Data:yaml数据驱动,使用pytest.mark.parametrize驱动时维护多个主体case的断言url参数等等内容
Page:__init__维护元素,通过不同的page维护页面操作封装
testcase:通过cese名称与用例表格关联,维护单个用例
Tools:可复用方法封装,文件读取,url解析,token解析.....
框架:pytest+playwright+allure
用例:PUP用例
项目管理
1、封装playwright关键字
对点击,切换选择框,获取/输入一些键盘鼠标常用的方法内容进行封装一层,并写入自定义日志,对后续allure报告自动管理日志定位错误的用例和执行失败的情况提供定位能力
class BrowserManager:
def __init__(self):
self.playwright = sync_playwright().start()
self.browser = self.playwright.chromium.launch(headless=False)
self.page = self.browser.new_page()
self.current_frame = self.page
self.default_frame = self.page
# url跳转
def goto(self, url):
self.page.goto(url)
log.info(f"goto to {url}")
# 点击元素
def click(self, selector):
self.page.click(selector)
log.info(f"Clicked on element with selector {selector}")
# 输入文本信息
def fill_text(self, selector, text):
self.page.fill(selector, text)
log.info(f"Typed text '{text}' into element with selector {selector}")
# 获取元素文本信息
def get_text(self, selector):
text = self.page.text_content(selector)
log.info(f"Retrieved text '{text}' from element with selector {selector}")
return text
2、数据驱动
yaml文件管理登录相关的测试数据包括要访问的连接,账号信息,用例标题相关内容,执行用例前需先进行yaml文件的预加载处理
- lilith_config:
title: lilith国际_邮箱密码登录
url: "你的测试地址"
user: a16216316416516@163.com
password: qwqw1212
farlight_config:
title: pup_farlight_邮箱密码登录
url: "你的测试地址"
user: a16216316416516@163.com
password: qwqw1212
tw_config:
title: pup台湾_邮箱密码登录
url: "你的测试地址"
user: a16216316416516@163.com
password: qwqw1212
vn_config:
title: pup越南_邮箱密码登录
url: "你的测试地址"
user: a16216316416516@163.com
password: qwqw1212
3、页面元素
统一在page目录的__init__下管理元素,使用时候导入page目录,传入对应的keywords,加上定位方法即可
# PUP页面元素汇总
# PUP中转页
pup_transfer = ".ant-btn"
pup_inner = ".ant-segmented-item >> nth=0"
pup_redirect = ".ant-segmented-item >> nth=1"
# PUP登录_通用
pup_login_iframe = "//*[@id='root']/iframe"
pup_pwd_login = "#rc-tabs-0-tab-P"
# pup登录_验证码登录
pup_login_username = ".ant-input >> nth=0"
pup_login_click_code = ".ant-btn-link"
pup_login_input_code = "input[placeholder='输入验证码']"
pup_login_code_agree0 = ".radioIcon___JMO75 >> nth=0"
pup_login_code_agree1 = ".radioIcon___JMO75 >> nth=1"
pup_login_button = ".submit___KDWyq"
4、验证码登录用例
log =GetLogger.get_logger()
data = read_yaml_file("./data/pup_code_login.yaml")
params = []
for config_dict in data:
for config_name,config_value in config_dict.items():
params.append(tuple(config_value.values()))
@pytest.mark.parametrize('title,url,iframe_user,redict_user,code',params)
def test_pup_redict_code_login(title,url,iframe_user,redict_user,code):
try:
log.info(f"正在执行{title}")
allure.dynamic.title(f"重定向验证码登录_{title}")
pup_page = BrowserManager()
pup_page.goto(url)
# 重定向
pup_page.click(page.pup_redirect)
pup_page.click(page.pup_transfer)
# 输入账号信息
pup_page.fill_text(page.pup_login_username, str(redict_user))
pup_page.click(page.pup_login_click_code)
# 等待发送验证码(国际延迟较高)
pup_page.wait(5000)
pup_page.fill_text(page.pup_login_input_code, str(code))
pup_page.click(page.pup_login_code_agree1)
# 点击登录按钮
pup_page.click(page.pup_login_button)
pup_page.wait(2000)
# 获取断言URL
url = pup_page.get_url()
log.info(f"登录成功获取的url{url}")
jwt_token = decode_jwt_token(extract_url(url))
account = jwt_token["account"]
log.info(f"解析jwt_token成功获取的acoount为{account}")
# 断言URL登录用户信息
assert account == str(redict_user)
finally:
pup_page.close()
5、结果产出allure报告
问题解决
1、已经安装了playwright之后驱动报错
# 仅下载 Chromium
playwright install chromium
# 仅下载 Firefox
playwright install firefox
# 仅下载 WebKit
playwright install webkit
评论区