testing-react — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited testing-react (Agent Skill) and scored it 91/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 1 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} is the classic direct prompt-injection phrasing. Placed in a skill body that the agent reads as trusted instructions, it tries to make the agent abandon its prior rules and follow whatever comes next — a full system-prompt override.
ignore/disregard/forget … previous instructions sentence.Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
| Type | Tool | Target | File pattern |
|---|---|---|---|
| Unit | Vitest | Pure functions, utilities, services | Co-located *.test.ts |
| Component | Vitest + RTL | React components | Co-located *.test.tsx |
| Hook | Vitest + RTL | Custom hooks | Co-located *.test.ts |
| E2E | Playwright | User flows, critical paths | Separate e2e/ directory |
Default to component tests for React components. Unit tests for pure functions and service classes. See e2e-testing for Playwright patterns.
Vitest config: environment: 'jsdom', globals: true, setupFiles pointing to a file that imports @testing-library/jest-dom/vitest. Use @vitejs/plugin-react and mirror path aliases from tsconfig.json.
getByRole > getByLabelText > getByPlaceholderText > getByText > getByTestId. Use data-testid only when no accessible query works.should <behavior> when <condition>.findBy* for async elements, waitFor after state-triggering actions, vi.useFakeTimers() for debounce/timer logic.userEvent over fireEvent for realistic interactions.vi.clearAllMocks() in beforeEach. Recreate test state per test instead of sharing mutable variables.import { render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
vi.mock('@/api/client');
describe('UserForm', () => {
beforeEach(() => { vi.clearAllMocks(); });
it('should submit valid form data', async () => {
const onSubmit = vi.fn();
render(<UserForm onSubmit={onSubmit} />);
await userEvent.type(screen.getByLabelText(/email/i), '[email protected]');
await userEvent.click(screen.getByRole('button', { name: /submit/i }));
await waitFor(() => {
expect(onSubmit).toHaveBeenCalledWith(
expect.objectContaining({ email: '[email protected]' }),
);
});
});
});import { renderHook, act } from '@testing-library/react';
it('should debounce value updates', () => {
vi.useFakeTimers();
const { result, rerender } = renderHook(
({ value }) => useDebounce(value, 300),
{ initialProps: { value: 'initial' } },
);
rerender({ value: 'updated' });
expect(result.current).toBe('initial');
act(() => { vi.advanceTimersByTime(300); });
expect(result.current).toBe('updated');
vi.useRealTimers();
});// Service mock — mock the module, not the transport layer
vi.mock('@/server-api/me/me.service', () => ({
MeService: { retrieveMe: vi.fn() },
}));
// QueryClient wrapper for components using TanStack Query
const createWrapper = () => {
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
});
return ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);
};
render(<Component />, { wrapper: createWrapper() });npx vitest # Watch mode
npx vitest run # Single run (CI)
npx vitest run src/features/ # Test specific directory
npx vitest --coverage # Coverage report~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.