cosmicstack-labs/frontend-testing
Comprehensive frontend testing strategy covering unit, integration, E2E, visual regression, and accessibility testing
npx skills add https://github.com/cosmicstack-labs/mercury-agent-skills --skill frontend-testing
Complete testing strategy for frontend applications — from unit tests to visual regression to E2E.
╱ E2E ╲ ╱ Few, critical paths ╲
╱─────────╲ ╱ Smoke tests, auth ╲
╱ Integration ╲ ╱ Component + feature ╲
╱───────────────╲ ╱ User interaction flows ╲
╱ Unit + Component ╲╱ Logic, rendering, hooks ╲
╱────────────────────╲╱ Fast, many, isolated ╲
import { render, screen, fireEvent } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { Button } from './Button';
describe('Button', () => {
it('renders with text', () => {
render(<Button>Click me</Button>);
expect(screen.getByText('Click me')).toBeInTheDocument();
});
it('handles click events', async () => {
const onClick = vi.fn();
render(<Button onClick={onClick}>Click</Button>);
await userEvent.click(screen.getByText('Click'));
expect(onClick).toHaveBeenCalledTimes(1);
});
});
import { render, screen, waitFor } from '@testing-library/react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { ProductsList } from './ProductsList';
import { server } from '../mocks/server';
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
test('loads and displays products', async () => {
render(
<QueryClientProvider client={new QueryClient()}>
<ProductsList />
</QueryClientProvider>
);
expect(screen.getByText('Loading...')).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByText('Product A')).toBeInTheDocument();
expect(screen.getByText('Product B')).toBeInTheDocument();
});
});
import { test, expect } from '@playwright/test';
test('user can complete checkout', async ({ page }) => {
await page.goto('/products');
await page.click('text=Add to Cart');
await page.click('text=Checkout');
await page.fill('[name=email]', '[email protected]');
await page.fill('[name=card]', '4242 4242 4242 4242');
await page.click('text=Pay Now');
await expect(page.getByText('Order confirmed!')).toBeVisible();
});
// vitest.config.ts
import { defineConfig } from 'vitest/config';
export default defineConfig({
test: {
globals: true,
environment: 'jsdom',
setupFiles: ['./src/test/setup.ts'],
coverage: {
provider: 'v8',
reporter: ['text', 'html', 'lcov'],
thresholds: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
},
});
waitFor and retry-able assertions. Avoid setTimeout.jest-axe or @axe-core/playwright for a11y.Take cosmicstack-labs/frontend-testing from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.