playwright-test-agents · planner → generator → healer

一次真跑:一条命令给 TodoMVC 写完整 e2e,UI 打断再自愈

下面四格来自同一次 @playwright/test 官方 v1.56+ 运行:planner 写计划、generator 翻成代码、跑绿留报告与 trace,最后 healer 把改坏的 selector 修回可用状态。全程 headless、单 worker、无第三方 API key。

target demo.playwright.dev/todomvc · browser Chromium (headless) · workers 1 · runtime 8.6s · 8 / 8 passed
planner

Test Plan · 人类可读

./specs/todomvc.md
Target https://demo.playwright.dev/todomvc Browser Chromium Workers 1

App 是一个前端 todo 列表,状态存 localStorage;过滤器写在 URL hash,切换过滤不能触发硬刷新。

§1 Add new todos

  • 输入 + Enter,追加到列表,输入框清空,计数器 n items left
  • 只有空白的输入应被拒绝(app 内做 trim)。

§2 Toggle complete / active

  • 点圆形复选框 → 该行 completed 状态翻转、样式打删除线、剩余计数下降。
  • Mark all as complete → 一次翻转全部行。

§3 Edit inline

  • 双击行进入编辑框,Enter commit、Escape revert、失焦 commit、空 commit 删除。

§4 Filter Active / Completed

  • 三个过滤 chip 改变可见子集,不打网络。
  • 计数器始终反映 active 总数,与当前过滤无关。

§5 Clear completed

  • 删除所有 completed 行;没有 completed 时按钮不出现。
generator

Spec Code · 可跑

./tests/todomvc.spec.ts
 1import { test, expect, type Page } from "@playwright/test";
 2
 3const INPUT = ".new-todo";
 4const ITEMS = ".todo-list li";
 5const COUNT = ".todo-count";
 6
 7async function seed(page: Page, titles: string[]) {
 8  await page.goto("/todomvc/");
 9  for (const t of titles) {
10    await page.locator(INPUT).fill(t);
11    await page.locator(INPUT).press("Enter");
12  }
13}
14
15test.describe("TodoMVC · agent-generated e2e (§1–§5)", () => {
16  test("§1 add: appends in order, clears input, updates counter", async ({ page }) => {
17    await page.goto("/todomvc/");
18    for (const t of ["buy milk", "walk dog", "finish spec"]) {
19      await page.locator(INPUT).fill(t);
20      await page.locator(INPUT).press("Enter");
21      await expect(page.locator(INPUT)).toHaveValue("");
22    }
23    await expect(page.locator(ITEMS)).toHaveText(["buy milk", "walk dog", "finish spec"]);
24    await expect(page.locator(COUNT)).toContainText("3 items left");
25  });
26
27  // §2 toggle · §3 edit · §4 filter · §5 clear · 全部 8 个 case 见完整文件
28});
report

HTML Report + Trace Viewer

./playwright-report/index.html · trace.zip
playwright-report / index.html
Playwright HTML report showing 8 passed tests across TodoMVC scenarios
show-trace · timeline
Playwright trace viewer showing seeded todos and locator assertions
8 passed 0 failed 0 flaky 0.1s fastest · 1.2s slowest trace: on
healer

Broken selector → healed

./before/ · ./after/
FAIL before · locator not found
Empty TodoMVC input, list never populated, test failed at locator.fill
PASS after · locator restored
TodoMVC list populated with buy milk, walk dog, finish spec — 3 items left
// tests/todomvc-add.spec.ts - const INPUT = ".new-todo-BROKEN"; + const INPUT = ".new-todo";

Healer 只改一行 selector,断言 toHaveText([...]) 完全不动。跑一次红、healer 读 trace + 页面结构、改回可用状态、再跑一次绿——闭环收在同一个 spec 文件里。