Broken Form Demo

← Back to Tetsing Lab

⚠️ Broken Form Demo

Submit with bad inputs to see inline errors. Fill everything correctly to reach the success state.

🎉

Form submitted successfully!

All fields validated. This is what a happy path looks like.

🎭

How to automate this page

Each step targets a specific validation scenario. Run them individually with --grep to isolate failures.

terminal # One-time setup
npm init playwright@latest

# Run your tests
npx playwright test

# Open the HTML report
npx playwright show-report
1 All four fields show errors on empty submit required fields

Click submit on an untouched form. All four fields (name, email, country, checkbox) should show their individual error messages at the same time.

tetsing-lab.spec.ts
import { test, expect } from '@playwright/test';

test('shows all required field errors on empty submit', async ({ page }) => {
  await page.goto('https://falcoma.com/tetsing-lab/broken-form-demo');

  await page.click('[data-testid=btn-submit]');

  await expect(page.locator('[data-testid=error-name]'))
    .toHaveText('Full name is required.');
  await expect(page.locator('[data-testid=error-email]'))
    .toHaveText('Email address is required.');
  await expect(page.locator('[data-testid=error-country]'))
    .toHaveText('Please select a country.');
  await expect(page.locator('[data-testid=error-agree]'))
    .toHaveText('You must agree to continue.');
});
2 Invalid email format shows a format error format validation

Type a string that looks like an email but is not valid. The error should switch from "required" to "invalid format". This tests that the validation rule for format is separate from the required check.

tetsing-lab.spec.ts
import { test, expect } from '@playwright/test';

test('rejects invalid email format', async ({ page }) => {
  await page.goto('https://falcoma.com/tetsing-lab/broken-form-demo');

  await page.fill('[data-testid=input-email]', 'not-an-email');
  await page.click('[data-testid=btn-submit]');

  await expect(page.locator('[data-testid=error-email]'))
    .toHaveText('Please enter a valid email address.');
});
3 Valid submission reveals the success banner happy path

Fill every field correctly and submit. The form wrapper disappears and the success banner takes its place. This is a full end-to-end happy path test.

tetsing-lab.spec.ts
import { test, expect } from '@playwright/test';

test('shows success banner on fully valid submission', async ({ page }) => {
  await page.goto('https://falcoma.com/tetsing-lab/broken-form-demo');

  await page.fill('[data-testid=input-name]', 'Vincent Wong');
  await page.fill('[data-testid=input-email]', 'vincent@falcoma.com');
  await page.selectOption('[data-testid=select-country]', 'de');
  await page.check('[data-testid=checkbox-agree]');
  await page.click('[data-testid=btn-submit]');

  await expect(page.locator('[data-testid=success-banner]')).toBeVisible();
  await expect(page.locator('[data-testid=form-wrapper]')).not.toBeVisible();
});
4 Reset button restores the form state management

After a successful submission, clicking Reset should hide the banner and bring the form back in its clean, empty state.

tetsing-lab.spec.ts
import { test, expect } from '@playwright/test';

test('reset button brings the form back after success', async ({ page }) => {
  await page.goto('https://falcoma.com/tetsing-lab/broken-form-demo');

  // Submit a valid form first
  await page.fill('[data-testid=input-name]', 'Vincent Wong');
  await page.fill('[data-testid=input-email]', 'vincent@falcoma.com');
  await page.selectOption('[data-testid=select-country]', 'de');
  await page.check('[data-testid=checkbox-agree]');
  await page.click('[data-testid=btn-submit]');
  await expect(page.locator('[data-testid=success-banner]')).toBeVisible();

  // Click reset and confirm the form is back
  await page.click('[data-testid=btn-reset]');
  await expect(page.locator('[data-testid=form-wrapper]')).toBeVisible();
  await expect(page.locator('[data-testid=success-banner]')).not.toBeVisible();
});