Тестирование
Рендерите приложения вне экрана, нажимайте клавиши и проверяйте кадры с @textjs/app/testing.
@textjs/app/testing (или @textjs/react/testing) рендерит ваше приложение за пределами экрана, нажимает клавиши и возвращает кадр в виде текста. Тесты выполняются без браузера и DevTools.
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 с Truecolor для снимков |
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Пустое пространство справа и снизу кадра обрезается, поэтому снимки не меняются из-за пробельных символов.