测试

使用 @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

帧右侧和底部的空白会被裁剪,因此快照不会因空白而反复变化。

在 GitHub 上编辑此页