feat(smartshell): Add secure spawn APIs, PTY support, interactive/streaming control, timeouts and buffer limits; update README and tests
This commit is contained in:
84
test/test.interactiveControl.ts
Normal file
84
test/test.interactiveControl.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import { expect, tap } from '@git.zone/tstest/tapbundle';
|
||||
import * as smartshell from '../ts/index.js';
|
||||
|
||||
tap.test('should handle programmatic input control with simple commands', async (tools) => {
|
||||
const testSmartshell = new smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
sourceFilePaths: [],
|
||||
});
|
||||
|
||||
// Use cat which works well with pipe mode
|
||||
const interactive = await testSmartshell.execInteractiveControl('cat');
|
||||
|
||||
// Send input programmatically
|
||||
await interactive.sendLine('TestUser');
|
||||
interactive.endInput();
|
||||
|
||||
// Wait for completion
|
||||
const result = await interactive.finalPromise;
|
||||
expect(result.exitCode).toEqual(0);
|
||||
expect(result.stdout).toContain('TestUser');
|
||||
});
|
||||
|
||||
tap.test('should handle streaming interactive control with cat', async (tools) => {
|
||||
const testSmartshell = new smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
sourceFilePaths: [],
|
||||
});
|
||||
|
||||
// Use cat for reliable pipe mode operation
|
||||
const streaming = await testSmartshell.execStreamingInteractiveControl('cat');
|
||||
|
||||
// Send multiple inputs
|
||||
await streaming.sendLine('One');
|
||||
await streaming.sendLine('Two');
|
||||
streaming.endInput();
|
||||
|
||||
const result = await streaming.finalPromise;
|
||||
expect(result.exitCode).toEqual(0);
|
||||
expect(result.stdout).toContain('One');
|
||||
expect(result.stdout).toContain('Two');
|
||||
});
|
||||
|
||||
tap.test('should handle sendInput without newline', async (tools) => {
|
||||
const testSmartshell = new smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
sourceFilePaths: [],
|
||||
});
|
||||
|
||||
// Use cat for testing input without newline
|
||||
const interactive = await testSmartshell.execInteractiveControl('cat');
|
||||
|
||||
// Send characters without newline, then newline, then EOF
|
||||
await interactive.sendInput('ABC');
|
||||
await interactive.sendInput('DEF');
|
||||
await interactive.sendInput('\n');
|
||||
interactive.endInput();
|
||||
|
||||
const result = await interactive.finalPromise;
|
||||
expect(result.exitCode).toEqual(0);
|
||||
expect(result.stdout).toContain('ABCDEF');
|
||||
});
|
||||
|
||||
tap.test('should mix passthrough and interactive control modes', async () => {
|
||||
const testSmartshell = new smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
sourceFilePaths: [],
|
||||
});
|
||||
|
||||
// Test that passthrough still works
|
||||
const passthroughResult = await testSmartshell.execPassthrough('echo "Passthrough works"');
|
||||
expect(passthroughResult.exitCode).toEqual(0);
|
||||
expect(passthroughResult.stdout).toContain('Passthrough works');
|
||||
|
||||
// Test that interactive control works
|
||||
const interactiveResult = await testSmartshell.execInteractiveControl('echo "Interactive control works"');
|
||||
const finalResult = await interactiveResult.finalPromise;
|
||||
expect(finalResult.exitCode).toEqual(0);
|
||||
expect(finalResult.stdout).toContain('Interactive control works');
|
||||
});
|
||||
|
||||
// Note: Tests requiring bash read with prompts should use PTY mode
|
||||
// See test.pty.ts for examples of testing commands that require terminal features
|
||||
|
||||
export default tap.start();
|
Reference in New Issue
Block a user