From 1ef91b7bb158198da39214d82a5cfb97bbf3441b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Aguilar?= Date: Mon, 18 May 2026 19:45:54 -0500 Subject: [PATCH] fix(test): strip ANSI codes from Ink TUI test assertions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three TUI component tests were broken on main because Ink 6.8.0 emits ANSI escape codes from ``, ``, and `` even when the renderer is not attached to a TTY. The affected assertions compare `lastFrame()` against plain strings, so the ANSI bytes inside the frame caused these to fail: src/cli/tui/components/__tests__/DeployStatus.test.tsx: - 'shows "Deploying to AWS" when not complete' - 'ignores non-resource-event messages (non-I5502 codes)' (frame contains `\u001b[90m╭…` from + bordered ) src/cli/tui/components/__tests__/LogPanel.test.tsx: - 'renders "No output yet" with no other content' (frame is `\u001b[2mNo output yet\u001b[22m` from ) src/cli/tui/components/__tests__/SecretInput.test.tsx: - 'renders placeholder when value is empty' (placeholder is split into + , so the literal substring 'sk-...' has ANSI codes between 's' and 'k-...') Fix: import `strip-ansi` (already a transitive dep, now declared as a devDependency) and apply it to `lastFrame()` in the four affected assertions. Other assertions in the same files were left untouched because they pass through plain log lines / system messages that are already ANSI-free. Verified locally: Before: Test Files 3 failed | 270 passed (273) | Tests 4 failed | 3912 passed (3916) After: Test Files 273 passed (273) | Tests 3916 passed (3916) --- package-lock.json | 1 + package.json | 1 + src/cli/tui/components/__tests__/DeployStatus.test.tsx | 5 +++-- src/cli/tui/components/__tests__/LogPanel.test.tsx | 3 ++- src/cli/tui/components/__tests__/SecretInput.test.tsx | 3 ++- 5 files changed, 9 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index caacc4419..3103dc91a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -79,6 +79,7 @@ "node-pty": "^1.1.0", "prettier": "^3.7.4", "secretlint": "^12.2.0", + "strip-ansi": "^7.2.0", "tsx": "^4.21.0", "typescript": "^5", "typescript-eslint": "^8.50.1", diff --git a/package.json b/package.json index 1ab3763c8..a5a5de9f2 100644 --- a/package.json +++ b/package.json @@ -143,6 +143,7 @@ "node-pty": "^1.1.0", "prettier": "^3.7.4", "secretlint": "^12.2.0", + "strip-ansi": "^7.2.0", "tsx": "^4.21.0", "typescript": "^5", "typescript-eslint": "^8.50.1", diff --git a/src/cli/tui/components/__tests__/DeployStatus.test.tsx b/src/cli/tui/components/__tests__/DeployStatus.test.tsx index fedca8e1a..b661ec13c 100644 --- a/src/cli/tui/components/__tests__/DeployStatus.test.tsx +++ b/src/cli/tui/components/__tests__/DeployStatus.test.tsx @@ -2,6 +2,7 @@ import type { DeployMessage } from '../../../cdk/toolkit-lib/index.js'; import { DeployStatus } from '../DeployStatus.js'; import { render } from 'ink-testing-library'; import React from 'react'; +import stripAnsi from 'strip-ansi'; import { describe, expect, it } from 'vitest'; function makeMsg( @@ -28,7 +29,7 @@ describe('DeployStatus', () => { it('shows "Deploying to AWS" when not complete', () => { const { lastFrame } = render(); - expect(lastFrame()).toContain('Deploying to AWS'); + expect(stripAnsi(lastFrame()!)).toContain('Deploying to AWS'); }); it('shows success message when complete without error', () => { @@ -90,7 +91,7 @@ describe('DeployStatus', () => { const { lastFrame } = render(); // Should show deploying text but no resource lines - expect(lastFrame()).toContain('Deploying to AWS'); + expect(stripAnsi(lastFrame()!)).toContain('Deploying to AWS'); expect(lastFrame()).not.toContain('Some general info'); }); diff --git a/src/cli/tui/components/__tests__/LogPanel.test.tsx b/src/cli/tui/components/__tests__/LogPanel.test.tsx index e7e445e48..28003ed84 100644 --- a/src/cli/tui/components/__tests__/LogPanel.test.tsx +++ b/src/cli/tui/components/__tests__/LogPanel.test.tsx @@ -2,6 +2,7 @@ import type { LogEntry } from '../LogPanel.js'; import { LogPanel } from '../LogPanel.js'; import { render } from 'ink-testing-library'; import React from 'react'; +import stripAnsi from 'strip-ansi'; import { afterEach, describe, expect, it, vi } from 'vitest'; const UP_ARROW = '\x1B[A'; @@ -19,7 +20,7 @@ describe('LogPanel', () => { describe('empty state', () => { it('renders "No output yet" with no other content', () => { const { lastFrame } = render(); - expect(lastFrame()).toBe('No output yet'); + expect(stripAnsi(lastFrame()!)).toBe('No output yet'); }); }); diff --git a/src/cli/tui/components/__tests__/SecretInput.test.tsx b/src/cli/tui/components/__tests__/SecretInput.test.tsx index 3b326ea2a..cf00b0378 100644 --- a/src/cli/tui/components/__tests__/SecretInput.test.tsx +++ b/src/cli/tui/components/__tests__/SecretInput.test.tsx @@ -1,6 +1,7 @@ import { ApiKeySecretInput, SecretInput } from '../SecretInput.js'; import { render } from 'ink-testing-library'; import React from 'react'; +import stripAnsi from 'strip-ansi'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { z } from 'zod'; @@ -34,7 +35,7 @@ describe('SecretInput', () => { ); - expect(lastFrame()).toContain('sk-...'); + expect(stripAnsi(lastFrame()!)).toContain('sk-...'); }); it('masks input with default * character', async () => {