安装
Playwright是专门为满足端到端测试的需求创建的。Playwright支持目前所有的渲染引擎,包括:Chromium、WebKit和Firefox。在Windows、Linux和macOS上都可以使用。也可以在移动端浏览器进行测试。
pip安装
pip install palywright
测试示例
下面是一个简单的测试脚本示例。
import re
from playwright.sync_api import Page, expect
def test_has_title(page: Page):
page.goto("https://playwright.dev/")
# Expect a title "to contain" a substring.
expect(page).to_have_title(re.compile("Playwright"))
def test_get_started_link(page: Page):
page.goto("https://playwright.dev/")
# Click the get started link.
page.get_by_role("link", name="Get started").click()
# Expects page to have a heading with the name of Installation.
expect(page.get_by_role("heading", name="Installation")).to_be_visible()
介绍
导航
打开被测URL
page.goto("https://playwright.dev/")
交互
执行交互操作,需要先定位元素。Playwright使用Locators API进行元素定位。
# 创建定位器
get_started = page.get_by_role("link", name="Get started")
# 执行点击操作
get_started.click()
基本交互指令
下面为基本的交互指令,还有很多其他指令。
指令 | 描述 |
---|---|
locator.check() | 选中复选框 |
locator.click() | 单击元素 |
locator.uncheck() | 取消选中复选框 |
locator.hover() | 将鼠标悬浮在元素上 |
locator.fill() | 填写表单字段,输入文本 |
locator.focus() | 聚焦元素 |
locator.press() | 按单键 |
locator.set_input_files() | 选择要上传的文件 |
locator.select_option() | 在下拉菜单中选择选项 |
断言
下面示例为等待元素断言,将等待页面获得包含“Playwright”的标题。
import re
from playwright.sync_api import expect
expect(page).to_have_title(re.compile("Playwright"))
常用的断言方式:
断言 | 描述 |
---|---|
expect(locator).to_be_attached() | 元素已加载 |
expect(locator).to_be_checked() | 复选框已选中 |
expect(locator).to_be_disabled() | 元素已禁用 |
expect(locator).to_be_editable() | 元素是可编辑的 |
expect(locator).to_be_empty() | 容器为空 |
expect(locator).to_be_enabled() | 元素已启用 |
expect(locator).to_be_focused() | 元素被聚集 |
expect(locator).to_be_hidden() | 元素不可见 |
expect(locator).to_be_in_viewport() | 元素与视口相交 |
expect(locator).to_be_visible() | 元素可见 |
expect(locator).to_contain_text() | 元素包含文本 |
expect(locator).to_have_accessible_description() | 元素具有匹配的可访问描述 |
expect(locator).to_have_accessible_name() | 元素具有匹配的可访问名称 |
expect(locator).to_have_attribute() | 元素具有DOM属性 |
expect(locator).to_have_class() | 元素具有class属性 |
expect(locator).to_have_count() | List具有精确的子项数量 |
expect(locator).to_have_css() | 元素具有css属性 |
expect(locator).to_have_id() | 元素有一个ID |
expect(locator).to_have_js_property() | 元素有一个JavaScript属性 |
expect(locator).to_have_role() | 元素具有特定的ARIA角色 |
expect(locator).to_have_text() | 元素与文本匹配 |
expect(locator).to_have_value() | 输入有一个值 |
expect(locator).to_have_values() | 已选择选项 |
expect(page).to_have_title() | 页面有一个标题 |
expect(page).to_have_url() | 页面有一个url |
expect(response).to_be_ok() | 响应的状态为ok |
交互操作介绍
Playwright所有的交互操作都是支持异步操作的,与同步操作的区别就是在操作代码前面加awati,例如
# 同步操作
page.get_by_role("link", name="Get started").click()
# 异步操作
await page.get_by_role("link", name="Get started").click()
- 同步模式:在同步模式下,代码按照从上到下的顺序执行。每个操作都会阻塞直到完成,然后再执行下一行代码。这意味着在等待某个操作(如页面加载)完成之前,程序不会继续往下执行。
- 异步模式:异步模式利用Python的asyncio库(或其他编程语言的异步机制),允许非阻塞的并发操作。这意味着在等待某个耗时操作(如网络请求)的同时,程序可以继续执行其他任务。你需要使用await关键字来等待异步操作的结果。
文本输入
使用locator.fill()是填写表单字段的最简单方法。它聚焦元素并使用输入的文本触发输入事件。它适用于、和[contenteditable]元素。
# 文本输入
page.get_by_role("textbox").fill("Peter")
# 日期输入
page.get_by_label("Birth date").fill("2020-02-02")
# 时间输入
page.get_by_label("Appointment time").fill("13:15")
# 本地时间输入
page.get_by_label("Local time").fill("2020-03-02T05:15")
复选框和单选按钮
使用locator.set_checked()是选中和取消选中复选框或单选按钮的最简单方法。此方法可以与input[type=checkbox]、input[type=radio]和[role=checkbox]element一起使用。
# 选中复选框
page.get_by_label('I agree to the terms above').check()
# 确定选中状态
expect(page.get_by_label('Subscribe to newsletter')).to_be_checked()
# 选中单选按钮
page.get_by_label('XL').check()
鼠标点击
# 单击
page.get_by_role("button").click()
# 双击
page.get_by_text("Item").dblclick()
# 右击
page.get_by_text("Item").click(button="right")
# Shift + 点击
page.get_by_text("Item").click(modifiers=["Shift"])
# 悬浮
page.get_by_text("Item").hover()
# 坐标点击
page.get_by_text("Item").click(position={ "x": 0, "y": 0})
# 强制点击
page.get_by_role("button").click(force=True)
键盘操作
# 回车
page.get_by_text("Submit").press("Enter")
# Ctrl + 方向键右
page.get_by_role("textbox").press("Control+ArrowRight")
# 键盘$符键
page.get_by_role("textbox").press("$")
上传文件
使用locator.set_input_files()方法选择要上传的输入文件。第一个参数指向类型为“file”的输入元素。数组中可以传递多个文件。如果某些文件路径是相对的,则它们将相对于当前工作目录进行解析。空数组清除所选文件。
# 上传一个文件
page.get_by_label("Upload file").set_input_files('myfile.pdf')
# 上传多个文件
page.get_by_label("Upload files").set_input_files(['file1.txt', 'file2.txt'])
# 上传文件夹
page.get_by_label("Upload directory").set_input_files('mydir')
# 删除所有选定文件
page.get_by_label("Upload file").set_input_files([])
# 从内存上传缓冲区
page.get_by_label("Upload file").set_input_files(
files=[
{"name": "test.txt", "mimeType": "text/plain", "buffer": b"this is a test"}
],
)
拖拽
使用locator.drag_to()执行拖放操作。此方法将:
将鼠标悬停在要拖动的元素上。
按下鼠标左键。
将鼠标移动到将接收拖放的元素上。
松开鼠标左键。
page.locator("#item-to-be-dragged").hover()
page.mouse.down()
page.locator("#item-to-drop-at").hover()
page.mouse.up()
滚动
Playwright在执行任何操作前都会自动滚动,因此不需要编写滚动代码。
# 如果按钮不可见,将自动滚动到可见后执行点击
page.get_by_role("button").click()
事件
介绍
Playwright允许监听网页上发生的各种类型的事件,如网络请求、创建子页面、专用工作人员等。订阅此类事件有几种方法,如等待事件或添加或删除事件监听器。
等待事件
大多数时候,脚本需要等待特定的事件发生。下面事一些典型的事件等待模式。
使用page.expect_request()等待具有指定url的请求:
with page.expect_request("**/*logo*.png") as first:
page.goto("https://wikipedia.org")
print(first.value.url)
等待弹窗窗口:
with page.expect_popup() as popup:
page.get_by_text("open the popup").click()
popup.value.goto("https://wikipedia.org")
添加/删除事件监听器
有时候事件发生在随机时间,而不是等待他们。Playwright支持添加和删除事件监听:
print_request_sent()和print_request_finished()为实现的监听方法。当page进行交互操作时,会对page进行监听。监听方法也可以传参。对于事件监听,是可以监听到前端页面的部分Ajax请求。
def print_request_sent(request):
print("Request sent: " + request.url)
def print_request_finished(request):
print("Request finished: " + request.url)
page.on("request", print_request_sent)
page.on("requestfinished", print_request_finished)
page.goto("https://wikipedia.org")
page.remove_listener("requestfinished", print_request_finished)
page.goto("https://www.openstreetmap.org/")
一次性监听器
page.once("dialog", lambda dialog: dialog.accept("2021"))
page.evaluate("prompt('Enter a number:')")
对于所有的事件和监听器,都支持异步方法。事件前面加async,监听器前面加await就是异步方法。例如:
async with page.expect_request("**/*logo*.png") as first:
await page.goto("https://wikipedia.org")
first_request = await first.value
print(first_request.url)
def print_request_sent(request):
print("Request sent: " + request.url)
def print_request_finished(request):
print("Request finished: " + request.url)
page.on("request", print_request_sent)
page.on("requestfinished", print_request_finished)
await page.goto("https://wikipedia.org")
page.remove_listener("requestfinished", print_request_finished)
await page.goto("https://www.openstreetmap.org/")
总结
Playwright是一个功能十分强大的框架,不仅可以进行UI自动化测试,还可以进行API测试和爬虫相关工作。
Playwright作为一个由微软开发的开源自动化测试工具,具有多个显著的优点,主要包括以下几个方面:
- 跨浏览器和跨平台支持
- Playwright支持所有现代渲染引擎,包括Chromium、WebKit和Firefox,因此可以兼容包括Chrome、Firefox、Safari等在内的主流浏览器。
- 它能在Windows、Linux和MacOS等多个操作系统上运行,提供广泛的平台支持。
- 多语言支持
- Playwright提供了统一的API,并支持多种编程语言,如TypeScript、JavaScript、Python、.NET和Java等。这使得开发人员能够使用他们熟悉的语言来编写自动化测试脚本,方便集成到现有项目中。
- 性能和效率
- Playwright专为速度和性能而设计,能够优化测试执行,实现更快、更高效的测试。
- 它支持本机并行测试执行,可以在多个浏览器和平台上同时运行测试,显著减少测试执行时间。
- 内置功能丰富
- Playwright具有内置的等待机制,可以自动等待页面加载、网络请求和元素可见性,减少了编写稳定测试时所需的手动等待时间。
- 它还提供了截图和视频记录功能,这对于调试测试失败的情况非常有用。
- 支持元素截图、模拟输入、拦截网络请求等多种高级功能。
- 易于使用和调试
- Playwright提供了简洁、直观的API,使得编写可靠、可扩展的浏览器自动化脚本变得非常容易。
- 它还提供了Playwright Inspector这样的GUI工具,可以帮助开发人员调试脚本,包括检查页面、生成选择器、逐步执行测试等。
- 代码生成和记录
- Playwright支持通过记录浏览器操作来生成测试代码,并支持将测试结果保存为多种语言,这大大提高了编写测试脚本的效率。
- 测试隔离和稳定性
- Playwright为每个测试创建一个独立的浏览器上下文,相当于一个全新的浏览器配置文件,提供了完全的测试隔离。
- 它的自动等待和丰富的内置事件相结合,消除了人为超时的可能性,从而提高了测试的稳定性。
- 社区和生态
- 尽管Playwright是一个相对较新的框架,但它已经获得了广泛的关注和使用,社区逐渐壮大。
- 微软的支持也保证了Playwright的长期维护和更新,使其能够持续适应Web技术的发展。
更多的内容可以访问官网查看:Playwright