Skip to main content
Glama
double-prompting-regression.test.ts6.09 kB
/** * Double Prompting Regression Test * * Tests the critical scenario where MCP commands executed after browser commands * cause double prompting: [user@host]$ [user@host]$ command instead of [user@host]$ command * * EVIDENCE FROM USER: * [jsbattig@localhost ~]$ [jsbattig@localhost ~]$ date * Shows double prompt instead of correct: [jsbattig@localhost ~]$ date */ import { JestTestUtilities } from './jest-test-utilities.js'; describe('Double Prompting Regression Prevention', () => { const testUtils = JestTestUtilities.setupJestEnvironment('double-prompting-regression'); test('should not double prompt when MCP command follows browser command', async () => { const sessionName = 'double-prompt-test'; const config = { preWebSocketCommands: [ // Establish SSH connection and execute a command to establish terminal state `ssh_connect {"name": "${sessionName}", "host": "localhost", "username": "jsbattig", "keyFilePath": "~/.ssh/id_ed25519"}`, `ssh_exec {"sessionName": "${sessionName}", "command": "pwd"}`, // First MCP command ], postWebSocketCommands: [ // This MCP command after browser activity should NOT double prompt `ssh_exec {"sessionName": "${sessionName}", "command": "date"}`, ], workflowTimeout: 30000, sessionName: sessionName }; const result = await testUtils.runTerminalHistoryTest(config); // Extract WebSocket responses to analyze prompting behavior const responses = result.concatenatedResponses; // Should NOT contain double prompting pattern const doublePromptPattern = /\[jsbattig@localhost[^\]]*\]\$\s+\[jsbattig@localhost[^\]]*\]\$\s+date/; expect(responses).not.toMatch(doublePromptPattern); // Should contain single prompt with date command const singlePromptPattern = /\[jsbattig@localhost[^\]]*\]\$\s+date/; expect(responses).toMatch(singlePromptPattern); // Verify proper command sequence without double prompts testUtils.expectWebSocketMessages(responses) .toContainCRLF() .toHavePrompts() .toMatchCommandSequence(['pwd', 'date']) .validate(); // CRITICAL: Ensure no double prompt anywhere in the output const promptCount = (responses.match(/\[jsbattig@localhost[^\]]*\]\$/g) || []).length; // Should have: initial prompt + pwd command prompt + pwd result prompt + date command prompt + date result prompt // Total: 5 prompts maximum, not 6+ from double prompting expect(promptCount).toBeLessThanOrEqual(5); // Verify date command output is present expect(responses).toContain('2025'); // Current year should be in date output }, 45000); test('should handle multiple MCP commands after browser activity without accumulating prompts', async () => { const sessionName = 'multi-mcp-test'; const config = { preWebSocketCommands: [ `ssh_connect {"name": "${sessionName}", "host": "localhost", "username": "jsbattig", "keyFilePath": "~/.ssh/id_ed25519"}`, `ssh_exec {"sessionName": "${sessionName}", "command": "ls", "source": "user"}`, // Simulate browser command ], postWebSocketCommands: [ `ssh_exec {"sessionName": "${sessionName}", "command": "whoami"}`, `ssh_exec {"sessionName": "${sessionName}", "command": "hostname"}`, `ssh_exec {"sessionName": "${sessionName}", "command": "uptime"}`, ], workflowTimeout: 30000, sessionName: sessionName }; const result = await testUtils.runTerminalHistoryTest(config); const responses = result.concatenatedResponses; // Check for any double prompting patterns const doublePromptPatterns = [ /\[jsbattig@localhost[^\]]*\]\$\s+\[jsbattig@localhost[^\]]*\]\$\s+whoami/, /\[jsbattig@localhost[^\]]*\]\$\s+\[jsbattig@localhost[^\]]*\]\$\s+hostname/, /\[jsbattig@localhost[^\]]*\]\$\s+\[jsbattig@localhost[^\]]*\]\$\s+uptime/, ]; doublePromptPatterns.forEach((pattern) => { expect(responses).not.toMatch(pattern); }); // Verify all commands executed successfully expect(responses).toContain('jsbattig'); // whoami output expect(responses).toContain('localhost'); // hostname output expect(responses).toMatch(/load average/); // uptime output // Count total prompts - should be reasonable for 4 commands (ls + whoami + hostname + uptime) const promptCount = (responses.match(/\[jsbattig@localhost[^\]]*\]\$/g) || []).length; expect(promptCount).toBeLessThanOrEqual(10); // Generous upper bound to catch excessive prompting }, 45000); test('should maintain proper prompt state when switching between browser and MCP commands', async () => { const sessionName = 'mixed-command-test'; const config = { preWebSocketCommands: [ `ssh_connect {"name": "${sessionName}", "host": "localhost", "username": "jsbattig", "keyFilePath": "~/.ssh/id_ed25519"}`, `ssh_exec {"sessionName": "${sessionName}", "command": "echo 'mcp-pre'"}`, `ssh_exec {"sessionName": "${sessionName}", "command": "echo 'browser-cmd'", "source": "user"}`, // Simulate browser command ], postWebSocketCommands: [ `ssh_exec {"sessionName": "${sessionName}", "command": "echo 'mcp-post'"}`, ], workflowTimeout: 30000, sessionName: sessionName }; const result = await testUtils.runTerminalHistoryTest(config); const responses = result.concatenatedResponses; // Verify all three commands executed expect(responses).toContain('mcp-pre'); expect(responses).toContain('browser-cmd'); expect(responses).toContain('mcp-post'); // Check for double prompting on the post-WebSocket MCP command const doublePromptPattern = /\[jsbattig@localhost[^\]]*\]\$\s+\[jsbattig@localhost[^\]]*\]\$\s+echo\s+'mcp-post'/; expect(responses).not.toMatch(doublePromptPattern); // Verify proper single prompting const singlePromptPattern = /\[jsbattig@localhost[^\]]*\]\$\s+echo\s+'mcp-post'/; expect(responses).toMatch(singlePromptPattern); }, 45000); });

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