測試
使用 @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");});任何支援 async 測試的測試執行器都能使用,包括 Bun、Vitest 和 Jest。
渲染
| 方法 | 說明 |
|---|---|
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影格會裁去右側和底部的空白,因此快照不會因空白而反覆變動。