Search for a command to run...
Last updated June 9, 2026
Ctrovalidate is designed with high logic coverage, but your application-specific schemas and custom rules should also be verified. This guide covers testing strategies for every layer of the monorepo.
Since ctrovalidate-core is pure JavaScript, you can unit test your schemas in any environment (Vitest, Jest, Node). This is the fastest way to verify complex business logic.
import { validateValue } from 'ctrovalidate-core';
import { signupSchema } from './schemas';
describe('Signup Schema', () => {
it('should fail on weak passwords', () => {
const result = validateValue('123', signupSchema.password);
expect(result.isValid).toBe(false);
});
it('should pass on valid email', () => {
const result = validateValue('test@test.com', signupSchema.email);
expect(result.isValid).toBe(true);
});
it('should validate full object', () => {
const { validate } = await import('ctrovalidate-core');
const results = validate(
{ email: 'test@test.com', password: 'Abc123!@' },
signupSchema
);
expect(results.email.isValid).toBe(true);
expect(results.password.isValid).toBe(true);
});
});When testing framework adapters, use React Testing Library or Vue Test Utils. Focus on user interactions (fireEvent, @testing-library/user-event).
import { render, screen, fireEvent } from '@testing-library/react';
import MyForm from './MyForm';
test('shows error message on invalid email', async () => {
render(<MyForm />);
const input = screen.getByLabelText(/email/i);
fireEvent.change(input, { target: { value: 'invalid-email' } });
fireEvent.blur(input);
expect(await screen.findByText(/invalid email address/i)).toBeInTheDocument();
});For high-standard verification of the ctrovalidate-browser controller, use Playwright or Cypress. This ensures that event listeners, DOM discovery, and ARIA attributes are working correctly in real browsers.
// Playwright example
test('form should not submit if invalid', async ({ page }) => {
await page.goto('/signup');
await page.click('button[type="submit"]');
// Verify ARIA state
const emailInput = page.locator('input[name="email"]');
await expect(emailInput).toHaveAttribute('aria-invalid', 'true');
// Verify error message presence
await expect(page.locator('.error-message')).toBeVisible();
});axe-core in your E2E tests to verify that the aria-describedby links correctly and that error containers have the proper roles.