Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions test/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,24 @@ export function createSession(
return envelope.result.sessionId;
}

// An interactive bash for a test. `--norc --noprofile` keep it from reading
// ~/.bashrc and ~/.profile: a startup file that prompts, prints or ends the
// shell breaks the commands that the test types (a mise "Trust them?" prompt
// swallowed one).
export const HERMETIC_BASH = ['/bin/bash', '--norc', '--noprofile', '-i'];

// Like createSession with HERMETIC_BASH. HISTFILE=/dev/null keeps the shell
// from reading or writing ~/.bash_history.
export function createBashSession(
testHome: string,
options: CreateSessionOptions = {},
): string {
return createSession(testHome, HERMETIC_BASH, {
...options,
env: { HISTFILE: '/dev/null', ...options.env },
});
}

export function destroySession(testHome: string, sessionId: string): void {
if (sessionId.length === 0) {
return;
Expand Down
3 changes: 2 additions & 1 deletion test/integration/batch.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { CommandErrorEnvelope } from '../../src/protocol/envelope.js';

import {
cleanupHome,
createBashSession,
createSession,
destroySession,
runCli,
Expand Down Expand Up @@ -170,7 +171,7 @@ describe('batch command integration', { timeout: 45_000 }, () => {
});

it('reads the step array from --file', async () => {
sessionId = createSession(testHome, ['/bin/bash']);
sessionId = createBashSession(testHome);
await sleep(500);

const stepsPath = join(testHome, 'plan.json');
Expand Down
25 changes: 11 additions & 14 deletions test/integration/run.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { afterEach, beforeEach, describe, expect, it } from 'vitest';

import {
cleanupHome,
createBashSession,
createSession,
destroySession,
readEvents,
Expand Down Expand Up @@ -122,7 +123,7 @@ describe('run command integration', { timeout: 45_000 }, () => {
});

it('returns immediately with --no-wait', async () => {
sessionId = createSession(testHome, ['/bin/bash']);
sessionId = createBashSession(testHome);
await sleep(500);

const result = runCli(
Expand All @@ -148,7 +149,7 @@ describe('run command integration', { timeout: 45_000 }, () => {
});

it('reads command from --file', async () => {
sessionId = createSession(testHome, ['/bin/bash']);
sessionId = createBashSession(testHome);
await sleep(500);

const scriptPath = join(testHome, 'test-script.sh');
Expand All @@ -171,7 +172,7 @@ describe('run command integration', { timeout: 45_000 }, () => {
});

it('handles multiline command input', async () => {
sessionId = createSession(testHome, ['/bin/bash']);
sessionId = createBashSession(testHome);
await sleep(1000);

const result = runCli(
Expand All @@ -198,7 +199,7 @@ describe('run command integration', { timeout: 45_000 }, () => {
});

it('waits for the command to complete before reporting success', async () => {
sessionId = createSession(testHome, ['/bin/bash']);
sessionId = createBashSession(testHome);
await sleep(1000);

const start = Date.now();
Expand Down Expand Up @@ -247,7 +248,7 @@ describe('run command integration', { timeout: 45_000 }, () => {
});

it('records input_run event in the event log', async () => {
sessionId = createSession(testHome, ['/bin/bash']);
sessionId = createBashSession(testHome);
await sleep(500);

const result = runCli(
Expand Down Expand Up @@ -329,7 +330,7 @@ describe('run command integration', { timeout: 45_000 }, () => {
});

it('returns timedOut when run completion is not observed within timeout', async () => {
sessionId = createSession(testHome, ['/bin/bash']);
sessionId = createBashSession(testHome);
await sleep(500);

const result = runCli(
Expand Down Expand Up @@ -506,13 +507,9 @@ describe('run command integration', { timeout: 45_000 }, () => {
);

it('does not log postamble cursor controls when shell echo is disabled', async () => {
sessionId = createSession(
testHome,
['/bin/bash', '--noprofile', '--norc'],
{
cols: WIDE_ARTIFACT_PROOF_COLS,
},
);
sessionId = createBashSession(testHome, {
cols: WIDE_ARTIFACT_PROOF_COLS,
});
await sleep(1000);

const disableEchoResult = runCli(
Expand Down Expand Up @@ -590,7 +587,7 @@ describe('run command integration', { timeout: 45_000 }, () => {
});

it('records structured run completion without leaking sentinel text to artifacts', async () => {
sessionId = createSession(testHome, ['/bin/bash'], {
sessionId = createBashSession(testHome, {
cols: WIDE_ARTIFACT_PROOF_COLS,
});
await sleep(1000);
Expand Down
3 changes: 2 additions & 1 deletion test/integration/slow-replay.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
cleanupHome,
createSession,
destroySession,
HERMETIC_BASH,
readEvents,
sleep,
} from '../helpers.js';
Expand Down Expand Up @@ -209,7 +210,7 @@ describe(
// The host default renderer is ghostty-web, so that the catch-up replay
// after the run uses the slow backend.
await createSlowSession(
['/bin/bash'],
HERMETIC_BASH,
{
AGENT_TTY_RENDERER: 'ghostty-web',
AGENT_TTY_TEST_REPLAY_MS_PER_EVENT: '100',
Expand Down
Loading