{"_id":"@accelerated-software-development/playwright-terminal-kit","name":"@accelerated-software-development/playwright-terminal-kit","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@accelerated-software-development/playwright-terminal-kit","version":"0.1.0","description":"Playwright testing library for CLI/TUI applications using ttyd and tmux","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"},"./fixtures":{"import":"./dist/testing/fixture.js","types":"./dist/testing/fixture.d.ts"}},"scripts":{"build":"tsc","dev":"tsc --watch","test":"bun test tests/","test:e2e":"playwright test examples/","typecheck":"tsc --noEmit","prepublishOnly":"npm run build"},"keywords":["playwright","ttyd","tmux","terminal","tui","cli","testing","snapshot","e2e"],"author":{"name":"ASD Engineering"},"license":"MIT","engines":{"node":">=18.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"repository":{"type":"git","url":"git+https://github.com/asd-engineering/playwright-terminal-kit.git"},"bugs":{"url":"https://github.com/asd-engineering/playwright-terminal-kit/issues"},"homepage":"https://github.com/asd-engineering/playwright-terminal-kit#readme","dependencies":{"ws":"^8.18.0","zod":"^3.24.0"},"devDependencies":{"@types/node":"^22.10.0","@types/ws":"^8.5.13","typescript":"^5.7.0"},"peerDependencies":{"@playwright/test":"^1.40.0"},"peerDependenciesMeta":{"@playwright/test":{"optional":false}},"gitHead":"79c40196f9a778e18425c1389fbef3eb336be09a","_id":"@accelerated-software-development/playwright-terminal-kit@0.1.0","_nodeVersion":"22.22.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-fFvauj6+tWnz1ifCSK+eluvn6tvROrH6fwtbGc/t/3fWReQJE/FqBAxd3vcbyRbmMChmqF8ChZJQwES3/HDXHw==","shasum":"f8c2fc286c39fb9966e72e7d7a1af8138bbe58fa","tarball":"https://registry.npmjs.org/@accelerated-software-development/playwright-terminal-kit/-/playwright-terminal-kit-0.1.0.tgz","fileCount":63,"unpackedSize":282929,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIG40GfWKN3HZ5o3be8HsN8R8+c0n5jpa/DSlgc9EKRaEAiACFmOvNiro0XOs18ktZehDPOKgCPWanOILnwHNO97JZg=="}]},"_npmUser":{"name":"kelvin.id","email":"contact@kelvin.id"},"directories":{},"maintainers":[{"name":"kelvin.id","email":"contact@kelvin.id"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/playwright-terminal-kit_0.1.0_1775577943523_0.6010086100947052"},"_hasShrinkwrap":false}},"time":{"created":"2026-04-07T16:05:43.437Z","0.1.0":"2026-04-07T16:05:43.698Z","modified":"2026-04-07T16:05:43.994Z"},"maintainers":[{"name":"kelvin.id","email":"contact@kelvin.id"}],"description":"Playwright testing library for CLI/TUI applications using ttyd and tmux","homepage":"https://github.com/asd-engineering/playwright-terminal-kit#readme","keywords":["playwright","ttyd","tmux","terminal","tui","cli","testing","snapshot","e2e"],"repository":{"type":"git","url":"git+https://github.com/asd-engineering/playwright-terminal-kit.git"},"author":{"name":"ASD Engineering"},"bugs":{"url":"https://github.com/asd-engineering/playwright-terminal-kit/issues"},"license":"MIT","readme":"# @accelerated-software-development/playwright-terminal-kit\n\nPlaywright testing library for CLI/TUI applications using **ttyd** and **tmux**.\n\nFeatures:\n- **Visual snapshot testing** - Capture and compare terminal states\n- **Browser automation** - Test terminals via Playwright in real browsers\n- **WebSocket client** - Direct terminal communication for headless testing\n- **tmux integration** - Deterministic terminal dimensions and state control\n- **Command injection** - Pass commands via URL parameters\n\n## Installation\n\n```bash\nnpm install @accelerated-software-development/playwright-terminal-kit @playwright/test\n# or\npnpm add @accelerated-software-development/playwright-terminal-kit @playwright/test\n# or\nbun add @accelerated-software-development/playwright-terminal-kit @playwright/test\n```\n\n### Prerequisites\n\n- **ttyd** - Terminal emulator over HTTP ([installation](https://github.com/tsl0922/ttyd#installation))\n- **tmux** (optional) - For deterministic session control\n- **Playwright** - Browser automation\n\n```bash\n# macOS\nbrew install ttyd tmux\n\n# Ubuntu/Debian\napt install ttyd tmux\n\n# Or download ttyd binary from:\n# https://github.com/tsl0922/ttyd/releases\n```\n\n## Quick Start\n\n```typescript\nimport { test, expect } from '@accelerated-software-development/playwright-terminal-kit';\n\ntest('CLI shows help', async ({ terminal }) => {\n  await terminal.type('my-cli --help');\n  await terminal.press('Enter');\n  await terminal.waitForText('Usage:');\n});\n\ntest('TUI navigation', async ({ terminal, takeSnapshot }) => {\n  await terminal.type('my-tui');\n  await terminal.press('Enter');\n  await terminal.press('Tab');\n\n  const snapshot = await takeSnapshot('menu-state');\n  expect(snapshot.text).toContain('[Dashboard]');\n});\n```\n\n## API Overview\n\n### Server Components\n\n#### TtydServer\n\nManages ttyd process lifecycle:\n\n```typescript\nimport { TtydServer } from '@accelerated-software-development/playwright-terminal-kit';\n\nconst server = new TtydServer({\n  port: 0,  // Dynamic allocation\n  shell: 'bash',\n  auth: { username: 'user', password: 'pass' }\n});\n\nconst { port, url, authUrl } = await server.start();\nconsole.log(`ttyd running at ${url}`);\n\n// Later...\nawait server.stop();\n```\n\n#### TmuxSession\n\nProvides deterministic terminal control:\n\n```typescript\nimport { TmuxSession } from '@accelerated-software-development/playwright-terminal-kit';\n\nconst session = new TmuxSession({\n  sessionName: 'test-session',\n  size: { cols: 120, rows: 40 }\n});\n\nawait session.create();\n\n// Send input\nawait session.sendText('echo hello');\nawait session.sendKeys(['Enter']);\n\n// Wait for output\nawait session.waitForText('hello');\n\n// Capture state\nconst snapshot = await session.snapshot('after-echo');\nconsole.log(snapshot.text);\n\n// Cleanup\nawait session.destroy();\n```\n\n### Client Components\n\n#### PlaywrightTerminal\n\nPage object for browser-based terminal interaction:\n\n```typescript\nimport { PlaywrightTerminal } from '@accelerated-software-development/playwright-terminal-kit';\n\n// In a Playwright test\nconst terminal = new PlaywrightTerminal(page);\n\nawait terminal.goto('http://localhost:7681/', {\n  auth: { username: 'user', password: 'pass' }\n});\n\nawait terminal.waitForTerminalReady();\nawait terminal.type('ls -la');\nawait terminal.press('Enter');\nawait terminal.waitForText('total');\n\nconst content = await terminal.getContent();\nconsole.log(content.text);\n```\n\n#### WebSocketClient\n\nDirect terminal communication (no browser needed):\n\n```typescript\nimport { WebSocketClient } from '@accelerated-software-development/playwright-terminal-kit';\n\nconst client = new WebSocketClient({\n  server: 'http://localhost:7681',\n  username: 'user',\n  password: 'pass'\n});\n\nawait client.connect();\n\nconst result = await client.execute('echo hello');\nconsole.log(result.output); // \"hello\"\n\nawait client.disconnect();\n```\n\n### Test Fixtures\n\nThe library provides Playwright test fixtures:\n\n```typescript\nimport { test, expect } from '@accelerated-software-development/playwright-terminal-kit';\n\ntest.describe('My CLI', () => {\n  test('shows version', async ({ terminal }) => {\n    await terminal.runCommand('my-cli --version');\n    await terminal.waitForText('1.0.0');\n  });\n\n  test('interactive mode', async ({ terminal, tmuxSession, takeSnapshot }) => {\n    await terminal.runCommand('my-cli interactive');\n\n    // Navigate TUI\n    await terminal.press('Tab');\n    await terminal.press('Enter');\n\n    // Capture for comparison\n    const snapshot = await takeSnapshot('interactive-menu');\n    expect(snapshot.text).toContain('Select option');\n  });\n});\n```\n\n### Custom Matchers\n\nExtend Playwright's expect with terminal-specific matchers:\n\n```typescript\nimport { expect } from '@playwright/test';\nimport { extendExpect } from '@accelerated-software-development/playwright-terminal-kit';\n\nextendExpect();\n\ntest('terminal matchers', async ({ terminal }) => {\n  const content = await terminal.getContent();\n\n  expect(content).toContainTerminalText('$');\n  expect(content).toMatchTerminalPattern(/user@host/);\n  expect(content).toShowPrompt();\n});\n```\n\n### Snapshot Testing\n\nCompare terminal output against saved snapshots:\n\n```typescript\nimport { SnapshotManager } from '@accelerated-software-development/playwright-terminal-kit';\n\nconst manager = new SnapshotManager({\n  snapshotDir: './__snapshots__',\n  stripAnsi: true,\n  normalizeWhitespace: true\n});\n\n// Save snapshot\nawait manager.save('my test', snapshot);\n\n// Compare with saved\nconst result = await manager.compare('my test', snapshot);\nif (!result.matches) {\n  console.log(result.diff);\n}\n```\n\nUpdate snapshots by setting `UPDATE_SNAPSHOTS=1`:\n\n```bash\nUPDATE_SNAPSHOTS=1 npx playwright test\n```\n\n### Utilities\n\n#### Key Codes\n\n```typescript\nimport { keyToBytes, keysToBytes } from '@accelerated-software-development/playwright-terminal-kit';\n\nkeyToBytes('Tab')      // [9]\nkeyToBytes('Ctrl+C')   // [3]\nkeyToBytes('Enter')    // [13]\nkeyToBytes('hello')    // [104, 101, 108, 108, 111]\n```\n\n#### Port Allocation\n\n```typescript\nimport { getRandomPort, isPortAvailable } from '@accelerated-software-development/playwright-terminal-kit';\n\nconst port = await getRandomPort();\nconst available = await isPortAvailable(3000);\n```\n\n#### ANSI Utilities\n\n```typescript\nimport { stripAnsi, normalizeTerminalOutput } from '@accelerated-software-development/playwright-terminal-kit';\n\nconst plain = stripAnsi('\\x1b[32mHello\\x1b[0m');  // \"Hello\"\nconst normalized = normalizeTerminalOutput(rawOutput);\n```\n\n## Configuration\n\n### TtydServer Options\n\n```typescript\ninterface TtydServerConfig {\n  port?: number;           // 0 for dynamic allocation\n  shell?: string;          // Shell command (default: \"bash\")\n  cwd?: string;            // Working directory\n  basePath?: string;       // URL base path (default: \"/\")\n  auth?: { username: string; password: string };\n  extraArgs?: string[];    // Additional ttyd arguments\n  binaryPath?: string;     // Custom ttyd binary path\n  writable?: boolean;      // Enable input (default: true)\n}\n```\n\n### TmuxSession Options\n\n```typescript\ninterface TmuxSessionConfig {\n  sessionName: string;     // Unique session name\n  size?: { cols: number; rows: number };  // Terminal dimensions\n  shell?: string;          // Shell (default: \"bash\")\n  cwd?: string;            // Working directory\n  env?: Record<string, string>;  // Environment variables\n}\n```\n\n### Snapshot Options\n\n```typescript\ninterface SnapshotConfig {\n  snapshotDir?: string;    // Where to save snapshots\n  stripAnsi?: boolean;     // Remove ANSI codes (default: true)\n  normalizeWhitespace?: boolean;  // Normalize whitespace (default: true)\n  ignorePatterns?: (string | RegExp)[];  // Patterns to ignore\n  updateSnapshots?: boolean;  // Update mode\n}\n```\n\n## Command Injection\n\nWhen ttyd is started with `--url-arg`, commands can be passed via URL:\n\n```typescript\nimport { buildCommandUrl, buildJustUrl } from '@accelerated-software-development/playwright-terminal-kit';\n\n// Single command\nconst url = buildCommandUrl('http://localhost:7681/', 'vim file.txt');\n// http://localhost:7681/?arg=vim%20file.txt\n\n// Just recipe\nconst justUrl = buildJustUrl('http://localhost:7681/', 'dev', ['--port=3000']);\n// http://localhost:7681/?arg=just%20dev%20--port%3D3000\n```\n\n## Tips\n\n### Waiting for Terminal Ready\n\nAlways wait for the terminal to be ready before interacting:\n\n```typescript\nawait terminal.waitForTerminalReady();\n```\n\n### Handling Timing\n\nFor TUI applications, use `waitForIdle` to ensure the screen has stabilized:\n\n```typescript\nawait terminal.press('Tab');\nawait terminal.waitForIdle(500);  // Wait 500ms with no changes\n```\n\n### Debugging\n\nTake screenshots on test failure:\n\n```typescript\ntest.afterEach(async ({ terminal }, testInfo) => {\n  if (testInfo.status !== 'passed') {\n    await terminal.screenshot({ path: `failure-${testInfo.title}.png` });\n  }\n});\n```\n\n### CI Environment\n\nEnsure ttyd is available in CI:\n\n```yaml\n# GitHub Actions example\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v4\n      - name: Install ttyd\n        run: |\n          wget -qO ttyd https://github.com/tsl0922/ttyd/releases/download/1.7.7/ttyd.x86_64\n          chmod +x ttyd\n          sudo mv ttyd /usr/local/bin/\n      - name: Install dependencies\n        run: npm ci\n      - name: Run tests\n        run: npx playwright test\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-f5db142f45dfdc6a004aac5ecfd02655"}