playwright 的Browser、Context、Page和对比
深入理解Browser、Context、Page,可以让我们轻松掌握Playwright的工作原理,并从容应对问题如:如何处理对话框?如何复用登录身份信息?录制调整视频大小或者存储目录?
1. 概念
在Playwright中,Browser, Context, 和 Page 是核心概念,它们共同定义了自动化测试的结构。
测试会在浏览器(Browser)的上下文(BrowserContext)中执行,每个上下文包含多个页面(Page)。每个页面都代表了一个打开的浏览器标签页。这种层级结构允许你在同一个浏览器实例中同时执行多个测试用例,以提高效率。
Browser
-
• Browser 对应于一个完整的浏览器实例,比如
Chrome、Firefox或WebKit。 -
•
Playwright脚本通常从启动一个Browser实例开始,并在测试结束时关闭它。 -
•
Browser可以在无头(headless)或有头(headful)模式下启动。
const { chromium } = require('playwright');
// 无头模式启动浏览器
async function launchInHeadlessMode() {
const browser = await chromium.launch({ headless: true });
console.log('浏览器已在无头模式下启动');
// 执行其他操作...
await browser.close();
}
// 有头模式启动浏览器
async function launchInHeadfulMode() {
const browser = await chromium.launch({ headless: false });
console.log('浏览器已在有头模式下启动');
// 执行其他操作...
await browser.close();
}
// 分别调用无头模式和有头模式启动浏览器的函数
launchInHeadlessMode();
launchInHeadfulMode();
-
• 一个
Browser实例可以包含多个BrowserContext。BrowserContext代表了浏览器的一个隔离环境,其中包含了一组浏览器窗口(Page)、cookies、缓存、本地存储等。使用多个BrowserContext可以帮助模拟不同用户的会话,或者隔离测试环境以避免相互干扰。
BrowserContext
-
•
BrowserContext代表了一个浏览器的会话,它类似于一个全新的浏览器配置文件。 -
•
Playwright为每个测试用例创建一个BrowserContext,以确保测试之间的隔离。 -
• 每个
BrowserContext拥有自己的Cookie、浏览器存储和浏览历史记录。 -
• 可以在同一个
Browser实例中创建多个BrowserContext来模拟多用户会话。
示例代码:
const { chromium } = require('playwright');
async function main() {
// 启动一个浏览器实例
const browser = await chromium.launch();
// 创建第一个 BrowserContext
let context1 = await browser.newContext();
let page1 = await context1.newPage();
await page1.goto('https://example.com');
console.log('在第一个上下文中打开网页');
// 创建第二个 BrowserContext
let context2 = await browser.newContext();
let page2 = await context2.newPage();
await page2.goto('https://example.com');
console.log('在第二个上下文中打开网页');
// ... 在这里可以继续创建更多的 BrowserContext 和 Page,并进行相应的操作
// 关闭所有打开的 BrowserContext
await context1.close();
await context2.close();
// 关闭浏览器实例
await browser.close();
}
说明如下:
-
• 启动了一个
Browser实例,然后创建了两个BrowserContext实例。 -
• 每个
BrowserContext实例都打开了相同的网页,但由于它们是隔离的,因此它们各自的状态(例如cookies、localStorage)不会相互影响。 -
• 关闭了这两个
BrowserContext以及最初的Browser实例
Page
-
•
Page是在BrowserContext中打开的单个网页。 -
• 每个
Page代表了用户与浏览器交互时看到的视图。 -
•
Page提供了丰富的API用于导航、操作元素、处理表单、弹出窗口等。 -
• 在同一个
BrowserContext中可以打开多个Page实例。
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext();
// 打开第一个页面
const page1 = await context.newPage();
await page1.goto('https://example.com');
console.log(await page1.title());
// 打开第二个页面
const page2 = await context.newPage();
await page2.goto('https://example.org');
console.log(await page2.title());
// 关闭浏览器
await browser.close();
})();
说明如下:
-
• 使用
browser.newContext()创建了一个新的浏览器上下文。 -
• 通过
context.newPage()分别创建了两个新的页面实例,即page1和page2,每个页面可以独立进行导航和操作
三者关系图

