VALIDATION LABCONTACT FORM

Form Lab

Contact Form

Validate a support/contact request with required identity fields, message length, optional attachment upload, and a success toast.

Beginner

Scenario

Contact and support forms are customer-facing intake pipes. QA must verify inline errors, upload handling, message length, and confirmation feedback so real requests are not silently lost.

Live interactive form

Contact Form

Customer support intake with optional evidence attachment.

Validation result panel

Awaiting submission.

Live widget · interact freely

Manual test checklist

  • 1Submit empty fields and confirm required errors
  • 2Enter an invalid email and verify the email message
  • 3Enter a message under 20 characters and confirm the length error
  • 4Attach a test file and confirm the result panel records the filename
  • 5Submit valid data and verify the success toast

Expected result

Required fields, invalid email, and short messages are blocked; a valid message with an optional attachment produces a success toast.

Automation challenge

Use getByLabel() for text fields, setInputFiles() for the optional attachment, getByRole() to submit, and assert both the success toast and validation result panel.

Stable selectors

  • Contact form[data-testid="form-contact-form"]
  • Full Name[data-testid="form-contact-full-name"]
  • Email[data-testid="form-contact-email"]
  • Subject[data-testid="form-contact-subject"]
  • Message[data-testid="form-contact-message"]
  • Attachment[data-testid="form-contact-attachment"]
  • Submit[data-testid="form-contact-submit"]
  • Validation result[data-testid="form-contact-result"]
  • Toast[data-testid="form-contact-toast"]

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.

Use simple IDs and names to understand how locating elements works. Form Lab pages expose predictable field ids and data-testid values for every control.

1
2
3
4
await page.goto('https://lab.hakdogan.com/practice/form-contact');

await page.locator('[data-testid="form-contact-form"]').waitFor();
await page.locator('[data-testid="form-contact-submit"]').click();

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.

1
2
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

form-contact.spec.ts
ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { test, expect } from '@playwright/test';

test('contact form accepts a support request with attachment', async ({ page }) => {
  await page.goto('https://lab.hakdogan.com/practice/form-contact');

  await page.getByLabel('Full Name').fill('Hasan Akdogan');
  await page.getByLabel('Email').fill('hasan@lab.dev');
  await page.getByLabel('Subject').fill('Checkout issue');
  await page.getByLabel('Message').fill('The checkout confirmation did not arrive after payment.');
  await page.getByLabel('Attachment').setInputFiles({
    name: 'evidence.txt',
    mimeType: 'text/plain',
    buffer: Buffer.from('test evidence only'),
  });
  await page.getByRole('button', { name: /send message/i }).click();

  await expect(page.getByTestId('form-contact-toast')).toContainText(/success/i);
  await expect(page.getByTestId('form-contact-result')).toContainText('evidence.txt');
});

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.

Idleform-contact.spec.ts
Failure demos
https://lab.hakdogan.com/practice/form-contact
playwright · headed · chromium0.00s
# awaiting Run Test · terminal scrolls automatically
Steps
  1. Fill contact fields
  2. Attach optional evidence
  3. Submit message
  4. Assert success toast
StatusIdle
BrowserChromium
FrameworkPlaywright + TypeScript
Elapsed (live)--
Specform-contact.spec.ts