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.
- package/harness/e2e-commands.ts +216 -0
- package/index.ts +9 -0
- package/package.json +1 -1
- package/packages/a2a-adapter/package.json +1 -1
- package/packages/agent-policy/package.json +1 -1
- package/packages/architecture-generator/package.json +1 -1
- package/packages/auth/package.json +1 -1
- package/packages/autonomous-refactor/package.json +1 -1
- package/packages/autonomous-runtime/package.json +1 -1
- package/packages/cache-strategy/package.json +1 -1
- package/packages/capability-registry/package.json +1 -1
- package/packages/checkpoint/package.json +1 -1
- package/packages/cli-plugin-sdk/package.json +1 -1
- package/packages/clipboard/package.json +1 -1
- package/packages/clipboard-plugin/package.json +1 -1
- package/packages/code-generation/package.json +1 -1
- package/packages/code-review/package.json +1 -1
- package/packages/codex-adapter/package.json +1 -1
- package/packages/codex-watcher/package.json +1 -1
- package/packages/config-capture/package.json +1 -1
- package/packages/context-compiler/package.json +1 -1
- package/packages/context-discovery/package.json +1 -1
- package/packages/context-manager/package.json +1 -1
- package/packages/cookie-sanitizer/package.json +1 -1
- package/packages/cost-optimizer/package.json +1 -1
- package/packages/dependency-analyzer/package.json +1 -1
- package/packages/django-plugin/package.json +1 -1
- package/packages/doc-generator/package.json +1 -1
- package/packages/e2e-tester/README.md +142 -0
- package/packages/e2e-tester/dist/index.d.ts +133 -0
- package/packages/e2e-tester/dist/index.js +380 -0
- package/packages/e2e-tester/dist/types.d.ts +91 -0
- package/packages/e2e-tester/dist/types.js +17 -0
- package/packages/e2e-tester/package.json +31 -0
- package/packages/e2e-tester/src/index.ts +488 -0
- package/packages/e2e-tester/src/types.ts +95 -0
- package/packages/evaluation-engine/package.json +1 -1
- package/packages/evaluation-runner/package.json +1 -1
- package/packages/event-bus/package.json +1 -1
- package/packages/event-store/package.json +1 -1
- package/packages/experience-replay/package.json +1 -1
- package/packages/feedback-collector/package.json +1 -1
- package/packages/file-copy-helper/package.json +1 -1
- package/packages/framework-detector/package.json +1 -1
- package/packages/framework-plugin-sdk/package.json +1 -1
- package/packages/frappe-plugin/package.json +1 -1
- package/packages/generic-web-plugin/package.json +1 -1
- package/packages/health-monitor/package.json +1 -1
- package/packages/intent-analyzer/package.json +1 -1
- package/packages/jev-judge/package.json +1 -1
- package/packages/knowledge-graph/package.json +1 -1
- package/packages/knowledge-retrieval/package.json +1 -1
- package/packages/laravel-plugin/package.json +1 -1
- package/packages/learning-engine/package.json +1 -1
- package/packages/mcp-adapter/package.json +1 -1
- package/packages/memory-engine/package.json +1 -1
- package/packages/milestone-manager/package.json +1 -1
- package/packages/model-registry/package.json +1 -1
- package/packages/nextjs-plugin/package.json +1 -1
- package/packages/notification/package.json +1 -1
- package/packages/observability/package.json +1 -1
- package/packages/okf-indexer/package.json +1 -1
- package/packages/paperclip-integration/package.json +1 -1
- package/packages/performance-optimizer/package.json +1 -1
- package/packages/privilege-broker/package.json +1 -1
- package/packages/project-analyzer/package.json +1 -1
- package/packages/project-bootstrap/package.json +1 -1
- package/packages/projection-engine/package.json +1 -1
- package/packages/prompt-compiler/package.json +1 -1
- package/packages/prompt-versioning/package.json +1 -1
- package/packages/provider-adapter-sdk/package.json +1 -1
- package/packages/provider-router/package.json +1 -1
- package/packages/provider-selector/package.json +1 -1
- package/packages/providers/package.json +1 -1
- package/packages/qdrant-skills/package.json +1 -1
- package/packages/quota-manager/package.json +1 -1
- package/packages/rate-limiter/package.json +1 -1
- package/packages/react-vite-plugin/package.json +1 -1
- package/packages/release-manager/package.json +1 -1
- package/packages/requirement-compiler/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/scheduler/package.json +1 -1
- package/packages/scheduler-adapter/package.json +1 -1
- package/packages/session/package.json +1 -1
- package/packages/session-api/package.json +1 -1
- package/packages/session-export/package.json +1 -1
- package/packages/shared-context/package.json +1 -1
- package/packages/skill-mcp-client/package.json +1 -1
- package/packages/skill-registry/package.json +1 -1
- package/packages/skills/package.json +1 -1
- package/packages/sprint-planner/package.json +1 -1
- package/packages/subscription-engine/package.json +1 -1
- package/packages/task-compiler/package.json +1 -1
- package/packages/telegram/package.json +1 -1
- package/packages/tencentdb-memory/package.json +1 -1
- package/packages/tencentdb-sync/package.json +1 -1
- package/packages/test-data-generator/package.json +1 -1
- package/packages/test-generator/package.json +1 -1
- package/packages/todo-bd-sync/package.json +1 -1
- package/packages/token-estimation/package.json +1 -1
- package/packages/token-optimizer/package.json +1 -1
- package/packages/trajectory/package.json +1 -1
- package/packages/tui/package.json +1 -1
- package/packages/types/package.json +1 -1
- package/packages/webmcp-tester/dist/index.d.ts +178 -0
- package/packages/webmcp-tester/dist/index.js +412 -0
- package/packages/webmcp-tester/package.json +27 -0
- package/packages/webmcp-tester/src/index.ts +571 -0
- package/packages/workflow-events/package.json +1 -1
- package/packages/workspace-scanner/package.json +1 -1
- package/packages/worktree/package.json +1 -1
- package/packages/write-review/package.json +1 -1
- 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/capability-registry",
|
|
3
|
-
"version": "1.1.
|
|
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",
|
|
@@ -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
|
+
```
|