with one click
qa-engineer-integration
Write integration tests for CLI commands with Vitest
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Write integration tests for CLI commands with Vitest
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Deep investigation of GitHub issues with root cause analysis and proposed solutions. Use when asked to investigate, analyze, or dig into an issue.
Generate a project spec or ticket spec. Use when asked to spec, define, design, or write a ticket for a project or task.
Triage GitHub issues or Linear tickets — classify type, assess priority, check reproducibility, detect duplicates. Use when asked to triage, assess, or categorize issues.
Plan and perform manual tests for Storyblok monoblok packages against a real, seeded Storyblok space
Drive multiple GitHub issues through the full pipeline (triage, investigate, plan, implement) in parallel. Use when asked to blitz, batch-process, or work multiple issues.
Use when writing documentation. Provides a writing style guide and content structure patterns.
| name | qa-engineer-integration |
| description | Write integration tests for CLI commands with Vitest |
Integration tests are mandatory for every new feature or behavior change. Write these tests before the implementation. Use this skill whenever a change affects CLI command behavior, API interactions, filesystem reads and writes, logging, or reporting.
preconditions helpers to set up MSW handlers, memfs state, and stubbed dependencies.command.parseAsync([...args]) and assert side effects and outputs.should.preconditions object (e.g., canLoadFiles, canLoadManifest, canCreateRemoteResources, failsToUpdateRemoteResources). Each helper should be focused, deterministic, and reusable across tests.preconditions.canCreateRemoteResources registers http.post and returns created items). This keeps request and response behavior close to the test intent.memfs and vol.fromJSON to create local files and vol.reset in afterEach to clear state. When you need path resolution, use resolveCommandPath with the command constants.index, then run command.parseAsync(['node', 'test', ...args]).expect(actions.method).toHaveBeenCalledWith(...), then check generated manifest entries, reports, log output, and console messages.Example shape (simplified):
const server = setupServer();
const preconditions = {
canLoadFiles(items: Item[]) {
const dir = resolveCommandPath(directories.items, DEFAULT_SPACE);
vol.fromJSON(Object.fromEntries(items.map(item => [path.join(dir, `${item.slug}.json`), JSON.stringify(item)])));
},
canCreateRemoteItems(items: Item[]) {
const created = items.map(item => ({ ...item, id: getID() }));
server.use(
http.post(`https://mapi.storyblok.com/v1/spaces/${DEFAULT_SPACE}/items`, async ({ request }) => {
const body = await request.json();
const match = created.find(i => i.slug === body.item.slug);
return HttpResponse.json({ item: match });
}),
);
return created;
},
};
describe('command push', () => {
beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
afterEach(() => {
vi.resetAllMocks();
vi.clearAllMocks();
vol.reset();
server.resetHandlers();
resetReporter();
});
afterAll(() => server.close());
it('should push items and write manifest/report', async () => {
preconditions.canLoadFiles([makeMockItem()]);
preconditions.canCreateRemoteItems([makeMockItem()]);
await command.parseAsync(['node', 'test', 'push', '--space', DEFAULT_SPACE]);
expect(actions.createItem).toHaveBeenCalled();
expect(await parseManifest()).toEqual([expect.objectContaining({ old_id: expect.anything() })]);
expect(getReport()).toEqual(expect.objectContaining({ status: 'SUCCESS' }));
});
});