Browser
|--- BrowserContext
|--- Page
|--- Page
|--- ...
2.典型场景
复用登录身份信息
-
• 使用同一
BrowserContext打开多个Page可以共享相同的Cookie,从而复用登录状态。 -
• 使用
context的storageState方法来实现 -
• 保存当前上下文的状态,包括登录信息,并在创建新页面时进行恢复
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext();
// 在第一个页面登录
const page1 = await context.newPage();
await page1.goto('https://example.com/login');
await page1.fill('input[name=username]', 'your_username');
await page1.fill('input[name=password]', 'your_password');
await page1.click('button[type=submit]');
// 保存上下文状态
const storageState = await context.storageState();
// 在新页面中恢复登录状态
const page2 = await context.newPage();
await page2.goto('https://example.com/dashboard', { waitUntil: 'domcontentloaded' });
// 具体的测试逻辑
await context.close();
await browser.close();
})();
操作对话框
当 Page 触发弹出对话框时,可以使用 Page 的相关 API 来定位和操作对话框元素。
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext();
const page = await context.newPage();
// 监听 'dialog' 事件
page.on('dialog', async (dialog) => {
console.log('Dialog message:', dialog.message());
// 模拟输入值并点击确定按钮
await dialog.type('Your input');
await dialog.accept();
});
// 触发一个包含 Prompt 对话框的操作,例如点击一个按钮
await page.goto('https://example.com');
await page.click('button');
// 关闭浏览器
await browser.close();
})();
说明如下:
-
• 使用
page.on()监听对话框事件 -
• 通过
dialog.type('Your input')模拟输入文本,并使用dialog.accept()确认对话框
视频录制
通过 Browser 的 browserContext.newPage() 打开 Page 后,可以使用 Browser 的录制功能来保存整个浏览器会话的视频。
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
const context = await browser.newContext({
viewport: { width: 1920, height: 1080 }, // 设置视口大小为 1920x1080
recordVideo: { dir: './videos/' } // 设置视频存储路径为当前目录下的 videos 文件夹
});
const page = await context.newPage();
// 打开页面并进行一些操作
await page.goto('https://example.com');
// 进行其他操作...
// 关闭浏览器
await browser.close();
})();
说明如下:
-
•
chromium.launch()启动了Chromium浏览器实例 -
• 使用
browser.newContext()创建了一个新的浏览器上下文,并设置了视口大小为1920x1080,同时开启了视频录制并设置了存储路径为当前目录下的videos文件夹。 -
• 使用
context.newPage()创建了一个新的页面。 -
• 可以在页面上执行各种操作,最后关闭了浏览器。
小结
深入理解这些概念和它们的关系是理解和有效使用 Playwright 进行自动化测试的基础。通过合理地管理 Browser,Context,和 Page,可以编写出高效、可维护且稳定的自动化测试脚本。
深入比较:Playwright、Cypress、Selenium三款自动化测试框架
自动化测试是软件开发过程中至关重要的一环,而选择适当的测试框架是成功实施自动化测试的关键。本文深入对比3个流行的自动化测试框架:
Playwright、Cypress 和Selenium,从多个维度进行对比并给出评分,以帮助开发者更好地选择适合其项目需求的工具。
1. 市场趋势

选取了npm下载次数和github上star数字对比三款工具表现: npm downloads和github stats说明:
-
•
cypress和playwright分别占据12名位置,在3月初每周下载量分别有550w+和450w+下载次数 -
•
playwright作为第2名在过去增长很快,尤其在过去1年 -
•
github stars看,playwright排在第一超过6w+,而cypress排在第2有4.5w+
2. 技术架构
Playwright

-
• 基于
Websocket通讯,建立与服务器连接,所有命令基于该连接
Cypress

-
• 基于
浏览器内,命令无需网络传输
Selenium

