在使用 Playwright
启动 Electron
应用时,偶尔会遇到 Electron
应用程序启动后没有返回对应的实例(ElectronApplication
)的问题。本文将为你提供可能的原因分析和相应的解决方案
1. 可能的原因分析
1.1 启动命令配置不正确
详细描述
Playwright
启动 Electron
应用时,通常需要提供正确的 Electron
可执行文件路径和必要的命令行参数。如果这些配置错误或路径不正确,Electron
应用可能会启动失败或无法返回实例。
解决方案
确保你指定了正确的 Electron
可执行文件路径及启动参数。一般 Electron
项目的可执行文件路径可以通过 node_modules/.bin/electron
找到。
TypeScript
const electronPath = require('electron');
const electronApp = await playwright._electron.launch({ executablePath: electronPath });
1.2 Electron
版本问题
详细描述
Playwright
支持多个 Electron
版本,但某些旧版本可能与 Playwright
的 API
不完全兼容,导致实例返回异常。
解决方案
确保你使用的 Electron
版本与 Playwright
兼容。升级 Electron
版本,或检查 Playwright
文档,确认你使用的 Playwright
版本是否支持当前的 Electron
版本。
1.3 启动速度过慢
详细描述
Electron
应用在启动过程中,特别是在初始化阶段,可能需要加载大量资源,导致启动速度变慢。默认情况下,Playwright
可能会超时,导致无法捕获应用实例。
解决方案
增加 Playwright
的启动超时限制。你可以通过 launch
方法中的 timeout
参数来延长超时时间:
TypeScript
const electronApp = await playwright._electron.launch({
executablePath: electronPath,
timeout: 60000 // 增加超时为 60 秒
});
1.4 未正确捕获主窗口
详细描述
Electron
应用启动时,如果没有明确地捕获主窗口,Playwright
可能无法返回正确的实例。例如,主窗口的创建可能被延迟,或者窗口未在启动时立即可用。
解决方案
确保 Electron
应用在启动时创建并显示主窗口。你可以通过在 main.js
文件中添加 app.on('ready')
的监听,确保主窗口在 Electron
准备好时创建。
TypeScript
app.on('ready', () => {
createWindow();
});
1.5 Electron
进程问题
详细描述
Electron
应用可能由于内部进程问题或崩溃而无法成功启动。这可能是由于代码错误、资源缺失或其他与应用逻辑相关的问题。
解决方案
在调试过程中,可以通过在 Electron
应用启动时检查日志信息,定位具体的错误。例如,在 main.js
中添加日志输出:
TypeScript
app.on('window-all-closed', () => {
console.log('All windows are closed');
});
1.6 Playwright
环境问题
详细描述
在某些情况下,Playwright
本身的配置或依赖环境可能不完整,导致 Electron
应用无法正常启动。例如,缺少系统依赖或库文件可能会导致问题。
解决方案
确保 Playwright
已正确安装并完成依赖配置,特别是在 Linux
系统上,可能需要安装一些额外的依赖。你可以使用 Playwright
自带的依赖安装工具:
TypeScript
npx playwright install-deps
小结
在 Playwright
启动 Electron
应用时,如果遇到没有返回实例的问题,可以从上述几个方面进行排查和解决。确保启动命令正确、Electron
版本兼容、适当延长超时时间,并检查启动过程中是否有错误日志输出。
通过这种方式,你将能更好地理解和调试 Playwright
与 Electron
的集成问题。
自动化测试项目中,常常会复用登录代码。该方法存在一些局限性,比如在全局设置中看不到测试的记录,包括HTML
报告中也不会出现,从而使得调试变得困难。下文分享了使用项目依赖来优化这个问题的方法
2. 什么是项目依赖?
项目依赖是一种更好的全局设置方法。通过创建一个独立的项目作为测试设置的一部分,每次运行基本项目中的测试时,首先会执行设置项目中的测试步骤。
2.1 配置项目依赖
为了实现项目依赖,首先需要在 Playwright
配置文件 playwright.config.ts
中定义两个项目:一个用于设置(setup
项目),另一个是依赖于 setup
的基本测试项目
TypeScript
import { defineConfig } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'setup',
testMatch: '**/*.setup.ts',
},
{
name: 'basic',
dependencies: ['setup'],
},
],
});
通过这种配置,HTML
报告中会显示设置测试的踪迹,你可以通过 trace viewer
检查设置过程的 DOM
快照,并且可以使用 fixtures
。
2.2 运行顺序
setup
项目的测试将首先运行,之后 chromium
、webkit
和 firefox
项目的测试将并行执行。

