בדיקות

רינדור אפליקציות מחוץ למסך, לחיצה על מקשים ובדיקת פריימים עם ⁦@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