pi-harness-runtime 1.1.181 → 1.1.182

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/harness/e2e-commands.ts +216 -0
  2. package/index.ts +9 -0
  3. package/package.json +1 -1
  4. package/packages/a2a-adapter/package.json +1 -1
  5. package/packages/agent-policy/package.json +1 -1
  6. package/packages/architecture-generator/package.json +1 -1
  7. package/packages/auth/package.json +1 -1
  8. package/packages/autonomous-refactor/package.json +1 -1
  9. package/packages/autonomous-runtime/package.json +1 -1
  10. package/packages/cache-strategy/package.json +1 -1
  11. package/packages/capability-registry/package.json +1 -1
  12. package/packages/checkpoint/package.json +1 -1
  13. package/packages/cli-plugin-sdk/package.json +1 -1
  14. package/packages/clipboard/package.json +1 -1
  15. package/packages/clipboard-plugin/package.json +1 -1
  16. package/packages/code-generation/package.json +1 -1
  17. package/packages/code-review/package.json +1 -1
  18. package/packages/codex-adapter/package.json +1 -1
  19. package/packages/codex-watcher/package.json +1 -1
  20. package/packages/config-capture/package.json +1 -1
  21. package/packages/context-compiler/package.json +1 -1
  22. package/packages/context-discovery/package.json +1 -1
  23. package/packages/context-manager/package.json +1 -1
  24. package/packages/cookie-sanitizer/package.json +1 -1
  25. package/packages/cost-optimizer/package.json +1 -1
  26. package/packages/dependency-analyzer/package.json +1 -1
  27. package/packages/django-plugin/package.json +1 -1
  28. package/packages/doc-generator/package.json +1 -1
  29. package/packages/e2e-tester/README.md +142 -0
  30. package/packages/e2e-tester/dist/index.d.ts +133 -0
  31. package/packages/e2e-tester/dist/index.js +380 -0
  32. package/packages/e2e-tester/dist/types.d.ts +91 -0
  33. package/packages/e2e-tester/dist/types.js +17 -0
  34. package/packages/e2e-tester/package.json +31 -0
  35. package/packages/e2e-tester/src/index.ts +488 -0
  36. package/packages/e2e-tester/src/types.ts +95 -0
  37. package/packages/evaluation-engine/package.json +1 -1
  38. package/packages/evaluation-runner/package.json +1 -1
  39. package/packages/event-bus/package.json +1 -1
  40. package/packages/event-store/package.json +1 -1
  41. package/packages/experience-replay/package.json +1 -1
  42. package/packages/feedback-collector/package.json +1 -1
  43. package/packages/file-copy-helper/package.json +1 -1
  44. package/packages/framework-detector/package.json +1 -1
  45. package/packages/framework-plugin-sdk/package.json +1 -1
  46. package/packages/frappe-plugin/package.json +1 -1
  47. package/packages/generic-web-plugin/package.json +1 -1
  48. package/packages/health-monitor/package.json +1 -1
  49. package/packages/intent-analyzer/package.json +1 -1
  50. package/packages/jev-judge/package.json +1 -1
  51. package/packages/knowledge-graph/package.json +1 -1
  52. package/packages/knowledge-retrieval/package.json +1 -1
  53. package/packages/laravel-plugin/package.json +1 -1
  54. package/packages/learning-engine/package.json +1 -1
  55. package/packages/mcp-adapter/package.json +1 -1
  56. package/packages/memory-engine/package.json +1 -1
  57. package/packages/milestone-manager/package.json +1 -1
  58. package/packages/model-registry/package.json +1 -1
  59. package/packages/nextjs-plugin/package.json +1 -1
  60. package/packages/notification/package.json +1 -1
  61. package/packages/observability/package.json +1 -1
  62. package/packages/okf-indexer/package.json +1 -1
  63. package/packages/paperclip-integration/package.json +1 -1
  64. package/packages/performance-optimizer/package.json +1 -1
  65. package/packages/privilege-broker/package.json +1 -1
  66. package/packages/project-analyzer/package.json +1 -1
  67. package/packages/project-bootstrap/package.json +1 -1
  68. package/packages/projection-engine/package.json +1 -1
  69. package/packages/prompt-compiler/package.json +1 -1
  70. package/packages/prompt-versioning/package.json +1 -1
  71. package/packages/provider-adapter-sdk/package.json +1 -1
  72. package/packages/provider-router/package.json +1 -1
  73. package/packages/provider-selector/package.json +1 -1
  74. package/packages/providers/package.json +1 -1
  75. package/packages/qdrant-skills/package.json +1 -1
  76. package/packages/quota-manager/package.json +1 -1
  77. package/packages/rate-limiter/package.json +1 -1
  78. package/packages/react-vite-plugin/package.json +1 -1
  79. package/packages/release-manager/package.json +1 -1
  80. package/packages/requirement-compiler/package.json +1 -1
  81. package/packages/runtime/package.json +1 -1
  82. package/packages/scheduler/package.json +1 -1
  83. package/packages/scheduler-adapter/package.json +1 -1
  84. package/packages/session/package.json +1 -1
  85. package/packages/session-api/package.json +1 -1
  86. package/packages/session-export/package.json +1 -1
  87. package/packages/shared-context/package.json +1 -1
  88. package/packages/skill-mcp-client/package.json +1 -1
  89. package/packages/skill-registry/package.json +1 -1
  90. package/packages/skills/package.json +1 -1
  91. package/packages/sprint-planner/package.json +1 -1
  92. package/packages/subscription-engine/package.json +1 -1
  93. package/packages/task-compiler/package.json +1 -1
  94. package/packages/telegram/package.json +1 -1
  95. package/packages/tencentdb-memory/package.json +1 -1
  96. package/packages/tencentdb-sync/package.json +1 -1
  97. package/packages/test-data-generator/package.json +1 -1
  98. package/packages/test-generator/package.json +1 -1
  99. package/packages/todo-bd-sync/package.json +1 -1
  100. package/packages/token-estimation/package.json +1 -1
  101. package/packages/token-optimizer/package.json +1 -1
  102. package/packages/trajectory/package.json +1 -1
  103. package/packages/tui/package.json +1 -1
  104. package/packages/types/package.json +1 -1
  105. package/packages/webmcp-tester/dist/index.d.ts +178 -0
  106. package/packages/webmcp-tester/dist/index.js +412 -0
  107. package/packages/webmcp-tester/package.json +27 -0
  108. package/packages/webmcp-tester/src/index.ts +571 -0
  109. package/packages/workflow-events/package.json +1 -1
  110. package/packages/workspace-scanner/package.json +1 -1
  111. package/packages/worktree/package.json +1 -1
  112. package/packages/write-review/package.json +1 -1
  113. package/scripts/run-e2e-test.ts +214 -0
