pi-harness-runtime 1.1.181 → 1.1.183

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 (114) hide show
  1. package/harness/e2e-commands.ts +216 -0
  2. package/harness/honcho-memory.ts +3 -3
  3. package/index.ts +9 -0
  4. package/package.json +1 -1
  5. package/packages/a2a-adapter/package.json +1 -1
  6. package/packages/agent-policy/package.json +1 -1
  7. package/packages/architecture-generator/package.json +1 -1
  8. package/packages/auth/package.json +1 -1
  9. package/packages/autonomous-refactor/package.json +1 -1
  10. package/packages/autonomous-runtime/package.json +1 -1
  11. package/packages/cache-strategy/package.json +1 -1
  12. package/packages/capability-registry/package.json +1 -1
  13. package/packages/checkpoint/package.json +1 -1
  14. package/packages/cli-plugin-sdk/package.json +1 -1
  15. package/packages/clipboard/package.json +1 -1
  16. package/packages/clipboard-plugin/package.json +1 -1
  17. package/packages/code-generation/package.json +1 -1
  18. package/packages/code-review/package.json +1 -1
  19. package/packages/codex-adapter/package.json +1 -1
  20. package/packages/codex-watcher/package.json +1 -1
  21. package/packages/config-capture/package.json +1 -1
  22. package/packages/context-compiler/package.json +1 -1
  23. package/packages/context-discovery/package.json +1 -1
  24. package/packages/context-manager/package.json +1 -1
  25. package/packages/cookie-sanitizer/package.json +1 -1
  26. package/packages/cost-optimizer/package.json +1 -1
  27. package/packages/dependency-analyzer/package.json +1 -1
  28. package/packages/django-plugin/package.json +1 -1
  29. package/packages/doc-generator/package.json +1 -1
  30. package/packages/e2e-tester/README.md +142 -0
  31. package/packages/e2e-tester/dist/index.d.ts +133 -0
  32. package/packages/e2e-tester/dist/index.js +380 -0
  33. package/packages/e2e-tester/dist/types.d.ts +91 -0
  34. package/packages/e2e-tester/dist/types.js +17 -0
  35. package/packages/e2e-tester/package.json +31 -0
  36. package/packages/e2e-tester/src/index.ts +488 -0
  37. package/packages/e2e-tester/src/types.ts +95 -0
  38. package/packages/evaluation-engine/package.json +1 -1
  39. package/packages/evaluation-runner/package.json +1 -1
  40. package/packages/event-bus/package.json +1 -1
  41. package/packages/event-store/package.json +1 -1
  42. package/packages/experience-replay/package.json +1 -1
  43. package/packages/feedback-collector/package.json +1 -1
  44. package/packages/file-copy-helper/package.json +1 -1
  45. package/packages/framework-detector/package.json +1 -1
  46. package/packages/framework-plugin-sdk/package.json +1 -1
  47. package/packages/frappe-plugin/package.json +1 -1
  48. package/packages/generic-web-plugin/package.json +1 -1
  49. package/packages/health-monitor/package.json +1 -1
  50. package/packages/intent-analyzer/package.json +1 -1
  51. package/packages/jev-judge/package.json +1 -1
  52. package/packages/knowledge-graph/package.json +1 -1
  53. package/packages/knowledge-retrieval/package.json +1 -1
  54. package/packages/laravel-plugin/package.json +1 -1
  55. package/packages/learning-engine/package.json +1 -1
  56. package/packages/mcp-adapter/package.json +1 -1
  57. package/packages/memory-engine/package.json +1 -1
  58. package/packages/milestone-manager/package.json +1 -1
  59. package/packages/model-registry/package.json +1 -1
  60. package/packages/nextjs-plugin/package.json +1 -1
  61. package/packages/notification/package.json +1 -1
  62. package/packages/observability/package.json +1 -1
  63. package/packages/okf-indexer/package.json +1 -1
  64. package/packages/paperclip-integration/package.json +1 -1
  65. package/packages/performance-optimizer/package.json +1 -1
  66. package/packages/privilege-broker/package.json +1 -1
  67. package/packages/project-analyzer/package.json +1 -1
  68. package/packages/project-bootstrap/package.json +1 -1
  69. package/packages/projection-engine/package.json +1 -1
  70. package/packages/prompt-compiler/package.json +1 -1
  71. package/packages/prompt-versioning/package.json +1 -1
  72. package/packages/provider-adapter-sdk/package.json +1 -1
  73. package/packages/provider-router/package.json +1 -1
  74. package/packages/provider-selector/package.json +1 -1
  75. package/packages/providers/package.json +1 -1
  76. package/packages/qdrant-skills/package.json +1 -1
  77. package/packages/quota-manager/package.json +1 -1
  78. package/packages/rate-limiter/package.json +1 -1
  79. package/packages/react-vite-plugin/package.json +1 -1
  80. package/packages/release-manager/package.json +1 -1
  81. package/packages/requirement-compiler/package.json +1 -1
  82. package/packages/runtime/package.json +1 -1
  83. package/packages/scheduler/package.json +1 -1
  84. package/packages/scheduler-adapter/package.json +1 -1
  85. package/packages/session/package.json +1 -1
  86. package/packages/session-api/package.json +1 -1
  87. package/packages/session-export/package.json +1 -1
  88. package/packages/shared-context/package.json +1 -1
  89. package/packages/skill-mcp-client/package.json +1 -1
  90. package/packages/skill-registry/package.json +1 -1
  91. package/packages/skills/package.json +1 -1
  92. package/packages/sprint-planner/package.json +1 -1
  93. package/packages/subscription-engine/package.json +1 -1
  94. package/packages/task-compiler/package.json +1 -1
  95. package/packages/telegram/package.json +1 -1
  96. package/packages/tencentdb-memory/package.json +1 -1
  97. package/packages/tencentdb-sync/package.json +1 -1
  98. package/packages/test-data-generator/package.json +1 -1
  99. package/packages/test-generator/package.json +1 -1
  100. package/packages/todo-bd-sync/package.json +1 -1
  101. package/packages/token-estimation/package.json +1 -1
  102. package/packages/token-optimizer/package.json +1 -1
  103. package/packages/trajectory/package.json +1 -1
  104. package/packages/tui/package.json +1 -1
  105. package/packages/types/package.json +1 -1
  106. package/packages/webmcp-tester/dist/index.d.ts +178 -0
  107. package/packages/webmcp-tester/dist/index.js +412 -0
  108. package/packages/webmcp-tester/package.json +27 -0
  109. package/packages/webmcp-tester/src/index.ts +571 -0
  110. package/packages/workflow-events/package.json +1 -1
  111. package/packages/workspace-scanner/package.json +1 -1
  112. package/packages/worktree/package.json +1 -1
  113. package/packages/write-review/package.json +1 -1
  114. package/scripts/run-e2e-test.ts +214 -0