2.3 项目依赖失败时的处理
例如,如果 e2e
测试项目依赖于 Browser Login
和 Database
项目,而 Database
项目测试失败,则 e2e
测试项目将不会执行。

3. 项目依赖的应用实例
Playwright
使用浏览器上下文(Browser Contexts
)运行测试,确保每个测试彼此独立运行。这意味着每个测试都有自己的本地存储、会话存储和 cookies
。然而,测试可以通过复用其他测试生成的存储状态(storage state
),例如包含 cookies
和本地存储快照,以在已登录的状态下运行。
3.1 实例:通过项目依赖复用 Wikipedia
登录
接下来,我们将创建一个使用项目依赖来实现全局设置的例子,通过登录 Wikipedia 并保存存储状态(storage state),所有后续测试在运行时将继承登录状态。
配置 setup
项目
首先,创建或修改 playwright.config.ts
文件。
TypeScript
import { defineConfig } from '@playwright/test';
export default defineConfig({
testDir: './tests',
projects: [
{
name: 'setup',
testMatch: '**/*.setup.ts',
},
],
});
创建登录测试
创建一个 login.setup.ts
文件,编写 Wikipedia
登录测试。
TypeScript
import { test as setup, expect } from '@playwright/test';
setup('do login', async ({ page }) => {
await page.goto('https://en.wikipedia.org');
await page.getByRole('link', { name: 'Log in' }).click();
await page.getByPlaceholder('Enter your username').fill('your_username');
await page.getByPlaceholder('Enter your password').fill('your_password');
await page.getByRole('button', { name: 'Log in' }).click();
await expect(page.getByRole('button', { name: 'Personal tools' })).toBeVisible();
});
为了确保用户名和密码的安全,可以将它们存储为 .env
变量,并通过 process.env.USERNAME!
和 process.env.PASSWORD!
访问。
TypeScript
import { test as setup, expect } from '@playwright/test';
setup('do login', async ({ page }) => {
await page.goto('https://en.wikipedia.org');
await page.getByRole('link', { name: 'Log in' }).click();
await page.getByPlaceholder('Enter your username').fill(process.env.USERNAME!);
await page.getByPlaceholder('Enter your password').fill(process.env.PASSWORD!);
await page.getByRole('button', { name: 'Log in' }).click();
await expect(page.getByRole('button', { name: 'Personal tools' })).toBeVisible();
});
安装 dotenv
包并在配置文件中引入。
e2e
测试项目
创建一个名为 e2e tests logged in
的项目,该项目依赖于 setup
项目,并将存储状态保存在 auth.json
文件中。
TypeScript
import { defineConfig } from '@playwright/test';
import path from 'path';
require('dotenv').config();
export const STORAGE_STATE = path.join(__dirname, 'playwright/.auth/user.json');
export default defineConfig({
testDir: './tests',
projects: [
{
name: 'setup',
testMatch: '**/*.setup.ts',
},
{
name: 'e2e tests logged in',
testMatch: '**/*loggedin.spec.ts',
dependencies: ['setup'],
use: {
storageState: STORAGE_STATE,
},
},
],
});
通过这种方式,所有 e2e 项目将从登录状态开始运行。
配置 HTML
报告和踪迹
为了查看更详细的报告,您可以配置 HTML
报告和踪迹。
TypeScript
import { defineConfig } from '@playwright/test';
import path from 'path';
require('dotenv').config();
export const STORAGE_STATE = path.join(__dirname, 'playwright/.auth/user.json');
export default defineConfig({
testDir: './tests',
reporter: ['html'],
retries: process.env.CI ? 2 : 0,
fullyParallel: true,
use: {
baseURL: 'https://en.wikipedia.org',
trace: 'on-first-retry',
},
projects: [
{
name: 'setup',
testMatch: '**/*.setup.ts',
},
{
name: 'e2e tests logged in',
dependencies: ['setup'],
use: {
storageState: STORAGE_STATE,
},
},
],
});

