ワンクリックで
yaebal-test-bot
Use when writing tests for a yaebal bot — @yaebal/test actors, api-call assertions, failure injection, and the virtual clock.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Use when writing tests for a yaebal bot — @yaebal/test actors, api-call assertions, failure injection, and the virtual clock.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Use when building multi-step dialogs in a yaebal bot — choosing between scenes, conversation, and prompt, and wiring their persistence.
Use when writing or modifying a Telegram bot built on the yaebal framework — bot setup, handlers, filter queries, commands, and context typing.
Use when adding LLM features to a yaebal bot with @yaebal/ai — ctx.ai streaming replies, model adapters, conversation memory, and rate limits.
Use when writing a custom yaebal plugin — the Plugin<In, Out> contract, derive vs decorate, and typed plugin dependencies.
Use when a yaebal bot fails to compile, start, or respond — install-order type errors, ESM specifier errors, Telegram 400/409/429 responses.
Use when running a yaebal bot in production — long polling with @yaebal/runner vs webhooks with @yaebal/web, graceful shutdown, and error handling.
| name | yaebal-test-bot |
| description | Use when writing tests for a yaebal bot — @yaebal/test actors, api-call assertions, failure injection, and the virtual clock. |
createTestEnv(bot) wraps any Composer/Bot, intercepts every outgoing api call (no real
HTTP, ever), and hands you virtual users and chats that send real update shapes. works with
node:test, vitest, or any runner. install as a dev dependency: pnpm add -D @yaebal/test.
import { test } from "node:test";
import assert from "node:assert/strict";
import { createTestEnv } from "@yaebal/test";
import { bot } from "../src/bot.js";
test("replies to /start", { timeout: 5_000 }, async () => {
const env = createTestEnv(bot);
const user = env.createUser({ firstName: "linia" });
await user.sendCommand("start");
assert.equal(env.lastApiCall("sendMessage")?.params?.text, "welcome!");
});
const group = env.createChat({ type: "group", title: "devs" });
await user.sendMessage("hello");
await user.in(group).sendCommand("help");
await user.sendPhoto({ caption: "look" });
// inline buttons: grab the bot's message, click by label
const bubble = env.lastBotMessage({ withReplyMarkup: true });
if (bubble) await user.on(bubble).clickByText("Next »");
await user.click("vote:up", bubble); // or by raw callback_data
env.lastApiCall("sendMessage"); // most recent call to a method: { method, params, result }
env.callsTo("editMessageText"); // every call to a method, in order
env.apiCalls; // everything recorded
env.clearApiCalls(); // reset between phases of one test
import { apiError } from "@yaebal/test";
// first call fails with a real TelegramError shape, later calls use auto-stubs again
env.onApi("sendMessage", apiError(429, "Too Many Requests", { retry_after: 1 }), { times: 1 });
env.onApi("getMe", { id: 7, is_bot: true, first_name: "MyBot", username: "my_bot" });
const env = createTestEnv(bot);
env.useFakeTimers(); // arm before the code schedules its timer
await user.sendCommand("start"); // handler sets a 1h timeout internally
await env.advanceTime(60 * 60 * 1000); // fires instantly
env.shutdown(); // ALWAYS in teardown — restores real Date.now/timers
createTestEnv guarantees this for dispatched updates —
but do not call bot.start() inside a test: bot-level startup (getMe, onStart
hooks) goes to the real network. drive the bot through actors instead.{ timeout } to test() — a parked wait or nav bug otherwise hangs the whole
suite forever.node:test + node:assert/strict unless the project already uses another runner.createTestEnv(bot, { strictApi: true }) throws on unstubbed methods;
{ strictDispatch: true } throws when no handler consumed an update — both catch silent bugs.createUpdate,
messageUpdate, …) and await env.dispatch(update).webhookRequest(update, { secretToken }) builds the POST
for a webhookCallback(bot, ...) handler.