VALIDATION LAB•VALIDATION ERRORS
Form Lab
Validation Errors
Run dedicated negative testing scenarios for empty submit, invalid email, short password, mismatched passwords, invalid phone, expired card, invalid CVV, unchecked terms, and server error simulation.
Scenario
Negative testing catches the bugs happy paths miss: missing guards, weak error copy, stale server failures, and form states that allow invalid data through.
Live interactive form
Validation Errors
Dedicated negative testing triggers with stable selectors and repeatable errors.
Validation result panel
Choose a negative scenario.
Live widget · interact freely
Manual test checklist
- 1Trigger empty submit and verify required errors
- 2Trigger invalid email and verify the error row
- 3Trigger short and mismatched passwords
- 4Trigger invalid phone
- 5Trigger expired card and invalid CVV
- 6Trigger unchecked terms
- 7Trigger server error simulation and verify the retryable error
Expected result
Each negative scenario produces a visible, stable error row that can be asserted independently with Playwright.
Automation challenge
Click each negative scenario button and assert its error row with getByTestId() and getByText(). Include a server error simulation assertion.
Stable selectors
- Negative lab
[data-testid="form-validation-errors-form"] - Empty submit
[data-testid="form-validation-errors-empty-submit"] - Invalid email
[data-testid="form-validation-errors-invalid-email"] - Short password
[data-testid="form-validation-errors-short-password"] - Mismatched passwords
[data-testid="form-validation-errors-mismatched-passwords"] - Invalid phone
[data-testid="form-validation-errors-invalid-phone"] - Expired card
[data-testid="form-validation-errors-expired-card"] - Invalid CVV
[data-testid="form-validation-errors-invalid-cvv"] - Unchecked terms
[data-testid="form-validation-errors-unchecked-terms"] - Server error
[data-testid="form-validation-errors-server-error"] - Validation result
[data-testid="form-validation-errors-result"]
Locator strategy
Three levels from simple IDs to scoped Playwright locators. IDs and names are easy to learn but are not always the best long-term choice when labels change or components repeat.
Negative cases are exposed as explicit buttons so each error can be asserted independently.
1234
await page.goto('https://lab.hakdogan.com/practice/form-validation-errors');
await page.getByTestId('form-validation-errors-empty-submit').click();
await expect(page.getByText(/required fields are missing/i)).toBeVisible();Avoid as primary strategies
XPath (unless there is no alternative), long CSS chains, Tailwind-style utility class selectors, generated or unstable IDs, and volatile framework internals break when layout, styling, or DOM structure shifts.
12
await page.locator('.w-full.rounded-xl.border.bg-blue-500').fill('demo@example.com');
await page.locator('//div[2]/form/div[1]/input').fill('demo@example.com');Reference Playwright spec
1234567891011121314
import { test, expect } from '@playwright/test';
test('validation errors page exposes negative cases', async ({ page }) => {
await page.goto('https://lab.hakdogan.com/practice/form-validation-errors');
await page.getByTestId('form-validation-errors-empty-submit').click();
await expect(page.getByText(/required fields are missing/i)).toBeVisible();
await page.getByTestId('form-validation-errors-invalid-email').click();
await expect(page.getByTestId('form-validation-errors-result')).toContainText('Invalid email');
await page.getByTestId('form-validation-errors-server-error').click();
await expect(page.getByText(/server error simulation/i)).toBeVisible();
});Headed Test Playback
Simulated headed-browser flow — no real browser is launched.
Automation-style playback (Playwright-shaped logs). No real browser; no commands run on your machine.
form-validation-errors.spec.ts- Trigger empty submit
- Trigger invalid email
- Trigger payment validation errors
- Trigger server error simulation
- Assert error panel