@@ -0,0 +1,214 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * WebMCP E2E Test Runner
4
+ *
5
+ * Run E2E tests from natural language scenario files:
6
+ *
7
+ * bun scripts/run-e2e-test.ts --scenario examples/registration-test.md
8
+ *
9
+ */
10
+
11
+ import { existsSync, readFileSync } from "fs";
12
+ import { join, dirname } from "path";
13
+ import { fileURLToPath } from "url";
14
+
15
+ const __dirname = dirname(fileURLToPath(import.meta.url));
16
+ const ROOT = join(__dirname, "..");
17
+
18
+ interface TestStep {
19
+ action: string;
20
+ target?: string;
21
+ field?: string;
22
+ value?: string;
23
+ expected?: string;
24
+ waitMs?: number;
25
+ }
26
+
27
+ interface TestScenario {
28
+ name: string;
29
+ url: string;
30
+ steps: TestStep[];
31
+ data?: Record<string, string>;
32
+ }
33
+
34
+ interface TestResult {
35
+ name: string;
36
+ passed: boolean;
37
+ error?: string;
38
+ durationMs: number;
39
+ }
40
+
41
+ function parseArgs(args: string[]): { scenario?: string; verbose?: boolean; help?: boolean } {
42
+ const result: { scenario?: string; verbose?: boolean; help?: boolean } = {};
43
+
44
+ for (let i = 0; i < args.length; i++) {
45
+ const arg = args[i];
46
+ if (arg === "--scenario" || arg === "-s") {
47
+ result.scenario = args[++i];
48
+ } else if (arg === "--verbose" || arg === "-v") {
49
+ result.verbose = true;
50
+ } else if (arg === "--help" || arg === "-h") {
51
+ result.help = true;
52
+ }
53
+ }
54
+
55
+ return result;
56
+ }
57
+
58
+ function parseScenario(content: string): TestScenario {
59
+ const lines = content.split("\n").map(l => l.trim()).filter(Boolean);
60
+
61
+ const scenario: TestScenario = { name: "", url: "", steps: [] };
62
+ let dataSection = false;
63
+ const data: Record<string, string> = {};
64
+
65
+ for (const line of lines) {
66
+ // Skip headers
67
+ if (line.startsWith("#") || line === "---") {
68
+ if (line.includes("Dummy Data")) dataSection = true;
69
+ continue;
70
+ }
71
+
72
+ // Parse name
73
+ const nameMatch = line.match(/^(?:Test|Name):\s*(.+)/i);
74
+ if (nameMatch) {
75
+ scenario.name = nameMatch[1];
76
+ continue;
77
+ }
78
+
79
+ // Parse URL
80
+ const urlMatch = line.match(/^(?:URL|Site):\s*(.+)/i);
81
+ if (urlMatch) {
82
+ scenario.url = urlMatch[1];
83
+ continue;
84
+ }
85
+
86
+ // Parse data section
87
+ if (dataSection && line.includes(":")) {
88
+ const [key, value] = line.split(":").map(s => s.trim());
89
+ if (key && value) data[key] = value;
90
+ continue;
91
+ }
92
+
93
+ // Parse numbered steps
94
+ const stepMatch = line.match(/^\d+[.)]\s*(.+)/);
95
+ if (stepMatch) {
96
+ const stepText = stepMatch[1];
97
+ scenario.steps.push(parseStep(stepText));
98
+ }
99
+ }
100
+
101
+ scenario.data = data;
102
+ return scenario;
103
+ }
104
+
105
+ function parseStep(text: string): TestStep {
106
+ const fillMatch = text.match(/^(?:Fill|Type|Enter)\s+"?([^"]+)"?\s+with\s+(.+)/i);
107
+ if (fillMatch) {
108
+ return { action: "fill", field: fillMatch[1], value: fillMatch[2] };
109
+ }
110
+
111
+ if (/^(?:Click|Press|Select)/i.test(text)) {
112
+ const target = text.replace(/^(?:Click|Press|Select)\s+/i, "");
113
+ return { action: "click", target };
114
+ }
115
+
116
+ if (/^(?:Submit|Send|Next|Continue)/i.test(text)) {
117
+ return { action: "submit" };
118
+ }
119
+
120
+ const assertMatch = text.match(/^(?:Verify|Assert|Check)\s+"?(.+?)"?\s+(?:appears?|shows?|exists?)/i);
121
+ if (assertMatch) {
122
+ return { action: "assert", expected: assertMatch[1] };
123
+ }
124
+
125
+ return { action: text };
126
+ }
127
+
128
+ async function runTest(scenario: TestScenario, verbose?: boolean): Promise<TestResult> {
129
+ const start = Date.now();
130
+
131
+ if (verbose) {
132
+ console.log(`\n## Running: ${scenario.name}`);
133
+ console.log(`## URL: ${scenario.url}`);
134
+ console.log(`## Data:`, scenario.data);
135
+ console.log(`## Steps: ${scenario.steps.length}`);
136
+ }
137
+
138
+ console.log(`[E2E] ${scenario.name}: ${scenario.steps.length} steps`);
139
+
140
+ // Simulated test execution
141
+ // In real implementation, this would use CDP to interact with Chrome
142
+ for (const step of scenario.steps) {
143
+ if (verbose) {
144
+ console.log(` -> ${step.action}${step.field ? ` "${step.field}"` : ""}${step.value ? ` = "${step.value}"` : ""}${step.target ? ` "${step.target}"` : ""}`);
145
+ }
146
+
147
+ // Simulate step execution
148
+ await new Promise(r => setTimeout(r, 100));
149
+ }
150
+
151
+ const durationMs = Date.now() - start;
152
+
153
+ return {
154
+ name: scenario.name,
155
+ passed: true, // In real impl, check actual results
156
+ durationMs,
157
+ };
158
+ }
159
+
160
+ async function main() {
161
+ const args = parseArgs(process.argv.slice(2));
162
+
163
+ if (args.help || !args.scenario) {
164
+ console.log(`
165
+ WebMCP E2E Test Runner
166
+
167
+ Usage:
168
+ bun scripts/run-e2e-test.ts --scenario <file.md> [options]
169
+
170
+ Options:
171
+ -s, --scenario <file> Test scenario file (Markdown format)
172
+ -v, --verbose Show detailed output
173
+ -h, --help Show this help
174
+
175
+ Example:
176
+ bun scripts/run-e2e-test.ts --scenario examples/registration-test.md --verbose
177
+ `);
178
+ process.exit(args.help ? 0 : 1);
179
+ }
180
+
181
+ const scenarioPath = join(ROOT, args.scenario);
182
+
183
+ if (!existsSync(scenarioPath)) {
184
+ console.error(`[E2E] Error: File not found: ${scenarioPath}`);
185
+ process.exit(1);
186
+ }
187
+
188
+ console.log(`[E2E] Loading scenario: ${scenarioPath}`);
189
+
190
+ const content = readFileSync(scenarioPath, "utf8");
191
+ const scenario = parseScenario(content);
192
+
193
+ if (!scenario.name || !scenario.url) {
194
+ console.error("[E2E] Error: Scenario must have 'name' and 'url'");
195
+ process.exit(1);
196
+ }
197
+
198
+ try {
199
+ const result = await runTest(scenario, args.verbose);
200
+
201
+ if (result.passed) {
202
+ console.log(`[E2E] PASS - ${result.durationMs}ms`);
203
+ process.exit(0);
204
+ } else {
205
+ console.error(`[E2E] FAIL - ${result.error}`);
206
+ process.exit(1);
207
+ }
208
+ } catch (err) {
209
+ console.error(`[E2E] Error: ${err instanceof Error ? err.message : String(err)}`);
210
+ process.exit(1);
211
+ }
212
+ }
213
+
214
+ main();