Skip to main content
Glama
terminal-locking-issue-reproduction.test.ts5.73 kB
/** * Terminal Locking Issue Reproduction Test * TDD: Write failing tests to reproduce the terminal locking behavior that needs fixing */ import { JestTestUtilities } from './integration/terminal-history-framework/jest-test-utilities'; describe('Terminal Locking Issue Reproduction', () => { const testUtils = JestTestUtilities.setupJestEnvironment('terminal-locking-reproduction'); /** * FAILING TEST: Demonstrates current broken behavior with artificial locking * This test SHOULD fail initially to prove the problem exists */ it('should NOT show terminal locked message for immediate command completion', async () => { // Arrange: Simple command that executes immediately const config = { preWebSocketCommands: [ 'ssh_connect {"name": "terminal-lock-test", "host": "localhost", "username": "jsbattig", "keyFilePath": "~/.ssh/id_ed25519"}' ], postWebSocketCommands: [ 'ssh_exec {"sessionName": "terminal-lock-test", "command": "pwd"}' // Simple, fast command ], workflowTimeout: 5000, // Short timeout to trigger issue sessionName: 'terminal-lock-test' }; // Act: Execute command through terminal const result = await testUtils.runTerminalHistoryTest(config); // Assert: These assertions SHOULD FAIL initially proving the problem expect(result.concatenatedResponses).not.toContain('Terminal locked - command executing'); expect(result.concatenatedResponses).not.toContain('⚠ Error: Command timeout'); expect(result.concatenatedResponses).not.toContain('terminal-locked'); // CSS class // Should contain natural prompt after command completion expect(result.concatenatedResponses).toMatch(/\[jsbattig@localhost[^\]]*\]\$/); }); /** * FAILING TEST: Demonstrates prompt detection failure for bracket format * This test reproduces the core issue: isPromptLine() not recognizing bracket prompts */ it('should detect bracket format prompts correctly', async () => { // Test data: Real bracket format prompts from current system const bracketPrompts = [ '[jsbattig@localhost ls-ssh-mcp]$ ', '[jsbattig@localhost ls-ssh-mcp]$', '[jsbattig@localhost ~]$ ', '[jsbattig@localhost /home/jsbattig]$ ' ]; // Simulate the isPromptLine function from terminal-input-handler.js const isPromptLine = (output: string): boolean => { const trimmedOutput = output.trim(); const promptPatterns = [ /^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+:[~\/][^$]*\$\s*$/, // user@host:path$ /^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+:[~\/][^#]*#\s*$/, // user@host:path# (root) /^\[[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\s+[^\]]+\]\$\s*$/, // [user@host project]$ (bracket format) /^\[\d{2}:\d{2}:\d{2}\][^$]*\$\s*$/, // [HH:MM:SS]...$ (with timestamp) /^[>]\s*$/ // Simple > prompt (minimal) ]; return promptPatterns.some(pattern => pattern.test(trimmedOutput)); }; // Act & Assert: These assertions SHOULD FAIL initially for (const prompt of bracketPrompts) { expect(isPromptLine(prompt)).toBe(true); } }); /** * FAILING TEST: Natural terminal flow without artificial delays * Tests the desired behavior where commands execute and terminal becomes ready immediately */ it('should allow immediate next command after previous command completes', async () => { const config = { preWebSocketCommands: [ 'ssh_connect {"name": "natural-flow-test", "host": "localhost", "username": "jsbattig", "keyFilePath": "~/.ssh/id_ed25519"}' ], postWebSocketCommands: [ 'ssh_exec {"sessionName": "natural-flow-test", "command": "pwd"}', 'ssh_exec {"sessionName": "natural-flow-test", "command": "whoami"}' // Second immediate command ], workflowTimeout: 10000, sessionName: 'natural-flow-test' }; const result = await testUtils.runTerminalHistoryTest(config); // Assert: Should see both commands execute without locking delays testUtils.expectWebSocketMessages(result.concatenatedResponses) .toMatchCommandSequence(['pwd', 'whoami']) .toNotContain('Terminal locked') .toNotContain('Command timeout') .validate(); // Should see natural prompt flow: command1 -> result1 -> prompt -> command2 -> result2 -> prompt const prompts = result.concatenatedResponses.match(/\[jsbattig@localhost[^\]]*\]\$/g); expect(prompts).toBeTruthy(); expect(prompts!.length).toBeGreaterThanOrEqual(2); // At least 2 prompts for 2 commands }); /** * FAILING TEST: WebSocket message timing analysis * Analyzes the timing between command execution and prompt appearance */ it('should show prompt immediately after command results without artificial delay', async () => { const config = { preWebSocketCommands: [ 'ssh_connect {"name": "timing-test", "host": "localhost", "username": "jsbattig", "keyFilePath": "~/.ssh/id_ed25519"}' ], postWebSocketCommands: [ 'ssh_exec {"sessionName": "timing-test", "command": "echo TIMING_TEST_MARKER"}' // Easily identifiable output ], workflowTimeout: 8000, sessionName: 'timing-test' }; const startTime = Date.now(); const result = await testUtils.runTerminalHistoryTest(config); const totalTime = Date.now() - startTime; // Should complete quickly without timeout delays expect(totalTime).toBeLessThan(5000); // Should complete in under 5 seconds // Should see marker followed by prompt expect(result.concatenatedResponses).toContain('TIMING_TEST_MARKER'); expect(result.concatenatedResponses).toMatch(/TIMING_TEST_MARKER[\r\n]+\[jsbattig@localhost[^\]]*\]\$/); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/LightspeedDMS/ssh-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server