运行测试后,可以通过 npx playwright show-report
命令查看完整的 HTML
报告和踪迹。

梳理
通过使用项目依赖,您可以轻松实现全局设置,并自动生成 HTML
报告和踪迹,提升调试体验。借助 Playwright
的这一功能,您的测试流程将更加高效和灵活。
在使用 Playwright
进行端到端(E2E
)测试时,有时你可能还没有正式的生产环境或测试环境,这时候在本地启动一个开发服务器(dev server
)进行测试将会非常有用。本文介绍了在Playwright
中如何启动本地服务器运行Playwright
测试。
4. 如何配置 Playwright 的本地开发服务器
当你通过 VS Code
扩展安装 Playwright
或初始化 Playwright
项目时,你会发现 playwright.config.ts
文件中有一个 webServer
选项。这个选项默认是被注释掉的,解开这个注释或手动添加这一配置,就可以在运行测试之前启动本地开发服务器。
以下是基本的配置示例:
TypeScript
import { defineConfig } from '@playwright/test';
export default defineConfig({
// 其他配置...
// 在启动测试前运行本地开发服务器
webServer: {
command: 'npm run start', // 启动开发服务器的命令
url: 'http://127.0.0.1:3000', // 服务器运行的地址
reuseExistingServer: !process.env.CI, // 是否复用已存在的服务器
},
});
4.1 command
参数详解
command
是启动本地开发服务器的 shell
命令。对于大多数 web
框架,通常使用 npm run start
命令来启动开发服务器。当然,也可以根据项目实际情况更换为其他适用的命令。
TypeScript
webServer: {
command: 'npm run start', // 启动开发服务器的命令
},
4.2 url
参数详解
url
是本地开发服务器的地址。测试运行器将等待该地址返回状态码为 2xx
、3xx
或常见的 400
系列状态码,表示服务器已经准备好接受连接。例如,地址可以设置为 http://127.0.0.1:3000
。当服务器就绪后,测试将自动开始执行。
TypeScript
webServer: {
url: 'http://127.0.0.1:3000', // 服务器的URL地址
},
4.3 复用已有服务器
reuseExistingServer
选项允许在本地开发时复用已有的服务器。如果指定的 URL
上已经有服务器在运行,则不再启动新的服务器。这个选项一般在本地开发环境中使用,但在 CI
环境下会禁用该功能以避免复用服务器。
4.4 增加服务器启动超时时间
在某些情况下,服务器可能需要更长时间才能启动。如果需要,可以通过设置 timeout
来增加等待服务器启动的时间。
TypeScript
webServer: {
timeout: 120 * 1000, // 超时时间为 120 秒
},
4.5 设置 baseURL
建议在 use
配置中添加 baseURL
,这样在测试中你可以使用相对路径进行页面导航,而不需要反复指定完整的 URL
。
TypeScript
use: {
baseURL: 'http://127.0.0.1:3000', // 基础URL
},
在测试代码中,你可以像下面这样使用相对路径:
TypeScript
const { test } = require('@playwright/test');
test('我的测试', async ({ page }) => {
// 这将会导航到 http://127.0.0.1:3000/about
await page.goto('./about');
});
总结
通过在 Playwright
配置文件中添加 webServer
选项,你可以在运行测试时自动启动本地开发服务器,从而在没有正式环境的情况下进行有效的端到端测试。这种方式可以大大提高开发效率,尤其适用于正在开发中的项目。