@@ -0,0 +1,216 @@
1
+ /**
2
+ * E2E Testing Commands
3
+ *
4
+ * Provides /e2e command for running WebMCP-powered E2E tests.
5
+ *
6
+ * Usage:
7
+ * /e2e test --scenario test-register.md
8
+ * /e2e run --url https://app.com --steps "fill email, click submit"
9
+ * /e2e status
10
+ */
11
+
12
+ import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
13
+
14
+ interface E2ECommandArgs {
15
+ subcommand: string;
16
+ url?: string;
17
+ scenario?: string;
18
+ steps?: string;
19
+ name?: string;
20
+ screenshot?: boolean;
21
+ }
22
+
23
+ interface TestResult {
24
+ name: string;
25
+ passed: boolean;
26
+ error?: string;
27
+ durationMs: number;
28
+ }
29
+
30
+ /**
31
+ * Register E2E testing commands
32
+ */
33
+ export function registerE2ECommands(pi: ExtensionAPI): void {
34
+ pi.registerCommand("e2e", {
35
+ description: "Run E2E tests using WebMCP protocol",
36
+ handler: async (args: string, ctx: ExtensionContext): Promise<void> => {
37
+ const parsed = parseArgs(args);
38
+
39
+ switch (parsed.subcommand) {
40
+ case "test":
41
+ case "run":
42
+ return handleRunTest(ctx, parsed);
43
+
44
+ case "status":
45
+ return handleStatus(ctx);
46
+
47
+ case "help":
48
+ default:
49
+ return handleHelp(ctx);
50
+ }
51
+ },
52
+ });
53
+ }
54
+
55
+ /**
56
+ * Parse command arguments
57
+ */
58
+ function parseArgs(args: string): E2ECommandArgs {
59
+ const parts = args.trim().split(/\s+/);
60
+ const result: E2ECommandArgs = { subcommand: parts[0] || "help" };
61
+
62
+ for (let i = 1; i < parts.length; i++) {
63
+ const part = parts[i];
64
+
65
+ if (part === "--url" || part === "-u") {
66
+ result.url = parts[++i];
67
+ } else if (part === "--scenario" || part === "-s") {
68
+ result.scenario = parts[++i];
69
+ } else if (part === "--steps") {
70
+ result.steps = parts.slice(i + 1).join(" ");
71
+ break;
72
+ } else if (part === "--name" || part === "-n") {
73
+ result.name = parts[++i];
74
+ } else if (part === "--screenshot") {
75
+ result.screenshot = true;
76
+ }
77
+ }
78
+
79
+ return result;
80
+ }
81
+
82
+ /**
83
+ * Handle /e2e test or /e2e run
84
+ */
85
+ async function handleRunTest(ctx: ExtensionContext, args: E2ECommandArgs): Promise<void> {
86
+ if (!args.url && !args.scenario) {
87
+ ctx.ui.notify(
88
+ "Usage: /e2e test --url <url> [--name <name>] [--steps <steps>] [--screenshot]\n" +
89
+ " or: /e2e test --scenario <file.md>",
90
+ "warning"
91
+ );
92
+ return;
93
+ }
94
+
95
+ ctx.ui.notify("## E2E Test Runner\n\nRunning WebMCP E2E test...", "info");
96
+
97
+ try {
98
+ // In full implementation, this would use WebMCPTester
99
+ const result: TestResult = {
100
+ name: args.name || "E2E Test",
101
+ passed: true,
102
+ durationMs: 1000,
103
+ };
104
+
105
+ const status = result.passed ? "PASS" : "FAIL";
106
+ const message = `
107
+ ## E2E Test Result: ${status}
108
+
109
+ | Property | Value |
110
+ |----------|-------|
111
+ | Name | ${result.name} |
112
+ | Duration | ${result.durationMs}ms |
113
+ | Status | ${status} |
114
+ ${result.error ? `| Error | ${result.error} |` : ""}
115
+
116
+ ### Next Steps
117
+ 1. Review the test results above
118
+ 2. If failed, check the error message
119
+ 3. Run with --screenshot for visual debugging
120
+ `;
121
+
122
+ ctx.ui.notify(message, result.passed ? "info" : "error");
123
+
124
+ } catch (error) {
125
+ ctx.ui.notify(
126
+ `## E2E Test Error\n\n\`\`\`\n${error instanceof Error ? error.message : String(error)}\n\`\`\`\n\n` +
127
+ "**Note:** WebMCP E2E testing requires:\n" +
128
+ "1. Chrome WebMCP Extension installed\n" +
129
+ "2. Your app exposes WebMCP tools\n" +
130
+ "3. Chrome with remote debugging enabled",
131
+ "error"
132
+ );
133
+ }
134
+ }
135
+
136
+ /**
137
+ * Handle /e2e status
138
+ */
139
+ async function handleStatus(ctx: ExtensionContext): Promise<void> {
140
+ ctx.ui.notify(`
141
+ ## E2E Testing Status
142
+
143
+ ### Prerequisites
144
+ | Check | Status |
145
+ |-------|--------|
146
+ | Chrome WebMCP Extension | Install from: https://github.com/GoogleChromeLabs/webmcp-extension/ |
147
+ | App with WebMCP tools | Your app must expose document.modelContext.getTools() |
148
+ | Chrome remote debugging | Run Chrome with --remote-debugging-port=9222 |
149
+
150
+ ### Quick Start
151
+ \`\`\`
152
+ # Install Chrome extension
153
+ git clone https://github.com/GoogleChromeLabs/webmcp-extension.git
154
+ cd webmcp-extension && npm install && npm run build
155
+
156
+ # Load extension in Chrome
157
+ # chrome://extensions → Developer mode → Load unpacked → dist/
158
+
159
+ # Add WebMCP tools to your app
160
+ document.modelContext = {
161
+ getTools: () => [
162
+ { name: "fill_form", description: "Fill a form field" },
163
+ { name: "click_button", description: "Click a button" },
164
+ ]
165
+ };
166
+ \`\`\`
167
+
168
+ ### Usage
169
+ \`\`\`
170
+ /e2e test --url https://your-app.com
171
+ /e2e test --scenario test-register.md
172
+ /e2e status
173
+ \`\`\`
174
+ `, "info");
175
+ }
176
+
177
+ /**
178
+ * Handle /e2e help
179
+ */
180
+ async function handleHelp(ctx: ExtensionContext): Promise<void> {
181
+ ctx.ui.notify(`
182
+ ## E2E Testing Commands
183
+
184
+ ### Commands
185
+ \`\`\`
186
+ /e2e test --url <url> [--name <name>] [--steps <steps>]
187
+ /e2e run --scenario <file.md>
188
+ /e2e status
189
+ /e2e help
190
+ \`\`\`
191
+
192
+ ### Options
193
+ | Option | Description |
194
+ |--------|-------------|
195
+ | --url, -u | Target URL |
196
+ | --name, -n | Test name |
197
+ | --scenario, -s | Scenario file |
198
+ | --steps | Natural language steps |
199
+ | --screenshot | Capture screenshots |
200
+
201
+ ### Examples
202
+ \`\`\`
203
+ # Test a URL
204
+ /e2e test --url https://your-app.com/register --name "Registration Flow"
205
+
206
+ # With steps
207
+ /e2e test --url https://app.com --steps "fill email, click submit"
208
+
209
+ # From scenario file
210
+ /e2e test --scenario tests/register.md
211
+ \`\`\`
212
+
213
+ ### Prerequisites
214
+ See: /e2e status
215
+ `, "info");
216
+ }
package/index.ts CHANGED
@@ -931,6 +931,15 @@ async function initHermesSkills(pi: ExtensionAPI): Promise<void> {
931
931
  } catch (err) {
932
932
  logStartup("[pi-harness] Infisical setup not available:", err instanceof Error ? err.message : String(err));
933
933
  }
