Skip to main content

TUI Testing Guide

Comprehensive guide to terminal user interface testing with @esimplicity/stack-tests.

Overview

TUI (Terminal User Interface) testing validates CLI applications and terminal-based interfaces using tmux-based simulation. Use @tui tagged steps for terminal testing.

Prerequisites

Install tmux

# macOS
brew install tmux

# Ubuntu/Debian
sudo apt-get install tmux

# Fedora
sudo dnf install tmux

# Verify
tmux -V

Install tui-tester

npm install -D tui-tester

Configuration

Enable TUI in Fixtures

// features/steps/fixtures.ts
import {
createBddTest,
TuiTesterAdapter,
} from '@esimplicity/stack-tests';

export const test = createBddTest({
createTui: () => new TuiTesterAdapter({
command: ['node', 'dist/cli.js'], // Your CLI command
size: { cols: 100, rows: 30 }, // Terminal size
debug: process.env.DEBUG === 'true',
cwd: process.cwd(), // Working directory
}),
});

Register TUI Steps

// features/steps/steps.ts
import { registerTuiSteps } from '@esimplicity/stack-tests/steps';

registerTuiSteps(test);

Add TUI Project

// playwright.config.ts
import { resolveWorkers } from '@esimplicity/stack-tests';

const tuiBdd = defineBddProject({
name: 'tui',
features: 'features/tui/**/*.feature',
steps: 'features/steps/**/*.ts',
tags: '@tui',
});

export default defineConfig({
projects: [
apiBdd,
uiBdd,
// TUI tests must run sequentially -- resolveWorkers enforces workers: 1
{ ...tuiBdd, workers: resolveWorkers({ testType: 'tui' }) },
],
});

Basic Usage

Start and Stop

@tui
Scenario: Basic TUI test
Given I start the TUI application
Then I should see "Welcome"
When I stop the TUI application

Typing Text

@tui
Scenario: Type commands
Given I start the TUI application
When I type "hello world"
And I press enter
Then I should see "You typed: hello world"

Keyboard Input

@tui
Scenario: Keyboard navigation
Given I start the TUI application
When I press "down"
And I press "down"
And I press "enter"
Then I should see "Option 2 selected"

Input Steps

Basic Typing

# Instant typing
When I type "command"

# Slow typing (50ms delay between characters)
When I type "command" slowly

Key Presses

# Common keys
When I press enter
When I press tab
When I press escape

# Arrow keys
When I press "up"
When I press "down"
When I press "left"
When I press "right"

# Function keys
When I press "f1"
When I press "f12"

# Other keys
When I press "home"
When I press "end"
When I press "pageup"
When I press "pagedown"
When I press "backspace"
When I press "delete"

Modifier Keys

# Ctrl combinations
When I press "c" with ctrl
When I press "s" with ctrl
When I press ctrl+c

# Alt combinations
When I press "f" with alt
When I press alt+f

# Shift combinations
When I press "tab" with shift
When I press shift+tab

# Multiple modifiers
When I press ctrl+shift+s

Field Input

# Fill labeled field
When I fill the TUI field "Username" with "admin"
When I enter "password123" in the "Password" field
@tui
Scenario: Navigate menu
Given I start the TUI application
When I navigate down 3 times
And I press enter
Then I should see "Settings"

When I navigate up 2 times
And I press enter
Then I should see "Dashboard"

Screen Navigation

@tui
Scenario: Navigate screens
Given I start the TUI application
When I navigate to "Settings" and select
Then I should see "Configuration Options"
When I go back
Then I should see "Main Menu"

Assertions

Text Visibility

# Wait for text (with timeout)
Then I should see "Welcome"
Then I should see "Welcome" in the terminal
Then I should see text "Loading complete"

# Immediate check
Then the screen should contain "Menu"

# Negative assertion
Then I should not see "Error"

Pattern Matching

Then the screen should match pattern "Version: \d+\.\d+\.\d+"

Timed Assertions

# Wait with explicit timeout
When I wait for "Ready" for 10 seconds

Line-Specific Assertions

# Check specific lines
Then line 1 should contain "Application Title"
Then the first line should contain "Title"
Then the last line should contain "Status: Ready"

Multiple Text Assertions

Then I should see all of:
| Welcome |
| Main Menu |
| Press ? for help |

Then I should not see any of:
| Error |
| Exception |
| Failed |

Forms

Fill Form

@tui
Scenario: Complete form
Given I start the TUI application
When I fill the form:
| field | value |
| Username | admin |
| Password | secret123 |
| Email | admin@example.com |
And I submit the form
Then I should see "Form submitted"

Submit Methods

# Press Enter
When I submit the form

# Press Ctrl+S
When I submit the form with ctrl+s

