VALIDATION LABSINGLE SELECT

Selection

Single Select

Select a value from a native dropdown and assert the downstream summary updates.

Beginner

Scenario

Native `<select>` elements behave differently across OSes and browsers — Mac vs Windows render the menu in totally different ways. Tests must use `selectOption()`, not click-by-position, or they break on every other CI machine.

Tool: Playwright

Live widget · interact freely

Manual test checklist

  • 1Open the dropdown via mouse — first option should be focused/highlighted
  • 2Open via keyboard (Alt+↓ on Win, Space on Mac) — same behavior?
  • 3Type the first letter of an option — does it jump to that option?
  • 4Confirm the summary chip updates synchronously, no flicker
  • 5Reload — does the previously chosen option persist (form state)?

Expected result

Choosing 'Playwright' updates the summary chip and emits a tracked event.

Automation challenge

Use `selectOption({ value: 'playwright' })` AND `selectOption({ label: 'Playwright' })` in two separate tests. Assert both succeed — proves the option is uniquely identifiable by value AND label.

Stable selectors

  • Tool select[data-testid="select-tool"]
  • Summary chip[data-testid="select-summary"]

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.

1
2
3
await page.goto('https://lab.hakdogan.com/practice/select');

await page.locator('#select-tool').selectOption('playwright');

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

select.spec.ts
ts
1
2
3
4
5
6
7
8
import { test, expect } from '@playwright/test';

test('native select dropdown', async ({ page }) => {
  await page.goto('https://lab.hakdogan.com/practice/select');

  await page.getByTestId('select-tool').selectOption('playwright');
  await expect(page.getByTestId('select-summary')).toHaveText('Tool: Playwright');
});

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.

Idleselect.spec.ts
Failure demos
https://lab.hakdogan.com/practice/select
playwright · headed · chromium0.00s
# awaiting Run Test · terminal scrolls automatically
Steps
  1. Selecting tool option
  2. Asserting summary chip
StatusIdle
BrowserChromium
FrameworkPlaywright + TypeScript
Elapsed (live)--
Specselect.spec.ts