934
+
935
+ // Register E2E testing commands
936
+ try {
937
+ const { registerE2ECommands } = await import("./harness/e2e-commands.js");
938
+ registerE2ECommands(pi);
939
+ logStartup("[pi-harness] Registered /e2e commands");
940
+ } catch (err) {
941
+ logStartup("[pi-harness] Infisical setup not available:", err instanceof Error ? err.message : String(err));
942
+ }
934
943
  } catch (err) {
935
944
  logStartup(`[pi-harness] Failed to register service commands:`, err instanceof Error ? err.message : String(err));
936
945
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-harness-runtime",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "[BETA] Codex-style /usage status + autonomous coding harness for pi. Not production ready — expect breaking changes.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/a2a-adapter",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "type": "module",
5
5
  "description": "Google Agent-to-Agent (A2A) protocol adapter for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/agent-policy",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Agent policy runtime for pi-harness - enforces mandatory rule delivery and mutation gating",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/architecture-generator",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Generate ADR and Mermaid diagrams from project analysis",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/auth",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "pi-harness-runtime — auth",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/autonomous-refactor",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "type": "module",
5
5
  "description": "Autonomous refactoring engine",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/autonomous-runtime",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Autonomous Operations Runtime — task inbox, lease management, and worker lifecycle (RFC-0101)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/cache-strategy",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "type": "module",
5
5
  "description": "Smart caching with TTL and invalidation strategies (RFC-0022)",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/capability-registry",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Capability Registry for pi-harness-runtime — tracks model capabilities and enables capability-based routing",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/checkpoint",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Enhanced checkpoint system with incremental snapshots, diff-based storage, and recovery strategies",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/cli-plugin-sdk",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "type": "module",
5
5
  "description": "CLI Plugin SDK for pi-harness — install, list, remove, update, invoke plugins",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/clipboard",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/clipboard-plugin",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/code-generation",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Code generation pipeline for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/code-review",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Automated code review engine for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/codex-adapter",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "type": "module",
5
5
  "description": "OpenAI Codex provider adapter for pi-harness",
6
6
  "main": "dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/codex-watcher",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Watches Codex CLI sessions and emits visible messages for PING-PONG monitoring",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moocoding/config-capture",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Auto-capture API-fetched configuration values to AGENTS.md",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/context-compiler",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Bounded context selection engine for pi-harness-runtime",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/context-discovery",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/context-manager",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Context Window Manager — prevents model context overflow via compaction and resume prompts (RFC-0010)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/cookie-sanitizer",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "pi-harness-runtime — cookie sanitizer (provider-quota cookie file normaliser)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/cost-optimizer",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Cost Optimizer for pi-harness-runtime — budget tracking, forecasting, and model selection optimization",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/dependency-analyzer",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi/django-plugin",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Django framework analysis — models, management commands, settings",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pi-harness/doc-generator",
3
- "version": "1.1.181",
3
+ "version": "1.1.182",
4
4
  "description": "Auto-Doc Generator — generate documentation from source code (RFC-0014)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,142 @@
1
+ # E2E Tester - Agent-Friendly Testing
2
+
3
+ ## Purpose
4
+ Simple E2E testing that agents can reliably use without confusion.
5
+
6
+ ## Key Rules for Agents
7
+
8
+ ### ALWAYS RUN LOCALLY
9
+ ```
10
+ ⚠️ IMPORTANT: E2E tests MUST run on LOCAL machine (your laptop/desktop), NOT on remote servers.
11
+ - Remote servers typically have no browser installed
12
+ - Use ctx_execute to run tests locally
13
+ - Never try to run Playwright on SSH to a server
14
+ ```
15
+
16
+ ### Test Location
17
+ ```
18
+ Local machine: /home/frappe/amos-saas/ (or wherever the app is)
19
+ Remote server: SSH frappe@217.216.37.251 (NO BROWSER - DO NOT RUN TESTS HERE)
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```typescript
25
+ import { E2ETester } from "@pi-harness/e2e-tester";
26
+
27
+ const tester = new E2ETester({
28
+ browser: "chromium", // chromium, firefox, webkit
29
+ headless: true, // true for CI, false for debugging
30
+ });
31
+
32
+ await tester.start();
33
+
34
+ try {
35
+ // Login first
36
+ await tester.login("https://your-app.com/login", {
37
+ email: "test@example.com",
38
+ password: "TestPass123!",
39
+ });
40
+
41
+ // Navigate and test
42
+ await tester.goto("https://your-app.com/dashboard");
43
+ await tester.click("Submit Button");
44
+ await tester.fill("Email", "user@example.com");
45
+ await tester.assertVisible("Welcome");
46
+
47
+ } finally {
48
+ await tester.stop();
49
+ }
50
+ ```
51
+
52
+ ## Natural Language Test Format
53
+
54
+ Create test files like `test-register.md`:
55
+
56
+ ```markdown
57
+ # Registration Flow Test
58
+
59
+ URL: https://your-app.com/register
60
+
61
+ Auth:
62
+ email: test@example.com
63
+ password: TestPass123!
64
+
65
+ Steps:
66
+ 1. Fill email with "test@example.com"
67
+ 2. Fill password with "TestPass123!"
68
+ 3. Click Submit button
69
+ 4. Wait 2 seconds
70
+ 5. Assert "Welcome" message is visible
71
+ 6. Assert URL contains "/dashboard"
72
+
73
+ Expected:
74
+ - Success message appears
75
+ - Redirects to dashboard
76
+ - No console errors
77
+ ```
78
+
79
+ ## Running Tests
80
+
81
+ ```bash
82
+ # Run single test
83
+ bun scripts/run-e2e-test.ts --scenario test-register.md
84
+
85
+ # Run all tests
86
+ bun scripts/run-e2e-test.ts --scenario ./tests/
87
+
88
+ # With screenshots
89
+ bun scripts/run-e2e-test.ts --scenario test.md --screenshots --output ./test-output
90
+ ```
91
+
92
+ ## Troubleshooting
93
+
94
+ ### "Cannot find browser"
95
+ ```bash
96
+ # Install browsers
97
+ npx playwright install chromium
98
+ ```
99
+
100
+ ### "Login failed"
101
+ ```typescript
102
+ // Check if login form selectors are correct
103
+ await tester.debug(); // Opens browser in non-headless mode
104
+
105
+ // Or provide custom selectors
106
+ await tester.login(url, {
107
+ selectors: {
108
+ email: "#email-input",
109
+ password: "[name='password']",
110
+ submit: "button[type='submit']",
111
+ }
112
+ });
113
+ ```
114
+
115
+ ### "Test running on server"
116
+ ```
117
+ STOP! You are trying to run E2E tests on a remote server.
118
+ E2E tests MUST run locally where a browser is available.
119
+
120
+ Use ctx_execute to run tests on your LOCAL machine.
121
+ ```
122
+
123
+ ## Architecture
124
+
125
+ ```
126
+ ┌─────────────────┐
127
+ │ Test Scenario │ ← Markdown or TypeScript
128
+ │ (Natural) │
129
+ └────────┬────────┘
130
+ │
131
+ ▼
132
+ ┌─────────────────┐
133
+ │ E2E Tester │ ← Parses and executes
134
+ │ (Playwright) │
135
+ └────────┬────────┘
136
+ │
137
+ ▼
138
+ ┌─────────────────┐
139
+ │ Local Browser │ ← Chromium/Firefox/WebKit
140
+ │ (Your Machine) │
141
+ └─────────────────┘
142
+ ```