with one click
testing-api-assertions
// Verify API requests in tests. Use when testing that correct API calls are made for create, update, or delete operations. Use when testing mutations, form submissions, or actions with backend side effects.
// Verify API requests in tests. Use when testing that correct API calls are made for create, update, or delete operations. Use when testing mutations, form submissions, or actions with backend side effects.
Remediate security vulnerabilities found by Grype or pnpm audit. Use when a security scan fails, a CVE needs fixing, or you need to analyze, upgrade, override, or ignore a vulnerable dependency.
Deep links in ToolHive Studio. Use when implementing, debugging, or asking about deep link features (toolhive-gui:// protocol), adding new deep link intents, understanding the deep link architecture, IPC model, or platform/packaging support.
Spin up and interact with ToolHive Studio's containerized dev environment (Xvfb + noVNC + DinD). Use when running, testing, or debugging the app in isolation — locally, in a git worktree, or in GitHub Codespaces; when touching `.devcontainer/*`, `scripts/devcontainer-*.sh`, or the `devContainer:dev` npm script; or when debugging "blank white window", "Docker daemon failed to start", or "Missing X server" errors in the devcontainer. The container is fully isolated: no host pnpm install, no host Docker socket, no host X11/GPU — experiment freely without contaminating the host.
Reproduce and fix bugs using TDD. Use when analyzing a bug report, writing a regression test, or applying a minimal fix. Covers test placement, mock patterns, and the red-green-refactor workflow for automated bug fixing.
Start here for all API mocking in tests. Covers auto-generation, fixtures, and when to use other skills. Required reading before creating, refactoring, or modifying any test involving API calls.
Test that components send correct query parameters or request arguments. Use when testing filtering, sorting, pagination, or any read operation where request parameters matter. Use for test-scoped mock customization.
| name | testing-api-assertions |
| description | Verify API requests in tests. Use when testing that correct API calls are made for create, update, or delete operations. Use when testing mutations, form submissions, or actions with backend side effects. |
Verify that your code sends the correct API requests for operations with side effects.
DO use for operations with side effects:
DON'T use for read operations:
Use recordRequests() to capture all API requests made during a test:
import { recordRequests } from '@/common/mocks/node'
it('creates a group with correct payload', async () => {
const rec = recordRequests()
// ... perform action that triggers API call ...
await userEvent.click(screen.getByRole('button', { name: /create/i }))
// Find the request
const request = rec.recordedRequests.find(
(r) => r.method === 'POST' && r.pathname === '/api/v1beta/groups'
)
// Assert it was made with correct data
expect(request).toBeDefined()
expect(request?.payload).toEqual({ name: 'my-group' })
})
Each recorded request contains:
{
pathname: '/api/v1beta/groups', // URL path
method: 'POST', // HTTP method
payload: { name: 'my-group' }, // Parsed JSON body (if present)
search: { filter: 'active' }, // Query parameters
}
const rec = recordRequests()
// ... trigger create action ...
const createRequest = rec.recordedRequests.find(
(r) => r.method === 'POST' && r.pathname === '/api/v1beta/workloads'
)
expect(createRequest?.payload).toMatchObject({
name: 'my-server',
group: 'default',
})
const rec = recordRequests()
// ... trigger delete action ...
const deleteRequest = rec.recordedRequests.find(
(r) =>
r.method === 'DELETE' && r.pathname === '/api/v1beta/workloads/my-server'
)
expect(deleteRequest).toBeDefined()
const rec = recordRequests()
// ... trigger actions ...
const postRequests = rec.recordedRequests.filter((r) => r.method === 'POST')
const groupIndex = postRequests.findIndex((r) => r.pathname.includes('/groups'))
const workloadIndex = postRequests.findIndex((r) =>
r.pathname.includes('/workloads')
)
// Group must be created before workload
expect(groupIndex).toBeLessThan(workloadIndex)
const rec = recordRequests()
// ... trigger batch action ...
const deleteRequests = rec.recordedRequests.filter(
(r) =>
r.method === 'DELETE' && r.pathname.startsWith('/api/v1beta/workloads/')
)
expect(deleteRequests).toHaveLength(3)
recordRequests() clears previous recordings when calledtoMatchObject() for partial matching when payload has extra fieldsFor read operations (GET) where you need to verify query parameters are sent correctly, don't use recordRequests(). Instead, use conditional overrides that return different data based on params, then verify the UI shows the expected data. See testing-api-overrides skill.
This approach is more robust because it tests actual user-facing behavior.