VALIDATION LAB•PROFILE 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.
Scenario
Profile forms persist user identity and preferences. QA should cover uniqueness, file upload restrictions, locale selections, and edit-save feedback.
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.
1234
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.
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
12345678910111213141516171819
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.
form-profile.spec.ts- Edit profile fields
- Select preferences
- Upload avatar fixture
- Assert profile update result