Skip to content
Back to skills

Write Test

ASecurity

Use when writing or changing a test for paneline hooks or draw functions.

  • 3 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added October 6, 2026
ai-agentstesting

Works with

  • terminal
  • cli
  • mcp

Security analysis

A100/100

Scanned October 6, 2026

npx -y skills add markneonin/paneline --skill write-test --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Write Test?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Write Test
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/markneonin-write-test/badge)](https://www.skillsdirectory.com/skills/markneonin-write-test)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: write-test
description: Use when writing or changing a test for paneline hooks or draw functions.
---

# Write a test

Tests run only with `claude plugin test .` (also part of `npm run check`). They run in a sandbox like the plugin's own: no file system, no network, no process.

## Layout and names

- One file per area: `tests/<area>.test.ts`, or `.test.tsx` when it mounts UI. Shared helpers for draw trees are in `tests/draw-tree.ts`.
- Import from `claude-code/testing`: `describe`, `expect`, `test`, `mock`. Types `Engine`, `Mounted` come from the same module.
- `describe("<area>")`, then tests named `<ID> <what the user sees>`, for example `M3 clicking a server selects it and shows its actions`. IDs are one letter and a number per file.
- Test body: `async ($, on) => { ... }`. `$` is the engine, `on` registers fake engine hooks.

## Build the fake world

Copy the `worldOf(on)` helper from the nearest test file, for example `tests/mcp-pane.test.tsx`. It:

- calls `mock.clock(on, { now })` and `mock.env(on, { HOME: "/h/u" })`;
- answers the engine events the code under test calls, such as `session.usage` and `ui.open`, with fixed data;
- returns a `world` object that records calls (commands run, usage fetches) for assertions.

## Mount and act

```
const pane = await $.ui.mount({ plugin: "paneline", surface: "terminal", component: "Pane",
  requestId: "session", props: { title: "Session", isFocused: false, bodyColumns: 60,
  placement: "dock", scroll: { offset: 0, bodyRows: 40 }, view: {} },
  viewport: { columns: 60, rows: 40 } })
```

- Find: `pane.findAll({ type: "Button" })`, `pane.find({ type: "Text", text })`.
- Act: `pane.press({ key })`. Read the tree: `pane.drawn()`.
- Chat parts mount the same way with their own component name, see `tests/reply.test.tsx`.

## Assert

- Assert drawn text, theme keys from `palette`, and the keys written to state. Not private variables.
- Name numbers as constants at the top of the file.
- Pure helpers, such as `fitTabs`, are tested by calling them directly (`tests/tab-bar.test.ts`).
- A new behaviour needs a test that fails without it. Check by breaking the code once.
- No comments in tests.

`claude plugin test .` runs every test file. To run one file, copy the folder with only that file under `tests/`, or accept the full run: it is fast.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…