agentgui 1.0.74 → 1.0.76
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/.prd +132 -0
- package/CLAUDE.md +303 -0
- package/lib/machines.ts +0 -403
- package/lib/schemas.ts +0 -23
- package/package.json +1 -1
- package/static/index.html +1 -1
- package/COMPREHENSIVE_TEST_RESULTS.json +0 -149
- package/TEST_RESULTS.json +0 -139
- package/acp-launcher.js +0 -190
- package/browser-execution-test.js +0 -436
- package/browser-test-harness.js +0 -371
- package/comprehensive-browser-test.js +0 -528
- package/execute-tests.js +0 -164
- package/real-browser-test.js +0 -465
- package/run-tests.sh +0 -69
package/browser-test-harness.js
DELETED
|
@@ -1,371 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Comprehensive End-to-End Browser Test Harness
|
|
3
|
-
* Tests real-time Claude Code execution, UI rendering, and concurrent operations
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
// Test results collector
|
|
7
|
-
const testResults = {
|
|
8
|
-
phases: {},
|
|
9
|
-
screenshots: [],
|
|
10
|
-
errors: [],
|
|
11
|
-
startTime: Date.now(),
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* PHASE 1: Server Startup Verification
|
|
16
|
-
*/
|
|
17
|
-
async function testPhase1_ServerStartup() {
|
|
18
|
-
console.log('\n========== PHASE 1: SERVER STARTUP VERIFICATION ==========');
|
|
19
|
-
|
|
20
|
-
try {
|
|
21
|
-
const response = await fetch('http://localhost:3000', {
|
|
22
|
-
method: 'HEAD',
|
|
23
|
-
headers: { 'Accept': '*/*' }
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
const isRunning = response.status === 200 || response.status === 302;
|
|
27
|
-
console.log(`Server status: ${response.status}`);
|
|
28
|
-
console.log(`Server running: ${isRunning ? '✓' : '✗'}`);
|
|
29
|
-
|
|
30
|
-
testResults.phases['phase1_server'] = {
|
|
31
|
-
status: isRunning ? 'PASS' : 'FAIL',
|
|
32
|
-
message: `Server responding with status ${response.status}`,
|
|
33
|
-
timestamp: new Date().toISOString()
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
return isRunning;
|
|
37
|
-
} catch (error) {
|
|
38
|
-
console.error('Server startup test failed:', error.message);
|
|
39
|
-
testResults.phases['phase1_server'] = {
|
|
40
|
-
status: 'FAIL',
|
|
41
|
-
error: error.message,
|
|
42
|
-
timestamp: new Date().toISOString()
|
|
43
|
-
};
|
|
44
|
-
testResults.errors.push({ phase: 1, error: error.message });
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* PHASE 2: UI Verification
|
|
51
|
-
*/
|
|
52
|
-
async function testPhase2_UIVerification() {
|
|
53
|
-
console.log('\n========== PHASE 2: UI VERIFICATION ==========');
|
|
54
|
-
|
|
55
|
-
try {
|
|
56
|
-
// Check for RippleUI components
|
|
57
|
-
const components = {
|
|
58
|
-
metadataPanel: document.querySelector('[data-component="agent-metadata"]'),
|
|
59
|
-
progressSection: document.querySelector('[data-component="execution-progress"]'),
|
|
60
|
-
outputArea: document.querySelector('[data-component="output-display"]'),
|
|
61
|
-
errorPanel: document.querySelector('[data-component="error-handler"]'),
|
|
62
|
-
themeToggle: document.querySelector('[data-component="theme-toggle"]')
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
const allComponentsVisible = Object.values(components).every(comp => comp !== null);
|
|
66
|
-
|
|
67
|
-
console.log('Component Check:');
|
|
68
|
-
for (const [name, comp] of Object.entries(components)) {
|
|
69
|
-
console.log(` ${name}: ${comp ? '✓' : '✗'}`);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
testResults.phases['phase2_ui'] = {
|
|
73
|
-
status: allComponentsVisible ? 'PASS' : 'FAIL',
|
|
74
|
-
components: Object.fromEntries(
|
|
75
|
-
Object.entries(components).map(([k, v]) => [k, v ? 'visible' : 'missing'])
|
|
76
|
-
),
|
|
77
|
-
timestamp: new Date().toISOString()
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
return allComponentsVisible;
|
|
81
|
-
} catch (error) {
|
|
82
|
-
console.error('UI verification test failed:', error.message);
|
|
83
|
-
testResults.phases['phase2_ui'] = {
|
|
84
|
-
status: 'FAIL',
|
|
85
|
-
error: error.message,
|
|
86
|
-
timestamp: new Date().toISOString()
|
|
87
|
-
};
|
|
88
|
-
testResults.errors.push({ phase: 2, error: error.message });
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* PHASE 3: Repository Setup Verification
|
|
95
|
-
*/
|
|
96
|
-
async function testPhase3_RepositorySetup() {
|
|
97
|
-
console.log('\n========== PHASE 3: REPOSITORY SETUP VERIFICATION ==========');
|
|
98
|
-
|
|
99
|
-
try {
|
|
100
|
-
// Check if repos exist using file system
|
|
101
|
-
// Note: This is a simulated check since we can't access filesystem directly from browser
|
|
102
|
-
// The actual repos will be verified when we try to execute Claude Code
|
|
103
|
-
|
|
104
|
-
const repos = {
|
|
105
|
-
lodash: '/tmp/test-repos/lodash',
|
|
106
|
-
chalk: '/tmp/test-repos/chalk'
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
console.log('Expected repositories:');
|
|
110
|
-
for (const [name, path] of Object.entries(repos)) {
|
|
111
|
-
console.log(` ${name}: ${path}`);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
testResults.phases['phase3_repos'] = {
|
|
115
|
-
status: 'PENDING',
|
|
116
|
-
message: 'Repository verification will occur during execution',
|
|
117
|
-
repos,
|
|
118
|
-
timestamp: new Date().toISOString()
|
|
119
|
-
};
|
|
120
|
-
|
|
121
|
-
return true; // Will be verified during execution
|
|
122
|
-
} catch (error) {
|
|
123
|
-
console.error('Repository setup test failed:', error.message);
|
|
124
|
-
testResults.phases['phase3_repos'] = {
|
|
125
|
-
status: 'FAIL',
|
|
126
|
-
error: error.message,
|
|
127
|
-
timestamp: new Date().toISOString()
|
|
128
|
-
};
|
|
129
|
-
testResults.errors.push({ phase: 3, error: error.message });
|
|
130
|
-
return false;
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* PHASE 4: Console Error Verification
|
|
136
|
-
*/
|
|
137
|
-
async function testPhase4_ConsoleErrors() {
|
|
138
|
-
console.log('\n========== PHASE 4: CONSOLE ERROR CHECKING ==========');
|
|
139
|
-
|
|
140
|
-
try {
|
|
141
|
-
// Collect console logs
|
|
142
|
-
const originalError = console.error;
|
|
143
|
-
const originalWarn = console.warn;
|
|
144
|
-
|
|
145
|
-
let errorCount = 0;
|
|
146
|
-
let warnCount = 0;
|
|
147
|
-
const capturedErrors = [];
|
|
148
|
-
|
|
149
|
-
console.error = function(...args) {
|
|
150
|
-
errorCount++;
|
|
151
|
-
capturedErrors.push({ level: 'error', message: args.join(' ') });
|
|
152
|
-
originalError.apply(console, args);
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
console.warn = function(...args) {
|
|
156
|
-
warnCount++;
|
|
157
|
-
originalWarn.apply(console, args);
|
|
158
|
-
};
|
|
159
|
-
|
|
160
|
-
// Check for uncaught errors in window
|
|
161
|
-
const uncaughtErrors = window.__uncaughtErrors || [];
|
|
162
|
-
|
|
163
|
-
console.log(`Captured errors: ${errorCount}`);
|
|
164
|
-
console.log(`Captured warnings: ${warnCount}`);
|
|
165
|
-
console.log(`Uncaught errors: ${uncaughtErrors.length}`);
|
|
166
|
-
|
|
167
|
-
const isClean = errorCount === 0 && uncaughtErrors.length === 0;
|
|
168
|
-
|
|
169
|
-
testResults.phases['phase4_console'] = {
|
|
170
|
-
status: isClean ? 'PASS' : 'WARN',
|
|
171
|
-
errorCount,
|
|
172
|
-
warnCount,
|
|
173
|
-
uncaughtErrorsCount: uncaughtErrors.length,
|
|
174
|
-
timestamp: new Date().toISOString()
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
return isClean;
|
|
178
|
-
} catch (error) {
|
|
179
|
-
console.error('Console error test failed:', error.message);
|
|
180
|
-
testResults.phases['phase4_console'] = {
|
|
181
|
-
status: 'FAIL',
|
|
182
|
-
error: error.message,
|
|
183
|
-
timestamp: new Date().toISOString()
|
|
184
|
-
};
|
|
185
|
-
testResults.errors.push({ phase: 4, error: error.message });
|
|
186
|
-
return false;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* PHASE 5: Network Status Check
|
|
192
|
-
*/
|
|
193
|
-
async function testPhase5_NetworkStatus() {
|
|
194
|
-
console.log('\n========== PHASE 5: NETWORK STATUS CHECK ==========');
|
|
195
|
-
|
|
196
|
-
try {
|
|
197
|
-
// Check API endpoints
|
|
198
|
-
const endpoints = [
|
|
199
|
-
'/gm/api/conversations',
|
|
200
|
-
'/gm/api/conversations',
|
|
201
|
-
];
|
|
202
|
-
|
|
203
|
-
let successCount = 0;
|
|
204
|
-
const results = {};
|
|
205
|
-
|
|
206
|
-
for (const endpoint of endpoints) {
|
|
207
|
-
try {
|
|
208
|
-
const response = await fetch(`http://localhost:3000${endpoint}`, {
|
|
209
|
-
method: 'GET',
|
|
210
|
-
headers: { 'Accept': 'application/json' }
|
|
211
|
-
});
|
|
212
|
-
results[endpoint] = response.status;
|
|
213
|
-
if (response.status === 200 || response.status === 201) {
|
|
214
|
-
successCount++;
|
|
215
|
-
}
|
|
216
|
-
} catch (error) {
|
|
217
|
-
results[endpoint] = `ERROR: ${error.message}`;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const isHealthy = successCount === endpoints.length;
|
|
222
|
-
|
|
223
|
-
console.log('API Endpoint Status:');
|
|
224
|
-
for (const [endpoint, status] of Object.entries(results)) {
|
|
225
|
-
console.log(` ${endpoint}: ${status}`);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
testResults.phases['phase5_network'] = {
|
|
229
|
-
status: isHealthy ? 'PASS' : 'WARN',
|
|
230
|
-
endpoints: results,
|
|
231
|
-
timestamp: new Date().toISOString()
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
return isHealthy;
|
|
235
|
-
} catch (error) {
|
|
236
|
-
console.error('Network status test failed:', error.message);
|
|
237
|
-
testResults.phases['phase5_network'] = {
|
|
238
|
-
status: 'FAIL',
|
|
239
|
-
error: error.message,
|
|
240
|
-
timestamp: new Date().toISOString()
|
|
241
|
-
};
|
|
242
|
-
testResults.errors.push({ phase: 5, error: error.message });
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* PHASE 6: Dark Mode Toggle Test
|
|
249
|
-
*/
|
|
250
|
-
async function testPhase6_DarkModeToggle() {
|
|
251
|
-
console.log('\n========== PHASE 6: DARK MODE TOGGLE TEST ==========');
|
|
252
|
-
|
|
253
|
-
try {
|
|
254
|
-
const themeToggle = document.querySelector('[data-component="theme-toggle"]');
|
|
255
|
-
|
|
256
|
-
if (!themeToggle) {
|
|
257
|
-
throw new Error('Theme toggle button not found');
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
// Get initial theme
|
|
261
|
-
const initialTheme = document.documentElement.getAttribute('data-theme') || 'light';
|
|
262
|
-
console.log(`Initial theme: ${initialTheme}`);
|
|
263
|
-
|
|
264
|
-
// Click toggle
|
|
265
|
-
themeToggle.click();
|
|
266
|
-
await new Promise(resolve => setTimeout(resolve, 200)); // Wait for animation
|
|
267
|
-
|
|
268
|
-
const afterToggle = document.documentElement.getAttribute('data-theme') || 'light';
|
|
269
|
-
console.log(`After toggle: ${afterToggle}`);
|
|
270
|
-
|
|
271
|
-
// Verify change
|
|
272
|
-
const themeChanged = initialTheme !== afterToggle;
|
|
273
|
-
|
|
274
|
-
// Click back
|
|
275
|
-
themeToggle.click();
|
|
276
|
-
await new Promise(resolve => setTimeout(resolve, 200));
|
|
277
|
-
|
|
278
|
-
const backToOriginal = document.documentElement.getAttribute('data-theme') === initialTheme;
|
|
279
|
-
console.log(`Back to original: ${backToOriginal}`);
|
|
280
|
-
|
|
281
|
-
const success = themeChanged && backToOriginal;
|
|
282
|
-
|
|
283
|
-
testResults.phases['phase6_darkmode'] = {
|
|
284
|
-
status: success ? 'PASS' : 'FAIL',
|
|
285
|
-
initialTheme,
|
|
286
|
-
afterToggle,
|
|
287
|
-
backToOriginal,
|
|
288
|
-
timestamp: new Date().toISOString()
|
|
289
|
-
};
|
|
290
|
-
|
|
291
|
-
return success;
|
|
292
|
-
} catch (error) {
|
|
293
|
-
console.error('Dark mode toggle test failed:', error.message);
|
|
294
|
-
testResults.phases['phase6_darkmode'] = {
|
|
295
|
-
status: 'FAIL',
|
|
296
|
-
error: error.message,
|
|
297
|
-
timestamp: new Date().toISOString()
|
|
298
|
-
};
|
|
299
|
-
testResults.errors.push({ phase: 6, error: error.message });
|
|
300
|
-
return false;
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
/**
|
|
305
|
-
* Execute all tests in sequence
|
|
306
|
-
*/
|
|
307
|
-
async function runAllTests() {
|
|
308
|
-
console.log('====================================================');
|
|
309
|
-
console.log('STARTING END-TO-END BROWSER TEST SUITE');
|
|
310
|
-
console.log('Time: ' + new Date().toISOString());
|
|
311
|
-
console.log('====================================================');
|
|
312
|
-
|
|
313
|
-
const tests = [
|
|
314
|
-
{ name: 'Phase 1: Server Startup', fn: testPhase1_ServerStartup },
|
|
315
|
-
{ name: 'Phase 2: UI Verification', fn: testPhase2_UIVerification },
|
|
316
|
-
{ name: 'Phase 3: Repository Setup', fn: testPhase3_RepositorySetup },
|
|
317
|
-
{ name: 'Phase 4: Console Errors', fn: testPhase4_ConsoleErrors },
|
|
318
|
-
{ name: 'Phase 5: Network Status', fn: testPhase5_NetworkStatus },
|
|
319
|
-
{ name: 'Phase 6: Dark Mode', fn: testPhase6_DarkModeToggle },
|
|
320
|
-
];
|
|
321
|
-
|
|
322
|
-
const results = [];
|
|
323
|
-
|
|
324
|
-
for (const test of tests) {
|
|
325
|
-
try {
|
|
326
|
-
console.log(`\nRunning: ${test.name}`);
|
|
327
|
-
const result = await test.fn();
|
|
328
|
-
results.push({ name: test.name, result });
|
|
329
|
-
} catch (error) {
|
|
330
|
-
console.error(`Test failed: ${test.name}`, error);
|
|
331
|
-
results.push({ name: test.name, result: false, error });
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
// Summary
|
|
336
|
-
console.log('\n====================================================');
|
|
337
|
-
console.log('TEST SUMMARY');
|
|
338
|
-
console.log('====================================================');
|
|
339
|
-
|
|
340
|
-
let passCount = 0;
|
|
341
|
-
for (const { name, result } of results) {
|
|
342
|
-
const status = result ? '✓ PASS' : '✗ FAIL';
|
|
343
|
-
console.log(`${status}: ${name}`);
|
|
344
|
-
if (result) passCount++;
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
console.log(`\nTotal: ${passCount}/${results.length} passed`);
|
|
348
|
-
console.log(`Duration: ${(Date.now() - testResults.startTime) / 1000}s`);
|
|
349
|
-
console.log(`Errors: ${testResults.errors.length}`);
|
|
350
|
-
|
|
351
|
-
if (testResults.errors.length > 0) {
|
|
352
|
-
console.log('\nErrors:');
|
|
353
|
-
testResults.errors.forEach((err, i) => {
|
|
354
|
-
console.log(` ${i + 1}. Phase ${err.phase}: ${err.error}`);
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// Save results to window for retrieval
|
|
359
|
-
window.__testResults = testResults;
|
|
360
|
-
window.__testSummary = { passCount, totalTests: results.length, results };
|
|
361
|
-
|
|
362
|
-
console.log('\n✓ Test suite complete. Results saved to window.__testResults');
|
|
363
|
-
|
|
364
|
-
return testResults;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Export for use
|
|
368
|
-
window.runAllTests = runAllTests;
|
|
369
|
-
window.testResults = testResults;
|
|
370
|
-
|
|
371
|
-
console.log('✓ Test harness loaded. Call window.runAllTests() to start tests.');
|