VALIDATION LAB•FRAMEWORK
Playwright · TypeScript (POM)
Framework
Choose a scenario, understand how the files work together, then run the project locally. Learn a maintainable automation structure through real QA examples.
Lesson 1 of 4 · Beginner
Automate the Inputs test
You already tested this form manually in Practice. Now learn how the same check is organised in a Playwright test and a Page Object.
Goal
Connect an acceptance criterion to code.
Files
Spec + Page Object + fixture.
Time
About 15 minutes · no account.
Lesson path
Progress
1 of 7 steps
inputs.spec.ts
Test: what to verify
1234567891011121314
import { test, expect } from '@playwright/test';
import { InputsPage } from './inputs.page';
test('invalid email shows a field error', async ({ page }) => {
const inputs = new InputsPage(page);
await inputs.goto();
await inputs.fillEmail('not-an-email');
await inputs.fillPassword('Pass-w0rd!');
await inputs.submit();
await expect(inputs.emailError).toHaveText(
'Please enter a valid email address.',
);
});Run it
$ npx playwright test inputs.spec.tsAcceptance criteria → assertions
- AC-002 Invalid email is rejected →
emailError.toHaveText() - AC-003 Error appears beside the field →
getByTestId('email-error') - AC-006 Focus order is logical → add the keyboard step next
Common mistakes
- Do not put raw selectors in the spec.
- Do not use
waitForTimeoutfor validation. - Keep assertions in the test so the expected behaviour is visible.
Your turn
Write the positive Inputs test, then continue with Buttons.
The framework
How the framework fits together
Code layers
Test → Page Object → Component
The test describes what should happen. The Page Object owns where things are and how a user interacts with them.
Run layers
Config → Runner → CI
Config sets the rules, Playwright runs the test, and CI repeats it for every change.
- tests/ → describe-blocks tagged
@smoke/@regression. - pages/ → Page Object Model for every screen with role-based locators.
- components/ → reusable component objects (header, toast, modal).
- utils/auth.ts → shared
signInAsfor user and admin journeys (storage promotion included). - utils/ → cross-cutting helpers: auth, mocks, waits, retries, downloads.
- data/ → pure data builders (faker-powered) — no I/O, no shared state.
- tsconfig.json → strict TypeScript,
noEmitcheck-only for the suite. - playwright.config.ts → projects, retries, traces, screenshots, video, GREP.
- .github/ → 4-shard matrix, nightly cron, artifact upload on failure.
+All project files · download the complete starter project
tests/login.spec.ts
Auth happy path + client-side validation negative cases.
12345678910111213141516171819202122232425
import { test, expect } from 'playwright/test';
import { LoginPage } from '../pages/login.page';
test.describe('Authentication @smoke', () => {
test('demo credentials reach Bug Playground', async ({ page }) => {
const login = new LoginPage(page);
await login.goto();
await login.useDemoAccount();
await login.submit();
await expect(page).toHaveURL(/\/bug-playground\/\/?$/);
});
test('invalid email and short password show validation messages @regression', async ({
page,
}) => {
const login = new LoginPage(page);
await login.goto();
await login.signIn('not-an-email', 'short');
await expect(login.emailFormatError).toHaveText(/Use a valid email address/i);
await expect(login.passwordLengthError).toHaveText(
/Password must be at least 8/i,
);
});
});Run locally
Setup
- unzip/ → extract
lab.hakdogan.com.zip. - cd/ → enter
lab.hakdogan.com/. - install/ → run
npm install. - browsers/ → run
npx playwright install. - test/ → run
npx playwright test.
Usage
- report/ →
npx playwright show-report. - smoke/ →
npx playwright test --grep @smoke. - regression/ →
npx playwright test --grep @regression. - debug/ →
npx playwright test --debug. - node/ → Node.js v18+ (v20 recommended).