- 前端
- CMS
【免费下载链接】wp-calypso
The JavaScript and API powered WordPress.com
导读:本文以 test/e2e/AGENTS.md(即test/e2e/CLAUDE.md指向的框架说明)为核心骨架,系统梳理 wp-calypso 仓库中基于 Playwright Test 的端到端(E2E)测试体系:从环境搭建、测试运行、Spec 骨架与 Fixture 体系,到 Given/When/Then 编写规范与 CI 标签机制。读完你将掌握在本地跑通、编写并调试 WordPress.com 与 Calypso 客户端 E2E 测试的完整实战能力。
一、框架总览:一切 Spec 都跑在 Playwright Test 上
wp-calypso 的 E2E 测试全部基于 Playwright Test 与 test/e2e/docs/overview.md,该套件是 WordPress.com 客户端的自动化验收测试,用于在浏览器中像真实用户一样驱动被测系统,配合 CI 流水线尽早捕获关键用户流程的回归。
- 测试文件位置:
test/e2e/specs/**/*.spec.ts - 参考示例:specs/tools/import__sites-squarespace.spec.ts、specs/tools/marketing__seo.spec.ts
- 被测范围:Calypso 功能、Calypso 与 Gutenberg 编辑器的交互、国际化与本地化、WordPress.com 新增的 Gutenberg 区块。
完整文档索引见 test/e2e/docs/overview.md,建议优先参考的文档包括 setup.md、tests_local.md、writing_tests.md、creating_reliable_tests.md、style_guide.md、custom_fixtures.md。
二、环境搭建:从零到本地跑通第一个 Spec
在开始写测试前,先按 test/e2e/docs/setup.md 完成环境准备。核心步骤(以 macOS 为例):
- 安装
nvm并切换到仓库根目录package.jsonengines字段要求的 Node.js 版本(通常为最新 LTS); - 通过
corepack enable启用仓库锁定的 yarn 版本; - 克隆仓库后在根目录执行
yarn install安装依赖(TypeScript、Playwright 等版本见test/e2e/package.json); - 获取密钥解密密钥并解密敏感配置:
export E2E_SECRETS_KEY='your-calypso-e2e-config-decode-key-here' yarn workspace wp-e2e-tests decrypt-secrets解密细节见 test_environment.md。
- 转译包(可用
--watch保持监听):
yarn workspace wp-e2e-tests build --watch- 运行测试:
yarn workspace wp-e2e-tests test:pw -- <test_path> --reporter=list默认测试目标为http://calypso.localhost:3000(即本地 Calypso 开发实例,E2E 测试要求其正在运行)。如需指向其他环境,通过CALYPSO_BASE_URL覆盖:
CALYPSO_BASE_URL=https://wpcalypso.wordpress.com yarn workspace wp-e2e-tests test:pw -- <test_path> --reporter=list可用的目标环境包括:本地calypso.localhost:3000、https://wordpress.com(staging/production)、https://wpcalypso.wordpress.com、https://horizon.wordpress.com。
三、运行测试的关键纪律:永远带上--reporter=list
test/e2e/AGENTS.md 反复强调一个最容易踩坑的细节:
IMPORTANT: Always use
--reporter=listto prevent the HTML report from opening automatically on failure. Without this flag, the test process will hang waiting for the HTML report browser window to close.
即运行任何测试都必须加--reporter=list,否则测试失败时终端会被自动弹出的 HTML 报告浏览器窗口阻塞,进程无法退出:
# 正确:测试结束后进程立即退出 yarn playwright test specs/path/to/test.spec.ts --reporter=list # 错误:失败时会卡在等待 HTML 报告关闭 yarn playwright test specs/path/to/test.spec.ts当你确实需要查看 HTML 报告时,去掉该参数跑完测试,再用yarn playwright show-report单独打开。
3.1 按文件、按标签、按套件脚本运行
- 单个/多个 Spec 文件(在
test/e2e目录内):
yarn test:pw -- <path_to_file_1> <path_to_file_2> --reporter=list- 按标签(Tag)运行:Spec 的
test.describe块上声明的标签决定了 CI 如何选择它。在本地用 Playwright 的--grep按标签过滤,例如运行 CI 对每次提交执行的@calypso-pr套件:
# 在 test/e2e 目录内 yarn test:pw:calypso-pr --reporter=list # 在仓库根目录 yarn workspace wp-e2e-tests test:pw:calypso-pr --reporter=list- 预置套件脚本:仓库在
test/e2e/package.json中预置了按标签 grep 或固定 viewport 的脚本:
| 脚本 | 运行内容 |
|---|---|
test:pw:desktop | 仅桌面 viewport |
test:pw:mobile | 仅移动端 viewport |
test:pw:calypso-pr | 每个 feature 分支每次提交执行的 Spec |
test:pw:calypso-release | 每个合并进trunk的 PR 执行的 Spec |
test:pw:dashboard-pr | Dashboard Spec(每个 feature 分支每次提交) |
test:pw:authentication | 登录、2FA 与安全密钥 Spec |
test:pw:a8c-for-agencies | A8C for Agencies Spec |
test:pw:i18n | 国际化 Spec |
test:pw:p2 | P2 内部系统 Spec |
3.2 移动端 viewport 与多项目
默认测试运行在desktopviewport(约 1920x1080)。Playwright 配置了两个项目:
chrome:桌面 Chrome HiDPI,即desktopviewport;mobile:Pixel 7,即mobileviewport,带@desktop-only标签的 Spec 会被跳过。
指定移动端运行:
yarn test:pw:mobile <path_to_spec> --reporter=list大多数测试要求同时在移动端与桌面 viewport 下通过;若页面在不同 viewport 下需要不同选择器或操作,应在页面/组件对象方法内部处理并尽量对 Spec 屏蔽差异,参考 tests_local.md 中的示例。
3.3 调试与类型检查
- 调试方式见 debugging.md;
- Playwright Test 运行时会自行转译 TypeScript,无需额外预构建,但不会做类型检查。要对 Spec 做类型检查,从仓库根目录执行:
yarn tsc --noEmit --project test/e2e/tsconfig.json3.4 认证 Cookie 缓存机制
认证 Cookie 按账号缓存于COOKIES_PATH下:第一个需要某账号的 worker 会持有该账号的锁完成登录并写入 Cookie 文件,其余 worker 等待锁释放后直接复用该文件,无需单独的预热(priming)步骤。
四、编写 Spec:骨架、认证与 Given/When/Then
4.1 Spec 骨架
test/e2e/AGENTS.md给出了最基础的 Spec 骨架,所有 Spec 都应从 lib/pw-base.ts 导入自定义的test、expect与tags:
import { tags, test, expect } from '../../lib/pw-base'; test.describe( 'Test Suite', { tag: [ tags.TAG_NAME ] }, () => { test( 'As a user, I can do something', async ( { page } ) => { await test.step( 'Given precondition', async function () { // test code } ); } ); } );lib/pw-base.ts是自定义 fixture 的唯一集中出口:该文件导出了定制后的 Playwrighttest常量、tags对象以及全部自定义 fixture(见下文),Spec 一律从这里导入,而不是直接使用@playwright/test。
4.2 认证(Authentication)
需要登录的测试在测试签名中声明对应的 account fixture 并调用authenticate:
test( 'Test', async ( { accountDefaultUser, page } ) => { await test.step( 'Given I am authenticated', async function () { await accountDefaultUser.authenticate( page ); } ); } );4.3 Given/When/Then 模式
用test.step()组织步骤,命名以Given(前置条件)/ When(动作)/ Then(断言)/ And(延续)开头:
await test.step( 'Given I am on the login page', async function () {} ); await test.step( 'When I enter credentials', async function () {} ); await test.step( 'Then I am logged in', async function () {} );4.4 完整 Spec 示例
以 specs/tools/marketing__seo.spec.ts(也记录于 writing_tests.md)为例,展示页面对象、account fixture 与步骤的完整配合:
import { DataHelper } from '@automattic/calypso-e2e'; import { expect, tags, test } from '../../lib/pw-base'; test.describe( DataHelper.createSuiteTitle( 'Marketing: SEO' ), { tag: [ tags.CALYPSO_PR ] }, () => { // Fixtures 在测试签名中声明。声明 account fixture 即会以该账号登录, // 因此只取测试真正需要的 fixture。 test( 'As a WordPress.com business plan user with an atomic site, I can see the SEO settings page', async ( { accountAtomic, helperData, page, pageMarketing, } ) => { const frontPageText = helperData.getRandomPhrase(); await test.step( `Given I am authenticated as '${ accountAtomic.accountName }'`, async function () { await accountAtomic.authenticate( page ); } ); await test.step( 'When I visit the Tools > Marketing > Traffic page', async function () { await pageMarketing.visitTab( accountAtomic.getSiteURL( { protocol: false } ), 'traffic' ); } ); await test.step( 'Then I can validate and preview the text', async function () { await pageMarketing.validatePreviewTextForPageStructureCategory( frontPageText ); } ); } ); } );4.5 快速开始清单
- 按
test/e2e/specs/<major_feature>/<major_feature>__<sub_feature>.spec.ts命名创建 TypeScript 文件(Playwright 只收集.spec.ts结尾的文件); import { tags, test } from '../../lib/pw-base';导入样板;- 在
test.describe上声明至少一个标签——无标签的 Spec 永远不会被任何构建选中,也就不会在 CI 上运行; - 编写步骤,必要时新建页面对象、组件或流程对象(参考 library_objects.md)。
4.6 数据驱动:循环定义测试
Playwright 没有内置each助手,直接遍历数据并为每个条目定义独立测试,保持标题唯一:
for ( const target of [ 'Media', 'Settings' ] ) { test( `As a user, I can navigate to ${ target }`, async ( { componentSidebar } ) => { await componentSidebar.navigate( target ); } ); }4.7 Setup / Teardown 与 Viewport
- 优先用 fixture 而非钩子:fixture 只为声明了它的测试运行,且自带清理。确需钩子时,Playwright 提供
test.beforeAll/beforeEach/afterEach/afterAll。注意beforeAll每个文件运行一次(而非每个测试一次),文件在另一个 worker 中被重试时会再次执行,因此它创建的资源必须能承受文件内测试共享与二次创建。 - Viewport 差异:如 writing_tests.md 所示,基于
envVariables.VIEWPORT_NAME === 'mobile'在页面对象方法内分支处理。
五、Fixture 体系:从lib/pw-base.ts到命名约定
5.1 什么是 Custom Fixture
Playwright Test 的核心概念是 fixture:为每个测试建立所需环境("everything it needs and nothing else"),且测试之间相互隔离。全部自定义 fixture 位于 lib/pw-base.ts,该文件导出了定制版test常量供 Spec 使用。典型用法:
import { expect, test } from '../../lib/pw-base'; test( 'should login and load editor', async ( { pageEditor, pageLogin } ) => { await pageLogin.login( 'user', 'pass' ); await pageEditor.open(); // ...test logic... } );5.2 可用 Fixture 一览
- Accounts:
fixtureAccounts(lib/pw-base.ts)中的每个 key 对应一个 fixture(如accountDefaultUser、accountAtomic、accounti18n等),外加accountGivenByEnvironment与accountSMS。声明 account fixture 即会以该账号登录(无论测试体是否使用),因此只声明所需账号。 - Pages / Components / Flows:遵循命名约定:
page*— 页面对象(如pageLogin、pageEditor、pagePeople、pageMarketing)component*— 组件对象(如componentSidebar、componentGutenberg)flow*— 流程对象(如flowLOHPThemeSignup)
- Clients:
clientEmail、clientRestAPI - Other:
secrets、environment、pageIncognito、sitePublic、helperData等
从源码lib/pw-base.ts的导入列表可以看到这些 fixture 背后的真实实现类:LoginPage、EditorPage、MarketingPage、PeoplePage、SidebarComponent、TestAccount、RestAPIClient、EmailClient、Secrets、DataHelper、MediaHelper、NewSiteResponse等均来自@automattic/calypso-e2e包,并辅以getAccount、envVariables、envToFeatureKey、getTestAccountByFeature等工具支撑账号与环境解析。
5.3 Fixture 命名约定
test/e2e/docs/custom_fixtures.md 明确了统一前缀约定,便于快速识别类型、提升可读性与可维护性:
| 前缀 | 类型 | 示例 |
|---|---|---|
account | TestAccount | accounti18n |
client | EmailClient或RestAPIClient | clientEmail |
component | packages/calypso-e2e/src/lib/components | componentSidebar |
environment | EnvVariables | environment |
flow | packages/calypso-e2e/src/lib/flows | flowLOHPThemeSignup |
helper | DataHelper或MediaHelper | helperData |
page | packages/calypso-e2e/src/lib/pages | pageAdvertising |
secrets | Secrets | secrets |
site | NewSiteResponse | sitePublic |
5.4 跳过条件与多上下文
- 跳过:基于
environmentfixture 的条件跳过:
test( 'Test', async ( { environment } ) => { test.skip( environment.TEST_ON_ATOMIC, 'Reason' ); } );- 多上下文:同时使用认证上下文与未认证上下文:
test( 'Test', async ( { page, pageIncognito } ) => { // page = authenticated context // pageIncognito = unauthenticated context } );六、CI 集成:标签、构建配置与调度
6.1 Feature/Test 标签
每个 Spec 至少有一个标签,声明在test.describe块上,取值来自 lib/pw-base.ts 的tags对象。CI 构建配置通过把标签传给 Playwright 的--grep来挑选要运行的 Spec。漏加标签会导致 Spec 永不进入 CI。
| 标签 | 说明 |
|---|---|
@calypso-pr | 仓库内任何 feature 分支的每次提交 |
@calypso-release | 任何合并进trunk的 PR |
@dashboard-pr | Dashboard 专项 Spec(任何 feature 分支的每次提交) |
@a8c-for-agencies | A8C for Agencies 客户端 Spec |
@authentication | 登录、2FA 与安全密钥 Spec |
@gutenberg | 编辑器专项 Spec(定期运行) |
@i18n | 验证国际化字符串的 Spec |
@p2 | 内部 P2 系统 Spec |
@legal | 市场与法务团队 Spec |
@jetpack-wpcom-integration | 测试 Jetpack 在 WPCOM 部署的 Spec |
其余标签仅用于分组、不选择构建;例如@jetpack-remote-site没有任何构建去 grep 它,只带该标签的 Spec 永远不会在 CI 上运行。完整说明见 tests_ci.md。
6.2 分支与主干上的构建配置
- Feature 分支(推送到 GitHub 即进入 TeamCity):
E2E Tests (mobile)、E2E Tests (desktop)自动触发;Pre-Release Tests需手动。 - Trunk(仅 PR 合并后):mobile/desktop 不自动触发,
Pre-Release Tests自动触发。Pre-Release E2E 与 Calypso Deploy 页面及 Slack 频道直连,通过后即可部署到生产。
6.3 定时构建
另有仅在trunk上定期运行的构建:WPCOM/Gutenberg E2E Tests(mobile/desktop,每天一次)、Authentication E2E(每 6 小时一次)。
七、可靠性建议与疑难排查
- 可靠测试:遵循 creating_reliable_tests.md 与 patterns_tricks_gotchas.md 中关于等待策略、选择器稳定性与常见坑的实践,避免脆弱断言。
- 样式规范:Spec 结构、步骤写法与命名遵循 style_guide.md。
- 排查:遇到环境或运行问题先查阅 troubleshooting.md;涉及 Google 认证会话续期的问题见 google_authentication.md。
- 区块冒烟测试:针对 WordPress.com 新增 Gutenberg 区块的快速验证流程见 block_smoke_testing.md。
八、小结
wp-calypso 的 E2E 测试体系把 Playwright Test 的 fixture 机制与一套严格约定(lib/pw-base.ts统一出口、前缀命名、标签驱动 CI、Given/When/Then 步骤、--reporter=list运行纪律)结合起来,构成了覆盖 Calypso、Gutenberg 编辑器、国际化与 A8C for Agencies 等客户端的高质量自动化验收层。新测试作者只需遵循 test/e2e/AGENTS.md 的骨架、接入 lib/pw-base.ts 提供的 fixture,再对照 docs/overview.md 索引的文档按需深入,即可快速产出稳定、可被 CI 自动执行的端到端测试。
- 前端
- CMS
【免费下载链接】wp-calypso
The JavaScript and API powered WordPress.com
相关推荐
wp-calypso E2E 测试框架指南:基于 Playwright Test 的端到端自动化测试实战
wp calypso E2E 测试框架指南:基于 Playwright Test 的端到端自动化测试实战 本文是基于 WordPress.com 开源项目 wp
前端CMSwp-calypso Playwright Test Healer:AI Agent 驱动的 E2E 测试修复实战指南
wp calypso Playwright Test Healer:AI Agent 驱动的 E2E 测试修复实战指南 导读 本指南围绕 wp calypso
前端CMSwp-calypso 的 Playwright Test Generator:基于 Claude Agent 自动生成与转换 E2E 测试的实战指南
wp calypso 的 Playwright Test Generator:基于 Claude Agent 自动生成与转换 E2E 测试的实战指南 导读 wp
前端CMS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考