VALIDATION LABPROFILE UPDATE FORM

Form Lab

Profile Update Form

Validate profile updates with display name, email, phone, language, timezone, avatar upload, duplicate email, invalid phone, and invalid file type scenarios.

Intermediate

Scenario

Profile forms persist user identity and preferences. QA should cover uniqueness, file upload restrictions, locale selections, and edit-save feedback.

Live interactive form

Profile Update Form

Profile preferences with duplicate email, phone, timezone, and avatar validation.

Validation result panel

Awaiting submission.

Live widget · interact freely

Manual test checklist

  • 1Update display name, language, and timezone and confirm success
  • 2Enter a non-numeric phone and confirm invalid phone error
  • 3Use used@lab.dev and confirm email already used
  • 4Upload a .txt avatar and confirm invalid file type
  • 5Upload a PNG test avatar and confirm the filename appears in the result panel

Expected result

Valid profile updates succeed; invalid phone, already-used email, and unsupported avatar file types show deterministic errors.

Automation challenge

Use setInputFiles() for avatar upload, selectOption() for language and timezone, and assert duplicate email plus invalid file type errors before a successful update.

Stable selectors

  • Profile form[data-testid="form-profile-form"]
  • Display Name[data-testid="form-profile-display-name"]
  • Email[data-testid="form-profile-email"]
  • Phone[data-testid="form-profile-phone"]
  • Language[data-testid="form-profile-language"]
  • Timezone[data-testid="form-profile-timezone"]
  • Avatar upload[data-testid="form-profile-avatar-upload"]
  • Validation result[data-testid="form-profile-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.

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-profile');

await page.locator('[data-testid="form-profile-form"]').waitFor();
await page.locator('[data-testid="form-profile-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-profile.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('profile form rejects invalid avatar type', async ({ page }) => {
  await page.goto('https://lab.hakdogan.com/practice/form-profile');

  await page.getByLabel('Display Name').fill('Hasan QA');
  await page.getByLabel('Email').fill('hasan@lab.dev');
  await page.getByLabel('Phone').fill('5551234567');
  await page.getByLabel('Language').selectOption('tr');
  await page.getByLabel('Timezone').selectOption('Europe/Istanbul');
  await page.getByLabel('Avatar upload').setInputFiles({
    name: 'avatar.txt',
    mimeType: 'text/plain',
    buffer: Buffer.from('not an image'),
  });
  await page.getByRole('button', { name: /update profile/i }).click();

  await expect(page.getByText(/invalid file type/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.

Idleform-profile.spec.ts
Failure demos
https://lab.hakdogan.com/practice/form-profile
playwright · headed · chromium0.00s
# awaiting Run Test · terminal scrolls automatically
Steps
  1. Edit profile fields
  2. Select preferences
  3. Upload avatar fixture
  4. Assert profile update result
StatusIdle
BrowserChromium
FrameworkPlaywright + TypeScript
Elapsed (live)--
Specform-profile.spec.ts