VALIDATION LAB•CHECKOUT FORM
Form Lab
Checkout Form
Exercise a checkout flow spanning customer info, shipping address, payment method, review order, terms acceptance, and submit order.
Scenario
Checkout flows combine multiple form domains and business rules. QA must validate cross-section dependencies, payment outcomes, terms acceptance, and final confirmation without losing state.
Live widget · interact freely
Manual test checklist
- 1Submit with missing shipping address and confirm address errors
- 2Choose declined payment and confirm order submit is blocked
- 3Leave terms unchecked and confirm the terms error
- 4Complete customer info, shipping, payment method, and review order
- 5Submit a valid order and confirm the success toast
Expected result
Successful checkout shows an order confirmation; missing address, declined payment, and unchecked terms each block submission with clear errors.
Automation challenge
Drive the checkout by labels and roles, select payment method, check terms, assert missing-address and declined-payment errors, then assert the successful order confirmation.
Stable selectors
- Checkout form
[data-testid="form-checkout-form"] - Customer Email
[data-testid="form-checkout-customer-email"] - Shipping Address
[data-testid="form-checkout-shipping-address"] - Payment Method
[data-testid="form-checkout-payment-method"] - Accept Terms
[data-testid="form-checkout-accept-terms"] - Review Order
[data-testid="form-checkout-review-order"] - Validation result
[data-testid="form-checkout-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-checkout');
await page.locator('[data-testid="form-checkout-form"]').waitFor();
await page.locator('[data-testid="form-checkout-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
123456789101112131415
import { test, expect } from '@playwright/test';
test('checkout form completes happy path', async ({ page }) => {
await page.goto('https://lab.hakdogan.com/practice/form-checkout');
await page.getByLabel('Customer Email').fill('buyer@lab.dev');
await page.getByLabel('Full Name').fill('Test Buyer');
await page.getByLabel('Shipping Address').fill('42 QA Street');
await page.getByLabel('City').fill('Istanbul');
await page.getByLabel('Payment Method').selectOption('test-success');
await page.getByLabel(/accept terms/i).check();
await page.getByRole('button', { name: /submit order/i }).click();
await expect(page.getByText(/order submitted successfully/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-checkout.spec.ts- Fill customer info
- Fill shipping address
- Choose payment method
- Review order and accept terms
- Submit order