Select Menu Items

When I select "Settings"
When I select option "Preferences"
When I select menu item "Exit"

Open Menu

When I open the menu
# Presses Alt+M
When I select from dropdown "Country" value "United States"

Dialogs

Confirmation Dialogs

# Confirm (types 'y' + Enter)
When I confirm the dialog

# Cancel (types 'n' + Enter)
When I cancel the dialog

# Dismiss (presses Escape)
When I dismiss the dialog

Commands

Execute CLI Commands

@tui
Scenario: Run commands
Given I start the TUI application
When I execute command "help"
Then I should see "Available commands"

When I run "list users"
Then I should see "User List"

Snapshots

Take Snapshots

@tui
Scenario: Capture screen state
Given I start the TUI application
Then I take a snapshot named "main-menu"

Compare Snapshots

@tui
Scenario: Verify screen layout
Given I start the TUI application
Then the screen should match snapshot "main-menu"

Snapshot Storage

Configure snapshot directory:

createTui: () => new TuiTesterAdapter({
command: ['node', 'dist/cli.js'],
snapshotDir: './snapshots/tui',
}),

Screen Capture

Capture for Debugging

When I capture the screen
# Stores in world.vars['lastScreenCapture']
Then I print the screen
# Outputs to console

Utility Steps

Clear Screen

When I clear the terminal

Resize Terminal

When I resize the terminal to 120x40

Wait

When I wait 2 seconds
When I wait for "Loading..." for 30 seconds

Complete Examples

CLI Tool Test

@tui
Feature: CLI Tool

Scenario: Help command
Given I start the TUI application
When I execute command "help"
Then I should see "Usage:"
And I should see "Commands:"
And I should see all of:
| init |
| build |
| deploy |

Scenario: Interactive mode
Given I start the TUI application
When I execute command "init"
Then I should see "Project name:"
When I type "my-project"
And I press enter
Then I should see "Template:"
When I navigate down 2 times
And I press enter
Then I should see "Project created successfully"

TUI Dashboard

@tui
Feature: Dashboard TUI

Background:
Given I start the TUI application
And I should see "Login"

Scenario: Login and navigate
When I enter "admin" in the "Username" field
And I press tab
And I enter "secret" in the "Password" field
And I submit the form
Then I should see "Dashboard"
And the screen should match snapshot "dashboard-home"

Scenario: Navigate to settings
When I enter "admin" in the "Username" field
And I press tab
And I enter "secret" in the "Password" field
And I submit the form
When I press "s"
Then I should see "Settings"
And I should see all of:
| Theme |
| Language |
| Shortcuts |
@tui
Feature: Menu Application

Scenario: Full menu navigation
Given I start the TUI application
Then I should see "Main Menu"

# Navigate to Files
When I navigate down 1 times
And I press enter
Then I should see "File Browser"

# Go back
When I go back
Then I should see "Main Menu"

# Navigate to Settings
When I navigate down 3 times
And I press enter
Then I should see "Settings"

# Change a setting
When I select menu item "Theme"
And I navigate down 2 times
And I press enter
Then I should see "Theme: Dark"

# Exit
When I quit the application

Environment Configuration

# .env
DEBUG=false

Enable debug mode for troubleshooting:

DEBUG=true npm test -- --project=tui

Best Practices

Wait for Ready State

# Good - wait for application to be ready
Given I start the TUI application
And I should see "Ready" # or specific prompt

# Avoid - no wait
Given I start the TUI application
When I type "command" # might fail if not ready

Use Meaningful Snapshots

# Good - descriptive names
Then the screen should match snapshot "login-form-empty"
Then the screen should match snapshot "login-form-error-invalid-password"

# Avoid - generic names
Then the screen should match snapshot "screen1"

Test Keyboard Navigation

# Test both keyboard and menu navigation
Scenario: Keyboard navigation
When I press "s" # Shortcut for Settings
Then I should see "Settings"

Scenario: Menu navigation
When I select menu item "Settings"
Then I should see "Settings"

Handle Loading States

When I execute command "load-data"
When I wait for "Loading..." for 2 seconds
Then I should see "Data loaded"
# Or use: When I wait for "Data loaded" for 30 seconds

Troubleshooting

tmux Not Found

# Check tmux is installed
which tmux

# Install if missing
brew install tmux # macOS

Application Not Starting

// Enable debug mode
createTui: () => new TuiTesterAdapter({
command: ['node', 'dist/cli.js'],
debug: true, // Shows all tmux commands
}),

Timing Issues

# Add explicit waits
Given I start the TUI application
When I wait for "Ready" # Wait for prompt
When I type "command"

CI/CD Issues

See CI/CD Integration for running TUI tests in pipelines.