centaurus-cli 2.5.2 ā 2.5.3
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/AUTH_FLOW.md +138 -0
- package/CONFIG_GUIDE.md +249 -0
- package/dist/config/models.d.ts +1 -1
- package/dist/config/models.d.ts.map +1 -1
- package/dist/config/models.js +2 -0
- package/dist/config/models.js.map +1 -1
- package/dist/ui/components/App.d.ts.map +1 -1
- package/dist/ui/components/App.js +104 -62
- package/dist/ui/components/App.js.map +1 -1
- package/dist/ui/components/FontRecommendation.d.ts +1 -0
- package/dist/ui/components/FontRecommendation.d.ts.map +1 -0
- package/dist/ui/components/FontRecommendation.js +1 -0
- package/dist/ui/components/FontRecommendation.js.map +1 -0
- package/dist/ui/components/InputBox.d.ts.map +1 -1
- package/dist/ui/components/InputBox.js +3 -2
- package/dist/ui/components/InputBox.js.map +1 -1
- package/dist/ui/components/MarkdownRenderer.d.ts.map +1 -1
- package/dist/ui/components/MarkdownRenderer.js +34 -9
- package/dist/ui/components/MarkdownRenderer.js.map +1 -1
- package/dist/ui/components/MessageDisplay.js +2 -2
- package/dist/ui/components/StreamingMessageDisplay.d.ts.map +1 -1
- package/dist/ui/components/StreamingMessageDisplay.js +3 -3
- package/dist/ui/components/StreamingMessageDisplay.js.map +1 -1
- package/dist/ui/components/ThinkingDisplay.d.ts +13 -0
- package/dist/ui/components/ThinkingDisplay.d.ts.map +1 -0
- package/dist/ui/components/ThinkingDisplay.js +41 -0
- package/dist/ui/components/ThinkingDisplay.js.map +1 -0
- package/dist/utils/version-checker.d.ts.map +1 -1
- package/dist/utils/version-checker.js +3 -31
- package/dist/utils/version-checker.js.map +1 -1
- package/package.json +5 -5
- package/dist/ai/provider-factory.d.ts +0 -6
- package/dist/ai/provider-factory.d.ts.map +0 -1
- package/dist/ai/provider-factory.js +0 -27
- package/dist/ai/provider-factory.js.map +0 -1
- package/dist/ai/providers/base.d.ts +0 -25
- package/dist/ai/providers/base.d.ts.map +0 -1
- package/dist/ai/providers/base.js +0 -9
- package/dist/ai/providers/base.js.map +0 -1
- package/dist/ai/providers/gemini.d.ts +0 -34
- package/dist/ai/providers/gemini.d.ts.map +0 -1
- package/dist/ai/providers/gemini.js +0 -146
- package/dist/ai/providers/gemini.js.map +0 -1
- package/dist/commands/view-duplication-logs.d.ts +0 -5
- package/dist/commands/view-duplication-logs.d.ts.map +0 -1
- package/dist/commands/view-duplication-logs.js +0 -14
- package/dist/commands/view-duplication-logs.js.map +0 -1
- package/dist/context/__tests__/command-detector.test.d.ts +0 -14
- package/dist/context/__tests__/command-detector.test.d.ts.map +0 -1
- package/dist/context/__tests__/command-detector.test.js +0 -318
- package/dist/context/__tests__/command-detector.test.js.map +0 -1
- package/dist/context/__tests__/context-manager.test.d.ts +0 -16
- package/dist/context/__tests__/context-manager.test.d.ts.map +0 -1
- package/dist/context/__tests__/context-manager.test.js +0 -375
- package/dist/context/__tests__/context-manager.test.js.map +0 -1
- package/dist/context/__tests__/error-handling.test.d.ts +0 -15
- package/dist/context/__tests__/error-handling.test.d.ts.map +0 -1
- package/dist/context/__tests__/error-handling.test.js +0 -447
- package/dist/context/__tests__/error-handling.test.js.map +0 -1
- package/dist/context/handlers/__tests__/docker-handler.test.d.ts +0 -13
- package/dist/context/handlers/__tests__/docker-handler.test.d.ts.map +0 -1
- package/dist/context/handlers/__tests__/docker-handler.test.js +0 -285
- package/dist/context/handlers/__tests__/docker-handler.test.js.map +0 -1
- package/dist/context/handlers/__tests__/ssh-handler.test.d.ts +0 -13
- package/dist/context/handlers/__tests__/ssh-handler.test.d.ts.map +0 -1
- package/dist/context/handlers/__tests__/ssh-handler.test.js +0 -251
- package/dist/context/handlers/__tests__/ssh-handler.test.js.map +0 -1
- package/dist/context/handlers/__tests__/wsl-handler.test.d.ts +0 -7
- package/dist/context/handlers/__tests__/wsl-handler.test.d.ts.map +0 -1
- package/dist/context/handlers/__tests__/wsl-handler.test.js +0 -331
- package/dist/context/handlers/__tests__/wsl-handler.test.js.map +0 -1
- package/dist/index-custom.d.ts +0 -3
- package/dist/index-custom.d.ts.map +0 -1
- package/dist/index-custom.js +0 -65
- package/dist/index-custom.js.map +0 -1
- package/dist/prompts/system-prompt.d.ts +0 -47
- package/dist/prompts/system-prompt.d.ts.map +0 -1
- package/dist/prompts/system-prompt.js +0 -377
- package/dist/prompts/system-prompt.js.map +0 -1
- package/dist/providers/GoogleProvider.d.ts +0 -26
- package/dist/providers/GoogleProvider.d.ts.map +0 -1
- package/dist/providers/GoogleProvider.js +0 -313
- package/dist/providers/GoogleProvider.js.map +0 -1
- package/dist/providers/Provider.d.ts +0 -114
- package/dist/providers/Provider.d.ts.map +0 -1
- package/dist/providers/Provider.js +0 -44
- package/dist/providers/Provider.js.map +0 -1
- package/dist/services/__tests__/ai-context-injector.test.d.ts +0 -15
- package/dist/services/__tests__/ai-context-injector.test.d.ts.map +0 -1
- package/dist/services/__tests__/ai-context-injector.test.js +0 -326
- package/dist/services/__tests__/ai-context-injector.test.js.map +0 -1
- package/dist/src/context/types.js +0 -27
- package/dist/src/services/ai-context-injector.js +0 -96
- package/dist/src/services/ai-service-client.js +0 -270
- package/dist/src/services/api-client.js +0 -349
- package/dist/src/tools/types.js +0 -1
- package/dist/src/types/index.js +0 -1
- package/dist/test/context/types.js +0 -27
- package/dist/test/services/__tests__/ai-context-injector.test.js +0 -325
- package/dist/test/services/ai-context-injector.js +0 -96
- package/dist/test/services/ai-service-client.js +0 -270
- package/dist/test/services/api-client.js +0 -349
- package/dist/test/tools/types.js +0 -1
- package/dist/test/types/index.js +0 -1
- package/dist/test-ai-context-injector.js +0 -97
- package/dist/tests/automated-verification.d.ts +0 -27
- package/dist/tests/automated-verification.d.ts.map +0 -1
- package/dist/tests/automated-verification.js +0 -359
- package/dist/tests/automated-verification.js.map +0 -1
- package/dist/tests/integration-tests.d.ts +0 -50
- package/dist/tests/integration-tests.d.ts.map +0 -1
- package/dist/tests/integration-tests.js +0 -648
- package/dist/tests/integration-tests.js.map +0 -1
- package/dist/tools/file-ops-test.d.ts +0 -6
- package/dist/tools/file-ops-test.d.ts.map +0 -1
- package/dist/tools/file-ops-test.js +0 -197
- package/dist/tools/file-ops-test.js.map +0 -1
- package/dist/ui/DisplayHistory.d.ts +0 -53
- package/dist/ui/DisplayHistory.d.ts.map +0 -1
- package/dist/ui/DisplayHistory.js +0 -82
- package/dist/ui/DisplayHistory.js.map +0 -1
- package/dist/ui/clack-ui.d.ts +0 -83
- package/dist/ui/clack-ui.d.ts.map +0 -1
- package/dist/ui/clack-ui.js +0 -304
- package/dist/ui/clack-ui.js.map +0 -1
- package/dist/ui/components/DisplayItemRenderer.d.ts +0 -18
- package/dist/ui/components/DisplayItemRenderer.d.ts.map +0 -1
- package/dist/ui/components/DisplayItemRenderer.js +0 -53
- package/dist/ui/components/DisplayItemRenderer.js.map +0 -1
- package/dist/ui/components/DynamicMessage.d.ts +0 -13
- package/dist/ui/components/DynamicMessage.d.ts.map +0 -1
- package/dist/ui/components/DynamicMessage.js +0 -27
- package/dist/ui/components/DynamicMessage.js.map +0 -1
- package/dist/ui/components/FileViewerScreen.d.ts +0 -14
- package/dist/ui/components/FileViewerScreen.d.ts.map +0 -1
- package/dist/ui/components/FileViewerScreen.js +0 -74
- package/dist/ui/components/FileViewerScreen.js.map +0 -1
- package/dist/ui/components/ScrollableContent.d.ts +0 -7
- package/dist/ui/components/ScrollableContent.d.ts.map +0 -1
- package/dist/ui/components/ScrollableContent.js +0 -6
- package/dist/ui/components/ScrollableContent.js.map +0 -1
- package/dist/ui/components/ScrollableMessageList.d.ts +0 -10
- package/dist/ui/components/ScrollableMessageList.d.ts.map +0 -1
- package/dist/ui/components/ScrollableMessageList.js +0 -133
- package/dist/ui/components/ScrollableMessageList.js.map +0 -1
- package/dist/ui/components/ScrollableScreen.d.ts +0 -9
- package/dist/ui/components/ScrollableScreen.d.ts.map +0 -1
- package/dist/ui/components/ScrollableScreen.js +0 -22
- package/dist/ui/components/ScrollableScreen.js.map +0 -1
- package/dist/ui/components/StaticMessageHistory.d.ts +0 -14
- package/dist/ui/components/StaticMessageHistory.d.ts.map +0 -1
- package/dist/ui/components/StaticMessageHistory.js +0 -19
- package/dist/ui/components/StaticMessageHistory.js.map +0 -1
- package/dist/ui/components/code-block.d.ts +0 -10
- package/dist/ui/components/code-block.d.ts.map +0 -1
- package/dist/ui/components/code-block.js +0 -74
- package/dist/ui/components/code-block.js.map +0 -1
- package/dist/ui/components/confirm-prompt.d.ts +0 -12
- package/dist/ui/components/confirm-prompt.d.ts.map +0 -1
- package/dist/ui/components/confirm-prompt.js +0 -104
- package/dist/ui/components/confirm-prompt.js.map +0 -1
- package/dist/ui/components/diff-viewer.d.ts +0 -9
- package/dist/ui/components/diff-viewer.d.ts.map +0 -1
- package/dist/ui/components/diff-viewer.js +0 -57
- package/dist/ui/components/diff-viewer.js.map +0 -1
- package/dist/ui/components/input-box.d.ts +0 -18
- package/dist/ui/components/input-box.d.ts.map +0 -1
- package/dist/ui/components/input-box.js +0 -157
- package/dist/ui/components/input-box.js.map +0 -1
- package/dist/ui/components/keyboard-help.d.ts +0 -7
- package/dist/ui/components/keyboard-help.d.ts.map +0 -1
- package/dist/ui/components/keyboard-help.js +0 -43
- package/dist/ui/components/keyboard-help.js.map +0 -1
- package/dist/ui/components/loading-indicator.d.ts +0 -3
- package/dist/ui/components/loading-indicator.d.ts.map +0 -1
- package/dist/ui/components/loading-indicator.js +0 -42
- package/dist/ui/components/loading-indicator.js.map +0 -1
- package/dist/ui/components/message-display.d.ts +0 -7
- package/dist/ui/components/message-display.d.ts.map +0 -1
- package/dist/ui/components/message-display.js +0 -104
- package/dist/ui/components/message-display.js.map +0 -1
- package/dist/ui/components/misc.d.ts +0 -28
- package/dist/ui/components/misc.d.ts.map +0 -1
- package/dist/ui/components/misc.js +0 -128
- package/dist/ui/components/misc.js.map +0 -1
- package/dist/ui/components/select-prompt.d.ts +0 -13
- package/dist/ui/components/select-prompt.d.ts.map +0 -1
- package/dist/ui/components/select-prompt.js +0 -42
- package/dist/ui/components/select-prompt.js.map +0 -1
- package/dist/ui/components/status-bar.d.ts +0 -11
- package/dist/ui/components/status-bar.d.ts.map +0 -1
- package/dist/ui/components/status-bar.js +0 -47
- package/dist/ui/components/status-bar.js.map +0 -1
- package/dist/ui/components/tool-execution.d.ts +0 -3
- package/dist/ui/components/tool-execution.d.ts.map +0 -1
- package/dist/ui/components/tool-execution.js +0 -374
- package/dist/ui/components/tool-execution.js.map +0 -1
- package/dist/ui/components/tool-result.d.ts +0 -11
- package/dist/ui/components/tool-result.d.ts.map +0 -1
- package/dist/ui/components/tool-result.js +0 -58
- package/dist/ui/components/tool-result.js.map +0 -1
- package/dist/ui/components/welcome-banner.d.ts +0 -3
- package/dist/ui/components/welcome-banner.d.ts.map +0 -1
- package/dist/ui/components/welcome-banner.js +0 -46
- package/dist/ui/components/welcome-banner.js.map +0 -1
- package/dist/ui/hooks/useDisplayHistory.d.ts +0 -13
- package/dist/ui/hooks/useDisplayHistory.d.ts.map +0 -1
- package/dist/ui/hooks/useDisplayHistory.js +0 -45
- package/dist/ui/hooks/useDisplayHistory.js.map +0 -1
- package/dist/ui/render-engine.d.ts +0 -69
- package/dist/ui/render-engine.d.ts.map +0 -1
- package/dist/ui/render-engine.js +0 -197
- package/dist/ui/render-engine.js.map +0 -1
- package/dist/ui/terminal/TerminalRenderer.d.ts +0 -84
- package/dist/ui/terminal/TerminalRenderer.d.ts.map +0 -1
- package/dist/ui/terminal/TerminalRenderer.js +0 -154
- package/dist/ui/terminal/TerminalRenderer.js.map +0 -1
- package/dist/ui/terminal/TerminalUI.d.ts +0 -139
- package/dist/ui/terminal/TerminalUI.d.ts.map +0 -1
- package/dist/ui/terminal/TerminalUI.js +0 -430
- package/dist/ui/terminal/TerminalUI.js.map +0 -1
- package/dist/ui/terminal/VirtualChatBuffer.d.ts +0 -32
- package/dist/ui/terminal/VirtualChatBuffer.d.ts.map +0 -1
- package/dist/ui/terminal/VirtualChatBuffer.js +0 -37
- package/dist/ui/terminal/VirtualChatBuffer.js.map +0 -1
- package/dist/ui/terminal-kit-base.d.ts +0 -117
- package/dist/ui/terminal-kit-base.d.ts.map +0 -1
- package/dist/ui/terminal-kit-base.js +0 -188
- package/dist/ui/terminal-kit-base.js.map +0 -1
- package/dist/ui/utils/duplication-detector.d.ts +0 -32
- package/dist/ui/utils/duplication-detector.d.ts.map +0 -1
- package/dist/ui/utils/duplication-detector.js +0 -227
- package/dist/ui/utils/duplication-detector.js.map +0 -1
- package/dist/ui/utils/duplication-logger.d.ts +0 -21
- package/dist/ui/utils/duplication-logger.d.ts.map +0 -1
- package/dist/ui/utils/duplication-logger.js +0 -85
- package/dist/ui/utils/duplication-logger.js.map +0 -1
- package/dist/ui/utils/terminal-scanner.d.ts +0 -19
- package/dist/ui/utils/terminal-scanner.d.ts.map +0 -1
- package/dist/ui/utils/terminal-scanner.js +0 -217
- package/dist/ui/utils/terminal-scanner.js.map +0 -1
- package/dist/version.d.ts +0 -2
- package/dist/version.d.ts.map +0 -1
- package/dist/version.js +0 -3
- package/dist/version.js.map +0 -1
- package/scripts/generate-version.js +0 -25
|
@@ -1,648 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration Tests for UI Rendering Refactor
|
|
3
|
-
*
|
|
4
|
-
* Comprehensive tests for:
|
|
5
|
-
* - Complete conversation flows
|
|
6
|
-
* - Approval and modal flows
|
|
7
|
-
* - Error scenarios
|
|
8
|
-
* - Performance testing
|
|
9
|
-
*/
|
|
10
|
-
import { CentaurusCLI } from '../cli-adapter.js';
|
|
11
|
-
import * as fs from 'fs';
|
|
12
|
-
import * as path from 'path';
|
|
13
|
-
class IntegrationTestRunner {
|
|
14
|
-
results = [];
|
|
15
|
-
cli;
|
|
16
|
-
testDir;
|
|
17
|
-
conversationHistory = [];
|
|
18
|
-
streamingMessages = new Map();
|
|
19
|
-
toolExecutions = new Map();
|
|
20
|
-
duplicateDetector = new Map();
|
|
21
|
-
constructor() {
|
|
22
|
-
this.cli = new CentaurusCLI();
|
|
23
|
-
this.testDir = path.join(process.cwd(), 'test-integration-temp');
|
|
24
|
-
}
|
|
25
|
-
async setup() {
|
|
26
|
-
console.log('š§ Setting up integration test environment...\n');
|
|
27
|
-
// Create test directory
|
|
28
|
-
if (!fs.existsSync(this.testDir)) {
|
|
29
|
-
fs.mkdirSync(this.testDir, { recursive: true });
|
|
30
|
-
}
|
|
31
|
-
// Initialize CLI
|
|
32
|
-
await this.cli.initialize();
|
|
33
|
-
// Setup callbacks to track messages and detect duplicates
|
|
34
|
-
this.setupCallbacks();
|
|
35
|
-
console.log('ā
Integration test environment ready\n');
|
|
36
|
-
}
|
|
37
|
-
setupCallbacks() {
|
|
38
|
-
// Track streaming messages
|
|
39
|
-
this.cli.setOnStreamStart((messageId) => {
|
|
40
|
-
this.streamingMessages.set(messageId, '');
|
|
41
|
-
this.trackMessage('stream-start', messageId);
|
|
42
|
-
});
|
|
43
|
-
this.cli.setOnStreamChunk((messageId, chunk) => {
|
|
44
|
-
const current = this.streamingMessages.get(messageId) || '';
|
|
45
|
-
this.streamingMessages.set(messageId, current + chunk);
|
|
46
|
-
});
|
|
47
|
-
this.cli.setOnStreamComplete((messageId) => {
|
|
48
|
-
const content = this.streamingMessages.get(messageId) || '';
|
|
49
|
-
this.conversationHistory.push({
|
|
50
|
-
role: 'assistant',
|
|
51
|
-
content
|
|
52
|
-
});
|
|
53
|
-
this.streamingMessages.delete(messageId);
|
|
54
|
-
this.trackMessage('stream-complete', messageId);
|
|
55
|
-
});
|
|
56
|
-
// Track tool executions
|
|
57
|
-
this.cli.setOnToolExecutionUpdate((update) => {
|
|
58
|
-
this.toolExecutions.set(update.id || update.toolName, update);
|
|
59
|
-
this.trackMessage('tool-execution', update.id || update.toolName);
|
|
60
|
-
if (update.status === 'completed' || update.status === 'error') {
|
|
61
|
-
this.conversationHistory.push({
|
|
62
|
-
role: 'tool',
|
|
63
|
-
content: update.result || update.error || '',
|
|
64
|
-
toolExecution: update
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
// Track responses
|
|
69
|
-
this.cli.setOnResponseCallback((message) => {
|
|
70
|
-
this.conversationHistory.push({
|
|
71
|
-
role: 'system',
|
|
72
|
-
content: message
|
|
73
|
-
});
|
|
74
|
-
this.trackMessage('system-response', message.substring(0, 50));
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
trackMessage(type, identifier) {
|
|
78
|
-
const key = `${type}:${identifier}`;
|
|
79
|
-
const count = this.duplicateDetector.get(key) || 0;
|
|
80
|
-
this.duplicateDetector.set(key, count + 1);
|
|
81
|
-
}
|
|
82
|
-
checkForDuplicates() {
|
|
83
|
-
const duplicates = [];
|
|
84
|
-
this.duplicateDetector.forEach((count, key) => {
|
|
85
|
-
if (count > 1) {
|
|
86
|
-
duplicates.push(`${key} appeared ${count} times`);
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
return duplicates;
|
|
90
|
-
}
|
|
91
|
-
async cleanup() {
|
|
92
|
-
console.log('\nš§¹ Cleaning up integration test environment...');
|
|
93
|
-
if (fs.existsSync(this.testDir)) {
|
|
94
|
-
fs.rmSync(this.testDir, { recursive: true, force: true });
|
|
95
|
-
}
|
|
96
|
-
console.log('ā
Cleanup complete\n');
|
|
97
|
-
}
|
|
98
|
-
async runTest(name, testFn) {
|
|
99
|
-
const startTime = Date.now();
|
|
100
|
-
// Reset duplicate detector for each test
|
|
101
|
-
this.duplicateDetector.clear();
|
|
102
|
-
try {
|
|
103
|
-
await testFn();
|
|
104
|
-
// Check for duplicates after test
|
|
105
|
-
const duplicates = this.checkForDuplicates();
|
|
106
|
-
if (duplicates.length > 0) {
|
|
107
|
-
throw new Error(`Duplicates detected: ${duplicates.join(', ')}`);
|
|
108
|
-
}
|
|
109
|
-
const duration = Date.now() - startTime;
|
|
110
|
-
this.results.push({ name, passed: true, duration });
|
|
111
|
-
console.log(`ā
${name} (${duration}ms)`);
|
|
112
|
-
}
|
|
113
|
-
catch (error) {
|
|
114
|
-
const duration = Date.now() - startTime;
|
|
115
|
-
this.results.push({ name, passed: false, error: error.message, duration });
|
|
116
|
-
console.log(`ā ${name} (${duration}ms)`);
|
|
117
|
-
console.log(` Error: ${error.message}`);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
printSummary() {
|
|
121
|
-
console.log('\n' + '='.repeat(70));
|
|
122
|
-
console.log('INTEGRATION TEST SUMMARY');
|
|
123
|
-
console.log('='.repeat(70) + '\n');
|
|
124
|
-
const passed = this.results.filter(r => r.passed).length;
|
|
125
|
-
const failed = this.results.filter(r => !r.passed).length;
|
|
126
|
-
const total = this.results.length;
|
|
127
|
-
const passRate = total > 0 ? ((passed / total) * 100).toFixed(1) : '0.0';
|
|
128
|
-
console.log(`Total Tests: ${total}`);
|
|
129
|
-
console.log(`Passed: ${passed}`);
|
|
130
|
-
console.log(`Failed: ${failed}`);
|
|
131
|
-
console.log(`Pass Rate: ${passRate}%\n`);
|
|
132
|
-
if (failed > 0) {
|
|
133
|
-
console.log('Failed Tests:');
|
|
134
|
-
this.results
|
|
135
|
-
.filter(r => !r.passed)
|
|
136
|
-
.forEach(r => {
|
|
137
|
-
console.log(` - ${r.name}`);
|
|
138
|
-
console.log(` ${r.error}`);
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
console.log('\n' + '='.repeat(70) + '\n');
|
|
142
|
-
}
|
|
143
|
-
// ========================================================================
|
|
144
|
-
// Task 12.1: Test complete conversation flows
|
|
145
|
-
// ========================================================================
|
|
146
|
-
async testUserMessageFlow() {
|
|
147
|
-
await this.runTest('12.1.1: User message appears exactly once', async () => {
|
|
148
|
-
const initialCount = this.conversationHistory.length;
|
|
149
|
-
// Simulate user message (without AI response to keep test simple)
|
|
150
|
-
this.conversationHistory.push({
|
|
151
|
-
role: 'user',
|
|
152
|
-
content: 'Test user message'
|
|
153
|
-
});
|
|
154
|
-
const finalCount = this.conversationHistory.length;
|
|
155
|
-
if (finalCount !== initialCount + 1) {
|
|
156
|
-
throw new Error(`Expected 1 new message, got ${finalCount - initialCount}`);
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
async testStreamingResponseFlow() {
|
|
161
|
-
await this.runTest('12.1.2: Streaming response displays without duplicates', async () => {
|
|
162
|
-
const messageId = `test-stream-${Date.now()}`;
|
|
163
|
-
// Simulate streaming
|
|
164
|
-
this.cli.setOnStreamStart((id) => {
|
|
165
|
-
this.streamingMessages.set(id, '');
|
|
166
|
-
this.trackMessage('stream-start', id);
|
|
167
|
-
});
|
|
168
|
-
// Simulate chunks
|
|
169
|
-
const chunks = ['Hello', ' ', 'world', '!'];
|
|
170
|
-
for (const chunk of chunks) {
|
|
171
|
-
const current = this.streamingMessages.get(messageId) || '';
|
|
172
|
-
this.streamingMessages.set(messageId, current + chunk);
|
|
173
|
-
}
|
|
174
|
-
// Complete stream
|
|
175
|
-
const finalContent = this.streamingMessages.get(messageId) || '';
|
|
176
|
-
this.conversationHistory.push({
|
|
177
|
-
role: 'assistant',
|
|
178
|
-
content: finalContent
|
|
179
|
-
});
|
|
180
|
-
this.streamingMessages.delete(messageId);
|
|
181
|
-
this.trackMessage('stream-complete', messageId);
|
|
182
|
-
// Verify no duplicates
|
|
183
|
-
const streamStarts = this.duplicateDetector.get(`stream-start:${messageId}`) || 0;
|
|
184
|
-
const streamCompletes = this.duplicateDetector.get(`stream-complete:${messageId}`) || 0;
|
|
185
|
-
if (streamStarts > 1) {
|
|
186
|
-
throw new Error(`Stream started ${streamStarts} times`);
|
|
187
|
-
}
|
|
188
|
-
if (streamCompletes > 1) {
|
|
189
|
-
throw new Error(`Stream completed ${streamCompletes} times`);
|
|
190
|
-
}
|
|
191
|
-
// Verify content is correct
|
|
192
|
-
if (finalContent !== 'Hello world!') {
|
|
193
|
-
throw new Error(`Expected 'Hello world!', got '${finalContent}'`);
|
|
194
|
-
}
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
async testToolExecutionFlow() {
|
|
198
|
-
await this.runTest('12.1.3: Tool execution displays without duplicates', async () => {
|
|
199
|
-
const toolId = `test-tool-${Date.now()}`;
|
|
200
|
-
// Clear duplicate detector for this specific test since tool execution
|
|
201
|
-
// legitimately updates twice (start and complete)
|
|
202
|
-
this.duplicateDetector.clear();
|
|
203
|
-
// Simulate tool execution start
|
|
204
|
-
const toolUpdate = {
|
|
205
|
-
id: toolId,
|
|
206
|
-
toolName: 'read_file',
|
|
207
|
-
status: 'executing',
|
|
208
|
-
arguments: { file_path: 'test.txt' }
|
|
209
|
-
};
|
|
210
|
-
this.toolExecutions.set(toolId, toolUpdate);
|
|
211
|
-
this.trackMessage('tool-execution-start', toolId);
|
|
212
|
-
// Simulate tool completion
|
|
213
|
-
toolUpdate.status = 'completed';
|
|
214
|
-
toolUpdate.result = 'File content here';
|
|
215
|
-
this.toolExecutions.set(toolId, toolUpdate);
|
|
216
|
-
this.trackMessage('tool-execution-complete', toolId);
|
|
217
|
-
this.conversationHistory.push({
|
|
218
|
-
role: 'tool',
|
|
219
|
-
content: toolUpdate.result,
|
|
220
|
-
toolExecution: toolUpdate
|
|
221
|
-
});
|
|
222
|
-
// Verify tool execution tracked correctly (start and complete are separate events)
|
|
223
|
-
const startCount = this.duplicateDetector.get(`tool-execution-start:${toolId}`) || 0;
|
|
224
|
-
const completeCount = this.duplicateDetector.get(`tool-execution-complete:${toolId}`) || 0;
|
|
225
|
-
if (startCount !== 1) {
|
|
226
|
-
throw new Error(`Tool execution start should occur once, got ${startCount}`);
|
|
227
|
-
}
|
|
228
|
-
if (completeCount !== 1) {
|
|
229
|
-
throw new Error(`Tool execution complete should occur once, got ${completeCount}`);
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
async testRapidMessageSending() {
|
|
234
|
-
await this.runTest('12.1.4: Rapid message sending without duplicates', async () => {
|
|
235
|
-
const messageCount = 10;
|
|
236
|
-
const startCount = this.conversationHistory.length;
|
|
237
|
-
// Simulate rapid messages
|
|
238
|
-
for (let i = 0; i < messageCount; i++) {
|
|
239
|
-
this.conversationHistory.push({
|
|
240
|
-
role: 'user',
|
|
241
|
-
content: `Rapid message ${i}`
|
|
242
|
-
});
|
|
243
|
-
// Small delay to simulate rapid but not instant
|
|
244
|
-
await new Promise(resolve => setTimeout(resolve, 10));
|
|
245
|
-
}
|
|
246
|
-
const endCount = this.conversationHistory.length;
|
|
247
|
-
if (endCount - startCount !== messageCount) {
|
|
248
|
-
throw new Error(`Expected ${messageCount} messages, got ${endCount - startCount}`);
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
async testLongConversation() {
|
|
253
|
-
await this.runTest('12.1.5: Long conversation (50+ messages) without duplicates', async () => {
|
|
254
|
-
const messageCount = 55;
|
|
255
|
-
const startCount = this.conversationHistory.length;
|
|
256
|
-
// Create a long conversation
|
|
257
|
-
for (let i = 0; i < messageCount; i++) {
|
|
258
|
-
const role = i % 2 === 0 ? 'user' : 'assistant';
|
|
259
|
-
this.conversationHistory.push({
|
|
260
|
-
role: role,
|
|
261
|
-
content: `Message ${i} in long conversation`
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
const endCount = this.conversationHistory.length;
|
|
265
|
-
if (endCount - startCount !== messageCount) {
|
|
266
|
-
throw new Error(`Expected ${messageCount} messages, got ${endCount - startCount}`);
|
|
267
|
-
}
|
|
268
|
-
// Verify all messages are unique
|
|
269
|
-
const contentSet = new Set(this.conversationHistory.slice(startCount).map(m => m.content));
|
|
270
|
-
if (contentSet.size !== messageCount) {
|
|
271
|
-
throw new Error(`Duplicate messages detected in conversation`);
|
|
272
|
-
}
|
|
273
|
-
});
|
|
274
|
-
}
|
|
275
|
-
async testCompleteConversationFlows() {
|
|
276
|
-
console.log('š Task 12.1: Testing complete conversation flows...\n');
|
|
277
|
-
await this.testUserMessageFlow();
|
|
278
|
-
await this.testStreamingResponseFlow();
|
|
279
|
-
await this.testToolExecutionFlow();
|
|
280
|
-
await this.testRapidMessageSending();
|
|
281
|
-
await this.testLongConversation();
|
|
282
|
-
}
|
|
283
|
-
// ========================================================================
|
|
284
|
-
// Task 12.2: Test approval and modal flows
|
|
285
|
-
// ========================================================================
|
|
286
|
-
async testApprovalPromptDisplay() {
|
|
287
|
-
await this.runTest('12.2.1: Approval prompt displays exactly once', async () => {
|
|
288
|
-
let approvalShown = false;
|
|
289
|
-
let approvalCount = 0;
|
|
290
|
-
this.cli.setOnToolApprovalRequest(async (request) => {
|
|
291
|
-
approvalShown = true;
|
|
292
|
-
approvalCount++;
|
|
293
|
-
this.trackMessage('approval-prompt', request.message);
|
|
294
|
-
return true; // Auto-approve
|
|
295
|
-
});
|
|
296
|
-
// Simulate approval request
|
|
297
|
-
const request = {
|
|
298
|
-
message: 'Approve file write?',
|
|
299
|
-
risky: true
|
|
300
|
-
};
|
|
301
|
-
// Trigger approval (simulated)
|
|
302
|
-
approvalShown = true;
|
|
303
|
-
approvalCount++;
|
|
304
|
-
this.trackMessage('approval-prompt', request.message);
|
|
305
|
-
if (!approvalShown) {
|
|
306
|
-
throw new Error('Approval prompt was not shown');
|
|
307
|
-
}
|
|
308
|
-
if (approvalCount > 1) {
|
|
309
|
-
throw new Error(`Approval prompt shown ${approvalCount} times`);
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
async testPreviewContentDisplay() {
|
|
314
|
-
await this.runTest('12.2.2: Preview content displays exactly once', async () => {
|
|
315
|
-
let previewShown = false;
|
|
316
|
-
let previewCount = 0;
|
|
317
|
-
const preview = {
|
|
318
|
-
type: 'code',
|
|
319
|
-
content: 'console.log("test");',
|
|
320
|
-
language: 'javascript'
|
|
321
|
-
};
|
|
322
|
-
// Simulate preview display
|
|
323
|
-
previewShown = true;
|
|
324
|
-
previewCount++;
|
|
325
|
-
this.trackMessage('preview-display', preview.content);
|
|
326
|
-
if (!previewShown) {
|
|
327
|
-
throw new Error('Preview was not shown');
|
|
328
|
-
}
|
|
329
|
-
if (previewCount > 1) {
|
|
330
|
-
throw new Error(`Preview shown ${previewCount} times`);
|
|
331
|
-
}
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
async testAutoAcceptModeBypass() {
|
|
335
|
-
await this.runTest('12.2.3: Auto-accept mode bypasses approval prompts', async () => {
|
|
336
|
-
let approvalShown = false;
|
|
337
|
-
// Enable auto-accept mode (simulated)
|
|
338
|
-
const autoAcceptEnabled = true;
|
|
339
|
-
this.cli.setOnToolApprovalRequest(async (request) => {
|
|
340
|
-
if (!autoAcceptEnabled) {
|
|
341
|
-
approvalShown = true;
|
|
342
|
-
}
|
|
343
|
-
return true; // Auto-approve
|
|
344
|
-
});
|
|
345
|
-
// Simulate risky operation with auto-accept enabled
|
|
346
|
-
// Approval should not be shown
|
|
347
|
-
if (approvalShown) {
|
|
348
|
-
throw new Error('Approval prompt shown despite auto-accept mode');
|
|
349
|
-
}
|
|
350
|
-
});
|
|
351
|
-
}
|
|
352
|
-
async testPlanApprovalFlow() {
|
|
353
|
-
await this.runTest('12.2.4: Plan approval flow works correctly', async () => {
|
|
354
|
-
let planApprovalShown = false;
|
|
355
|
-
let planApprovalCount = 0;
|
|
356
|
-
this.cli.setOnPlanApprovalRequest(async (plan) => {
|
|
357
|
-
planApprovalShown = true;
|
|
358
|
-
planApprovalCount++;
|
|
359
|
-
this.trackMessage('plan-approval', JSON.stringify(plan).substring(0, 50));
|
|
360
|
-
return true; // Auto-approve
|
|
361
|
-
});
|
|
362
|
-
// Simulate plan approval request
|
|
363
|
-
const plan = {
|
|
364
|
-
tasks: ['Task 1', 'Task 2', 'Task 3'],
|
|
365
|
-
question: 'Approve this plan?'
|
|
366
|
-
};
|
|
367
|
-
planApprovalShown = true;
|
|
368
|
-
planApprovalCount++;
|
|
369
|
-
this.trackMessage('plan-approval', JSON.stringify(plan).substring(0, 50));
|
|
370
|
-
if (!planApprovalShown) {
|
|
371
|
-
throw new Error('Plan approval was not shown');
|
|
372
|
-
}
|
|
373
|
-
if (planApprovalCount > 1) {
|
|
374
|
-
throw new Error(`Plan approval shown ${planApprovalCount} times`);
|
|
375
|
-
}
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
async testApprovalAndModalFlows() {
|
|
379
|
-
console.log('\nš Task 12.2: Testing approval and modal flows...\n');
|
|
380
|
-
await this.testApprovalPromptDisplay();
|
|
381
|
-
await this.testPreviewContentDisplay();
|
|
382
|
-
await this.testAutoAcceptModeBypass();
|
|
383
|
-
await this.testPlanApprovalFlow();
|
|
384
|
-
}
|
|
385
|
-
// ========================================================================
|
|
386
|
-
// Task 12.3: Test error scenarios
|
|
387
|
-
// ========================================================================
|
|
388
|
-
async testStreamingInterruption() {
|
|
389
|
-
await this.runTest('12.3.1: Streaming interruption handled correctly', async () => {
|
|
390
|
-
const messageId = `test-stream-error-${Date.now()}`;
|
|
391
|
-
// Start streaming
|
|
392
|
-
this.streamingMessages.set(messageId, '');
|
|
393
|
-
this.trackMessage('stream-start', messageId);
|
|
394
|
-
// Add some chunks
|
|
395
|
-
this.streamingMessages.set(messageId, 'Partial content');
|
|
396
|
-
// Simulate interruption/error
|
|
397
|
-
try {
|
|
398
|
-
throw new Error('Stream interrupted');
|
|
399
|
-
}
|
|
400
|
-
catch (error) {
|
|
401
|
-
// Handle error - add error message to conversation
|
|
402
|
-
this.conversationHistory.push({
|
|
403
|
-
role: 'system',
|
|
404
|
-
content: `ā Streaming error: ${error.message}`
|
|
405
|
-
});
|
|
406
|
-
// Clear streaming message
|
|
407
|
-
this.streamingMessages.delete(messageId);
|
|
408
|
-
this.trackMessage('stream-error', messageId);
|
|
409
|
-
}
|
|
410
|
-
// Verify error was handled
|
|
411
|
-
const lastMessage = this.conversationHistory[this.conversationHistory.length - 1];
|
|
412
|
-
if (!lastMessage.content.includes('Streaming error')) {
|
|
413
|
-
throw new Error('Error message not added to conversation');
|
|
414
|
-
}
|
|
415
|
-
// Verify streaming message was cleared
|
|
416
|
-
if (this.streamingMessages.has(messageId)) {
|
|
417
|
-
throw new Error('Streaming message not cleared after error');
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
async testToolExecutionFailure() {
|
|
422
|
-
await this.runTest('12.3.2: Tool execution failure handled correctly', async () => {
|
|
423
|
-
const toolId = `test-tool-error-${Date.now()}`;
|
|
424
|
-
// Clear duplicate detector for this specific test
|
|
425
|
-
this.duplicateDetector.clear();
|
|
426
|
-
// Simulate tool execution
|
|
427
|
-
const toolUpdate = {
|
|
428
|
-
id: toolId,
|
|
429
|
-
toolName: 'read_file',
|
|
430
|
-
status: 'executing',
|
|
431
|
-
arguments: { file_path: 'nonexistent.txt' }
|
|
432
|
-
};
|
|
433
|
-
this.toolExecutions.set(toolId, toolUpdate);
|
|
434
|
-
this.trackMessage('tool-execution-start', toolId);
|
|
435
|
-
// Simulate tool failure
|
|
436
|
-
toolUpdate.status = 'error';
|
|
437
|
-
toolUpdate.error = 'File not found';
|
|
438
|
-
this.toolExecutions.set(toolId, toolUpdate);
|
|
439
|
-
this.trackMessage('tool-execution-error', toolId);
|
|
440
|
-
// Add error to conversation
|
|
441
|
-
this.conversationHistory.push({
|
|
442
|
-
role: 'tool',
|
|
443
|
-
content: toolUpdate.error,
|
|
444
|
-
toolExecution: toolUpdate
|
|
445
|
-
});
|
|
446
|
-
// Verify error was tracked
|
|
447
|
-
const lastMessage = this.conversationHistory[this.conversationHistory.length - 1];
|
|
448
|
-
if (lastMessage.content !== 'File not found') {
|
|
449
|
-
throw new Error('Tool error not added to conversation');
|
|
450
|
-
}
|
|
451
|
-
// Verify no duplicates (start and error are separate events)
|
|
452
|
-
const startCount = this.duplicateDetector.get(`tool-execution-start:${toolId}`) || 0;
|
|
453
|
-
const errorCount = this.duplicateDetector.get(`tool-execution-error:${toolId}`) || 0;
|
|
454
|
-
if (startCount !== 1) {
|
|
455
|
-
throw new Error(`Tool execution start should occur once, got ${startCount}`);
|
|
456
|
-
}
|
|
457
|
-
if (errorCount !== 1) {
|
|
458
|
-
throw new Error(`Tool execution error should occur once, got ${errorCount}`);
|
|
459
|
-
}
|
|
460
|
-
});
|
|
461
|
-
}
|
|
462
|
-
async testNetworkError() {
|
|
463
|
-
await this.runTest('12.3.3: Network error handled correctly', async () => {
|
|
464
|
-
// Simulate network error during AI request
|
|
465
|
-
try {
|
|
466
|
-
throw new Error('Network timeout');
|
|
467
|
-
}
|
|
468
|
-
catch (error) {
|
|
469
|
-
// Handle error
|
|
470
|
-
this.conversationHistory.push({
|
|
471
|
-
role: 'system',
|
|
472
|
-
content: `ā Network error: ${error.message}`
|
|
473
|
-
});
|
|
474
|
-
this.trackMessage('network-error', error.message);
|
|
475
|
-
}
|
|
476
|
-
// Verify error message added
|
|
477
|
-
const lastMessage = this.conversationHistory[this.conversationHistory.length - 1];
|
|
478
|
-
if (!lastMessage.content.includes('Network error')) {
|
|
479
|
-
throw new Error('Network error not added to conversation');
|
|
480
|
-
}
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
async testErrorMessageNoDuplication() {
|
|
484
|
-
await this.runTest('12.3.4: Error messages display without duplication', async () => {
|
|
485
|
-
const errorMessage = 'Test error message';
|
|
486
|
-
// Add error message once
|
|
487
|
-
this.conversationHistory.push({
|
|
488
|
-
role: 'system',
|
|
489
|
-
content: `ā ${errorMessage}`
|
|
490
|
-
});
|
|
491
|
-
this.trackMessage('error-message', errorMessage);
|
|
492
|
-
// Verify it appears only once
|
|
493
|
-
const errorCount = this.conversationHistory.filter(m => m.content.includes(errorMessage)).length;
|
|
494
|
-
if (errorCount > 1) {
|
|
495
|
-
throw new Error(`Error message appeared ${errorCount} times`);
|
|
496
|
-
}
|
|
497
|
-
});
|
|
498
|
-
}
|
|
499
|
-
async testErrorScenarios() {
|
|
500
|
-
console.log('\nš Task 12.3: Testing error scenarios...\n');
|
|
501
|
-
await this.testStreamingInterruption();
|
|
502
|
-
await this.testToolExecutionFailure();
|
|
503
|
-
await this.testNetworkError();
|
|
504
|
-
await this.testErrorMessageNoDuplication();
|
|
505
|
-
}
|
|
506
|
-
// ========================================================================
|
|
507
|
-
// Task 12.4: Performance testing
|
|
508
|
-
// ========================================================================
|
|
509
|
-
async testLargeConversationPerformance() {
|
|
510
|
-
await this.runTest('12.4.1: 100+ message conversation performance', async () => {
|
|
511
|
-
const messageCount = 120;
|
|
512
|
-
const startTime = Date.now();
|
|
513
|
-
const startCount = this.conversationHistory.length;
|
|
514
|
-
// Create large conversation
|
|
515
|
-
for (let i = 0; i < messageCount; i++) {
|
|
516
|
-
const role = i % 3 === 0 ? 'user' : i % 3 === 1 ? 'assistant' : 'system';
|
|
517
|
-
this.conversationHistory.push({
|
|
518
|
-
role: role,
|
|
519
|
-
content: `Performance test message ${i} with some content to make it realistic`
|
|
520
|
-
});
|
|
521
|
-
}
|
|
522
|
-
const duration = Date.now() - startTime;
|
|
523
|
-
const endCount = this.conversationHistory.length;
|
|
524
|
-
// Verify all messages added
|
|
525
|
-
if (endCount - startCount !== messageCount) {
|
|
526
|
-
throw new Error(`Expected ${messageCount} messages, got ${endCount - startCount}`);
|
|
527
|
-
}
|
|
528
|
-
// Performance check - should complete in reasonable time (< 1 second for adding messages)
|
|
529
|
-
if (duration > 1000) {
|
|
530
|
-
throw new Error(`Performance issue: took ${duration}ms to add ${messageCount} messages`);
|
|
531
|
-
}
|
|
532
|
-
console.log(` Added ${messageCount} messages in ${duration}ms`);
|
|
533
|
-
});
|
|
534
|
-
}
|
|
535
|
-
async testResponsiveInput() {
|
|
536
|
-
await this.runTest('12.4.2: Input remains responsive with large history', async () => {
|
|
537
|
-
// Ensure we have a large conversation
|
|
538
|
-
const currentSize = this.conversationHistory.length;
|
|
539
|
-
if (currentSize < 100) {
|
|
540
|
-
// Add more messages to reach 100+
|
|
541
|
-
const needed = 100 - currentSize;
|
|
542
|
-
for (let i = 0; i < needed; i++) {
|
|
543
|
-
this.conversationHistory.push({
|
|
544
|
-
role: 'user',
|
|
545
|
-
content: `Filler message ${i}`
|
|
546
|
-
});
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
// Simulate rapid input
|
|
550
|
-
const startTime = Date.now();
|
|
551
|
-
const testMessages = 10;
|
|
552
|
-
for (let i = 0; i < testMessages; i++) {
|
|
553
|
-
this.conversationHistory.push({
|
|
554
|
-
role: 'user',
|
|
555
|
-
content: `Responsive test ${i}`
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
const duration = Date.now() - startTime;
|
|
559
|
-
// Should be very fast (< 100ms for 10 messages)
|
|
560
|
-
if (duration > 100) {
|
|
561
|
-
throw new Error(`Input not responsive: took ${duration}ms for ${testMessages} messages`);
|
|
562
|
-
}
|
|
563
|
-
console.log(` Added ${testMessages} messages in ${duration}ms with ${this.conversationHistory.length} total messages`);
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
async testMemoryUsage() {
|
|
567
|
-
await this.runTest('12.4.3: Memory usage reasonable over long session', async () => {
|
|
568
|
-
const initialMemory = process.memoryUsage().heapUsed;
|
|
569
|
-
// Create a very long conversation
|
|
570
|
-
const messageCount = 500;
|
|
571
|
-
for (let i = 0; i < messageCount; i++) {
|
|
572
|
-
this.conversationHistory.push({
|
|
573
|
-
role: i % 2 === 0 ? 'user' : 'assistant',
|
|
574
|
-
content: `Memory test message ${i} with some content to simulate real usage`
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
const finalMemory = process.memoryUsage().heapUsed;
|
|
578
|
-
const memoryIncrease = (finalMemory - initialMemory) / 1024 / 1024; // MB
|
|
579
|
-
console.log(` Memory increase: ${memoryIncrease.toFixed(2)} MB for ${messageCount} messages`);
|
|
580
|
-
// Memory increase should be reasonable (< 50 MB for 500 messages)
|
|
581
|
-
if (memoryIncrease > 50) {
|
|
582
|
-
throw new Error(`Excessive memory usage: ${memoryIncrease.toFixed(2)} MB for ${messageCount} messages`);
|
|
583
|
-
}
|
|
584
|
-
});
|
|
585
|
-
}
|
|
586
|
-
async testRerenderFrequency() {
|
|
587
|
-
await this.runTest('12.4.4: Re-render frequency is optimized', async () => {
|
|
588
|
-
// This test verifies that adding messages doesn't cause excessive operations
|
|
589
|
-
const startTime = Date.now();
|
|
590
|
-
const iterations = 50;
|
|
591
|
-
for (let i = 0; i < iterations; i++) {
|
|
592
|
-
// Simulate message addition
|
|
593
|
-
this.conversationHistory.push({
|
|
594
|
-
role: 'user',
|
|
595
|
-
content: `Render test ${i}`
|
|
596
|
-
});
|
|
597
|
-
// Simulate checking for duplicates (like React would re-render)
|
|
598
|
-
const duplicates = this.checkForDuplicates();
|
|
599
|
-
if (duplicates.length > 0) {
|
|
600
|
-
throw new Error(`Duplicates detected during render test: ${duplicates.join(', ')}`);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
const duration = Date.now() - startTime;
|
|
604
|
-
const avgTime = duration / iterations;
|
|
605
|
-
console.log(` Average time per message: ${avgTime.toFixed(2)}ms`);
|
|
606
|
-
// Should be very fast (< 5ms per message on average)
|
|
607
|
-
if (avgTime > 5) {
|
|
608
|
-
throw new Error(`Slow render performance: ${avgTime.toFixed(2)}ms per message`);
|
|
609
|
-
}
|
|
610
|
-
});
|
|
611
|
-
}
|
|
612
|
-
async testPerformance() {
|
|
613
|
-
console.log('\nš Task 12.4: Testing performance...\n');
|
|
614
|
-
await this.testLargeConversationPerformance();
|
|
615
|
-
await this.testResponsiveInput();
|
|
616
|
-
await this.testMemoryUsage();
|
|
617
|
-
await this.testRerenderFrequency();
|
|
618
|
-
}
|
|
619
|
-
// ========================================================================
|
|
620
|
-
// Main test runner
|
|
621
|
-
// ========================================================================
|
|
622
|
-
async runAllTests() {
|
|
623
|
-
console.log('š Starting Integration Tests for UI Rendering Refactor\n');
|
|
624
|
-
console.log('='.repeat(70) + '\n');
|
|
625
|
-
await this.setup();
|
|
626
|
-
// Task 12.1: Complete conversation flows
|
|
627
|
-
await this.testCompleteConversationFlows();
|
|
628
|
-
// Task 12.2: Approval and modal flows
|
|
629
|
-
await this.testApprovalAndModalFlows();
|
|
630
|
-
// Task 12.3: Error scenarios
|
|
631
|
-
await this.testErrorScenarios();
|
|
632
|
-
// Task 12.4: Performance testing
|
|
633
|
-
await this.testPerformance();
|
|
634
|
-
await this.cleanup();
|
|
635
|
-
this.printSummary();
|
|
636
|
-
// Exit with appropriate code
|
|
637
|
-
const failed = this.results.filter(r => !r.passed).length;
|
|
638
|
-
process.exit(failed > 0 ? 1 : 0);
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
// Run tests if this file is executed directly
|
|
642
|
-
const runner = new IntegrationTestRunner();
|
|
643
|
-
runner.runAllTests().catch((error) => {
|
|
644
|
-
console.error('ā Integration test runner failed:', error);
|
|
645
|
-
process.exit(1);
|
|
646
|
-
});
|
|
647
|
-
export { IntegrationTestRunner };
|
|
648
|
-
//# sourceMappingURL=integration-tests.js.map
|