-
• 基于
http requests,在Selenium WebDriver和web browsers之间通讯 -
•
Selenium实际上包含一组工具,基于录制回放的Selenium IDE、支持并行执行的Selenium Grid,还有核心的Selenium WebDriver,以及由此演化而来的Selenium2、Selenium3、Selenium4是下面重点要比较的内容
3. 兼容性
Playwright: 9/10
-
• 支持多种浏览器,包括
Chromium、Firefox和WebKit。 -
• 提供对不同浏览器的无缝支持,可在同一测试用例中执行多个浏览器的测试。
Cypress: 7/10
-
• 主要支持
Chromium和Electron,对于其他浏览器的支持较少。 -
• 在 Firefox 和 Microsoft Edge 上的支持相对较新。
Selenium: 8/10
-
• 多浏览器支持,但有时需要特定的驱动程序。
-
• 一些浏览器可能不支持所有功能。
4. 执行速度
Playwright: 9/10
-
• 采用先进的技术,如
无头模式和并发执行,并行执行多个浏览器实例,加速测试过程。
Cypress: 8/10
-
• 专注于单页面应用
(SPA),因此在执行速度上相对较快。 -
• 但在大型应用或多页面测试中,性能可能有所下降。
Selenium: 7/10
-
•
Selenium Grid可以实现并发执行。 -
• 慢于
Playwright,尤其是在远程操作执行时。
5. 易用性
Playwright: 8/10
-
• 提供丰富的
API和文档,学习曲线相对较低,尤其是有经验的开发者。 -
• 相对于
Selenium,更容易设置和运行。 -
•
Playwright提供了强大而灵活的元素定位和断言机制,支持多种策略,包括文本、属性和角色。 -
•
Playwright提供了强大的调试工具,可以直接在浏览器中调试测试用例。
Cypress: 9/10
-
• 专注于简化测试流程,易于上手。
-
• 提供直观的命令式
API。 -
•
Cypress的元素定位和断言相对简单,通过类名和属性等辅助定位. -
•
Cypress的调试工具非常直观,可以在测试运行过程中实时查看。
Selenium: 7/10
-
• 学习曲线较陡峭,特别是对于初学者。
-
• 多语言支持,但某些语言的库可能不如其他语言成熟。
-
•
Selenium的元素定位相对传统,通过XPath和CSS选择器等方式,断言也是基于页面元素状态。 -
•
Selenium调试通常需要借助浏览器的开发者工具,相对较为独立。
6. 维护性
Playwright: 8/10
-
• 拥有稳定的
API,高度模块化,易于维护 -
• 相对较新,社区不如
Selenium庞大
Cypress: 8/10
-
• 大型项目中,由于缺乏一些
Selenium的通用性,可能需要更多的工作
Selenium: 7/10
-
• 成熟且稳定,但可能需要更多的配置。
-
• 随着时间的推移,可能需要不断更新测试脚本。
7. 社区支持
Playwright: 8/10
-
• 社区相对较新,但在不断增长
-
• 微软等大公司支持,但相比
Selenium的社区规模还是较小
Cypress: 8/10
-
• 虽然不如
Selenium那么大,但在社区中也有相当的支持。 -
• 活跃的维护者和贡献者。
Selenium: 9/10
-
• 问题通常能够得到迅速解决。
-
• 大量的文档和教程可用。
8. 结论
根据以上对比和评分,开发者在选择适合自己项目需求的测试框架时,往往会考虑多种因素:
-
•
Playwright适合高性能大型的项目,在跨浏览器支持、执行速度和灵活性上,可能是一个很好的选择。 -
•
Cypress专注于简单易用,适用于单页面应用的测试。 -
•
Selenium在社区支持和成熟性上胜过其他两者,适合那些需要广泛支持的项目。
以上工具我在过去项目中都有使用,Cypress在3-4年前使用,最近转到了Playwright,考虑的主要因素还是项目特点+团队情况:比如语言熟悉程度、自动化学习兴趣,独立解决问题能力等等。
总之,自动化框架最终的选择Playwright、Cypress、Selenium根据项目的具体需求和团队的技术偏好来进行权衡。如果没有特别的想法,那么选择最新的Playwright大概率是不错的方案。
更多推荐


所有评论(0)