playwright
项目地址:https://github.com/microsoft/playwright-python
官方文档:https://playwright.dev/python/docs/intro
安装
系统要求
Python 3.8+
Windows 10+ or MacOS 12+ or Ubuntu 20.04+
pip install pytest-playwright
playwright install
如果版本过低,可升级python,需要3.8+
国内镜像下载地址 https://repo.huaweicloud.com/python/3.12.1/python-3.12.1-amd64.exe
使用
录制测试脚本
会启动一个 Chromium 浏览器,操作完成之后点击红色按钮结束录制即可。
playwright codegen https://xxx.net/login
编写测试脚本
from playwright.sync_api import Playwright, sync_playwright, expect
import requests
import json
def run(playwright: Playwright) -> None:
browser = playwright.chromium.launch(headless=False)
context = browser.new_context()
page = context.new_page()
page.goto("https://xxx.net/login")
page.get_by_placeholder("请输入账号/手机号").click()
page.get_by_placeholder("请输入账号/手机号").fill("xxx")
page.get_by_placeholder("请输入账号/手机号").press("Tab")
page.get_by_placeholder("请输入密码").fill("xxx")
page.get_by_role("button", name="登录").click()
# 此处手动登录,然后到个人信息页再获取cookie
page.wait_for_timeout(3000)
cookies = context.cookies()
print(page.title(), end='\n')
f = open('cookies.txt', 'w')
json.dump(cookies, f)
print('已获取cookies', end='\n')
user_token = None
zujuan_core = None
for cookie in cookies:
print(cookie)
if cookie['name'] == 'user_token':
user_token = cookie['value']
elif cookie['name'] == 'zujuan-core':
zujuan_core = cookie['value']
print(user_token, end='\n')
print(zujuan_core, end='\n')
update_cookie_url = 'http://xxx/json_api';
update_cookie_json_data = {'user_token': user_token, 'zujuan_core': zujuan_core}
response = requests.post(url=update_cookie_url, json=update_cookie_json_data)
f2 = open('response.txt', 'wb')
#byte格式
f2.write(response.content)
print('已获取response')
page.wait_for_timeout(2000)
# ---------------------
context.close()
browser.close()
with sync_playwright() as playwright:
run(playwright)
运行测试脚本
cd /Users/sherlock/dev/playwright
pytest test_example.py
debug 脚本
PWDEBUG=1 pytest -s test_example.py
可以打断点配合 debug
page.pause()
批处理调用
@echo off
cd C:\spider\playwright
echo test_xkw
pytest test_xkw.py
echo finish
如果是java调用,还需要指定具体路径
@echo off
cd C:\spider\playwright
echo test_xkw
C:\Users\Administrator\AppData\Local\Programs\Python\Python312\Scripts\pytest C:\spider\playwright\test_xkw.py
echo finish
选择器
page.get_by_placeholder("请输入密码").fill("000000ab")
page.get_by_role("button", name="登录").click()
#按文本内容搜索
hasNickname = page.get_by_text('伊春测试一中').count() > 0
#如果已登录状态,只需要前面刷新完页面即可
if not hasNickname:
page.get_by_role("button", name="登录").click()
#...
css选择器文档:https://playwright.dev/python/docs/locators#locate-by-css-or-xpath
复杂的并不推荐使用
示例:
#定位元素并获取文本内容
content = page.locator('div.unusual').inner_html()
# 发送企微 whbhool
webhook_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"
json_data = {"msgtype": "text", "text": {"content" : "xxx:" + content }}
requests.post(url=webhook_url, json=json_data)
截图
#整个页面截图
page.screenshot(path="example2.png")
#指定选择器截图
page.locator(".s-canvas").screenshot(path="example.png")
保存浏览器状态(会话之类的)
在编写UI自动化测试用例的时候,通常会采用每个测试用例前打开新页面重新进行登录,以减少用例间的影响,但是这种方式会使得测试用例的执行时间大幅度上升。
如果可以将登录状态保持住,开始测试用例的时候打开新页面,跳过登录直接进入到待测系统中,就可以大幅度提高测试执行效率。
from playwright.sync_api import Playwright, sync_playwright, expect
import requests
import os
def run(playwright: Playwright) -> None:
ss_file = 'login_data.json'
browser = playwright.chromium.launch(headless=False)
# 判断是否存在状态文件,有的话就加载
if os.path.isfile(ss_file):
context = browser.new_context(storage_state=ss_file)
else:
context = browser.new_context()
#context = browser.new_context()
page = context.new_page()
page.goto("https://xxx.com/login")
# 通过title判断是否成功进入系统,如果没有需要进行登录,一般在第一次访问系统,或登录信息过期等原因会触发
if '工时' not in page.title():
page.get_by_placeholder("请输入账号/手机号").click()
page.get_by_placeholder("请输入账号/手机号").fill("xxx")
page.get_by_placeholder("请输入账号/手机号").press("Tab")
page.get_by_placeholder("请输入密码").fill("xxx")
page.get_by_placeholder("请输入密码").press("Tab")
page.get_by_role("button", name="登录").click()
# 保存状态文件
storage = context.storage_state(path=ss_file)
page.wait_for_timeout(1000)
page.get_by_role("link").nth(1).click()
#定位元素并获取文本内容
content = page.locator('div.unusual').inner_html()
webhook_url = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx"
json_data = {"msgtype": "text", "text": {"content" : "xxx:" + content }}
requests.post(url=webhook_url, json=json_data)
page.wait_for_timeout(1000)
# ---------------------
context.close()
browser.close()
with sync_playwright() as playwright:
run(playwright)
指定外部浏览器
官方文档:https://playwright.dev/docs/api/class-browsertype#browser-type-connect-over-cdp
一般是使用chrome浏览器的debug模式来实现,首先需要以debug模式启动:
chrome.exe --remote-debugging-port=12345 -–start-maximized
mac下启动命令为:
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222
常见可用参数:
-–incognito
:隐私模式打开这里笔者主要就是想使用真实的浏览器,就不加了
-–start-maximized
:窗口最大化--user-data-dir
:设置用户目录这里需要单独指定一个文件夹目录,不存在会新建,如果不显式指定该参数,运行会污染浏览器默认的配置文件;
笔者这里使用了一个新的浏览器,就不加了--new-window
:直接打开网址可以不设置,打开空白标签页
修改py脚本
from playwright.sync_api import Playwright, sync_playwright, expect
import requests
import json
def run(playwright: Playwright) -> None:
#browser = playwright.chromium.launch(headless=False)
#context = browser.new_context()
#page = context.new_page()
## 使用debug模式连接主机的chrome
chromium = playwright.chromium
browser = chromium.connect_over_cdp('http://localhost:12345')
context = browser.contexts[0]
#page = context.pages[0]
page = context.new_page()
page.goto("https://www.baidu.com")
#。。。。省略
# ---------------------
## 使用后一般不关闭窗口了,因为就是要模拟真实浏览器的效果
#context.close()
#browser.close()
with sync_playwright() as playwright:
run(playwright)
还可以参考:
https://blog.csdn.net/lilongsy/article/details/130560129
https://zhuanlan.zhihu.com/p/573640396
评论区