Skip to content

Configure Termwright

Most projects can start without a Termwright config. Add one when several tests share the same command or need different viewport, timeout, trace, or environment defaults.

Create termwright.config.ts:

import { fileURLToPath } from 'node:url';
import { defineTermwrightConfig } from 'termwright/test';
const cli = fileURLToPath(new URL('./dist/cli.js', import.meta.url));
export default defineTermwrightConfig({
command: [process.execPath, cli],
columns: 100,
rows: 30,
trace: 'retain-on-failure',
});

Create termwright.setup.ts:

import { configureTermwright } from 'termwright/test';
import config from './termwright.config.js';
configureTermwright(config);

Then load the setup file from vitest.config.ts, which is read by Termwright’s embedded test engine:

export default {
test: {
setupFiles: ['./termwright.setup.ts'],
},
};

Termwright does not discover termwright.config.ts automatically. Projects that already have a test config can add the setup file to it.

The closest setting wins:

  1. project configuration;
  2. test.override({ termwrightOptions }) for a file or suite;
  3. options passed to terminal.launch().

Nested env and timeouts values merge by key. A command array is replaced as a whole.

OptionDefaultPurpose
commandnoneCommand used by terminal.launch() when no command is passed
columns100Initial terminal width in cells
rows30Initial terminal height in cells
env{}Environment variables added to launched applications
timeoutssee belowAction, text, idle, ready, exit, and assertion timeouts
traceretain-on-failureWhich test attempts keep a trace
outputDirtermwright-reportDirectory for retained traces
snapshotDir__snapshots__Snapshot directory relative to each test file
terminalProfiledefault profileCharacter width and terminal behavior profile
paletteterminal defaultsFixed 16-color palette used by color assertions and snapshots
failOnLogLevelerrorLowest structured log level that fails a passing test; use false to disable
requiredCapabilities[]Semantic capabilities that must be available when a session launches
profiles{}Named groups of overrides
updateSnapshotsfollows the CLISnapshot update policy; normally leave this unset and use --update

terminalProfile accepts only default and cjk-wide. The latter treats East Asian Ambiguous characters as wide. Both use the same Unicode 15 extended grapheme model; this setting does not select an emulator or an old Unicode version.

Session-specific options such as cwd, envMode, semantic setup, and artifact security belong on terminal.launch().

export default defineTermwrightConfig({
timeouts: {
action: 5_000,
text: 5_000,
idle: 2_000,
ready: 10_000,
exit: 10_000,
expect: 5_000,
},
});

Set the timeout for the operation that can legitimately take longer. Individual assertions also accept { timeout }. Do not increase a global timeout to hide a locator or synchronization error.

ValueBehavior
retain-on-failureKeep failed attempts and remove passing traces
on-first-retryRecord the first retry attempt
onKeep every trace
offDo not record traces

See Open traces and reports for replay and artifact handling.

Named profiles let the same test run with different terminal settings:

termwright.config.ts
export default defineTermwrightConfig({
profiles: {
compact: { columns: 80, rows: 24 },
wide: { columns: 140, rows: 40, terminalProfile: 'cjk-wide' },
},
});

Add the profiles as test projects:

vitest.config.ts
import { termwrightProjects } from 'termwright/test';
import termwright from './termwright.config.js';
export default {
test: {
setupFiles: ['./termwright.setup.ts'],
projects: termwrightProjects(termwright),
},
};

Run all configured projects with npx termwright test, or select one:

Terminal window
npx termwright test -- --project compact

Use a CI operating-system matrix for platform coverage. A terminal profile does not emulate Windows, macOS, or Linux process behavior.

The CLI resource profile selects a scheduling policy. Termwright then derives the effective worker and terminal limits from the host’s available CPUs, memory, temporary disk space, and Linux cgroup limits. A profile name is not a fixed concurrency number.

ProfileIntended useEffective limits
localNormal developmentHost-derived
ciLinux and macOS CIHost-derived
windows-ciWindows CIHost-derived
stressIntentional high-fanout capacity testsHost-derived

Run npx termwright doctor --json in the project directory to inspect the effective limits and the reason each limit was chosen. Use local for normal development, ci on Linux and macOS CI, and windows-ci on Windows CI. The stress policy deliberately permits more parallel work and is intended for capacity testing, not ordinary test runs.

A test that needs several terminals at the same time must declare them before the test starts:

test.resources({ terminals: 2 })('connects two peers', async ({ terminal }) => {
const [client, server] = await Promise.all([
terminal.launch(clientOptions),
terminal.launch(serverOptions),
]);
});

Termwright waits for the declared group to fit instead of starting a test with only part of its required capacity.

Use retries only for diagnostics. A fail-then-pass result remains flaky and returns a non-zero exit code.

vitest.config.ts
import { termwrightRetry } from 'termwright/test';
export default {
test: {
retry: termwrightRetry({ ci: 0, local: 0 }),
},
};

TERMWRIGHT_RETRIES overrides the number of additional attempts and accepts an integer from 0 through 100.

VariableMeaning
TERMWRIGHT_RETRIESNumber of additional attempts
TERMWRIGHT_DEBUG1 for driver debug output; all also includes raw PTY traffic
TERMWRIGHT_PROFILENamed Termwright profile to apply
TERMWRIGHT_UPDATE_SNAPSHOTSall, changed, missing, or none

Internal endpoint and token variables are set by Termwright. Applications and test configuration should not set them.