테스트

@textjs/app/testing으로 화면 밖에서 앱을 렌더링하고 키를 누르며 프레임을 검증하세요.

@textjs/app/testing(또는 @textjs/react/testing)은 앱을 화면 밖에서 렌더링하고, 키를 누르고, 프레임을 텍스트로 반환해요. 테스트는 브라우저나 DevTools 없이 실행돼요.

counter.test.tsxtsx
import { afterEach, expect, test } from "bun:test";import { cleanup, render } from "@textjs/app/testing";import { Counter } from "./counter";afterEach(cleanup);test("counts up", async () => {  const app = await render(<Counter />, { cols: 40, rows: 6 });  await app.press("up up");  expect(app.lastFrame()).toContain("count = 2");});

Bun, Vitest, Jest를 비롯해 async 테스트를 지원하는 모든 러너에서 작동해요.

렌더링

메서드설명
render(el, { cols, rows, theme })화면 밖에 마운트 (기본값 80×24)
lastFrame()일반 텍스트로 된 프레임
lines()행 배열로 된 프레임
frames지금까지의 서로 다른 모든 프레임
toAnsi()스냅샷용 트루컬러 ANSI
cell(x, y){ char, fg, bg, attrs }
locate(text)첫 번째 일치 항목의 { x, y }
rerender(el) / unmount()업데이트 또는 해제

renderToString(el, options)는 한 번 렌더링하고 텍스트를 반환해요.

입력

await app.press("down");await app.press("ctrl+k");      // modifiersawait app.press("g g");         // a sequenceawait app.press("G");           // Shift+Gawait app.type("hello\n");      // one key per character, \n is Enterawait app.paste("multi\nline");await app.wheel(3);await app.resize(120, 36);

모든 호출은 act() 안에서 실행되고 결과 프레임을 모두 반영하므로, 다음 검증에서 업데이트를 확인할 수 있어요.

시간

await app.wait(300);                    // real time passes, then frames flushawait app.waitForText("Deployed");      // poll until the frame contains itawait app.waitFor(() => expect(saved).toBe(true), { timeout: 2000 });

애니메이션, 스피너, 토스트는 실제 타이머를 사용하므로, wait와 waitFor로 상태를 안정적으로 확인할 수 있어요.

스냅샷

expect(app.lastFrame()).toMatchSnapshot();expect(app.toAnsi()).toMatchSnapshot(); // colors too

프레임의 오른쪽과 아래쪽 공백을 제거하므로, 공백 때문에 스냅샷이 계속 바뀌지 않아요.

GitHub에서 이 페이지 편집