VALIDATION LABSLIDER INTERACTION LAB

Selection

Slider Interaction Lab

Exercise slider changes through drag, track click, keyboard arrows, and direct numeric input while comparing visual, displayed, and submitted values.

Intermediate

Scenario

Sliders often hide state bugs because the thumb moves even when form state, display copy, or submitted data is wrong. This module trains QA to assert more than a visible position.

Slider Interaction Lab

QA-focused range control

Exercise drag, track click, keyboard arrows, and direct input. The lab intentionally exposes mismatches between visual state, displayed value, and submitted value.

Error: displayed, visual, or submitted values disagree.

Current value

26 / 100

Percentage

26%

Last interaction

none

Submitted value

25

Event log

No slider events yet.

QA scenarios

Set value to 50 using drag · expected submitted value: 50
Set value to 75 using keyboard · expected submitted value: 75
Click random position and verify value · expected submitted value: 25

Intentional bug switches

Live widget · interact freely

Manual test checklist

  • 1Drag the slider to 50 and compare current, percentage, and submitted values
  • 2Focus the slider and use ArrowRight/ArrowLeft until it reaches 75
  • 3Click a random track position and verify the resulting value is truthful
  • 4Review the event log for mousedown, mousemove, mouseup, input, and change
  • 5Toggle each intentional bug and confirm the feedback panel changes between success and error

Expected result

The lab logs low-level slider events and highlights intentional mismatches in green or red so QA can practice detecting interaction bugs.

Automation challenge

Write tests that use mouse movement, keyboard arrows, and direct input. Assert both `slider-current-value` and `slider-submitted-value`, then prove at least one intentional bug creates a mismatch.

Stable selectors

  • Slider lab[data-testid="slider-lab"]
  • Native slider[data-testid="qa-slider"]
  • Direct input[data-testid="slider-direct-input"]
  • Current value[data-testid="slider-current-value"]
  • Percentage[data-testid="slider-percentage"]
  • Last interaction[data-testid="slider-last-interaction"]
  • Submitted value[data-testid="slider-submitted-value"]
  • Feedback panel[data-testid="slider-feedback"]
  • Event log[data-testid="slider-event-log"]
  • QA scenarios[data-testid="slider-scenarios"]
  • Bug controls[data-testid="slider-bug-controls"]

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. Sliders expose both native range state and visible readouts, so start by locating the input and value panels directly.

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

await page.locator('#qa-slider').fill('50');
await expect(page.locator('[data-testid="slider-current-value"]')).toContainText('50');

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

slider.spec.ts
ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import { test, expect } from '@playwright/test';

test('slider lab exposes display and submitted value mismatches', async ({ page }) => {
  await page.goto('https://lab.hakdogan.com/practice/slider');

  await page.getByTestId('slider-bug-displayOffByOne').uncheck();
  await page.getByTestId('slider-bug-keyboardBlocked').uncheck();
  await page.getByTestId('slider-direct-input').fill('75');

  await expect(page.getByTestId('slider-current-value')).toContainText('75 / 100');
  await expect(page.getByTestId('slider-submitted-value')).toHaveText(/75/);
  await expect(page.getByTestId('slider-feedback')).toHaveAttribute('data-state', 'success');

  await page.getByTestId('slider-bug-displayOffByOne').check();
  await expect(page.getByTestId('slider-feedback')).toHaveAttribute('data-state', 'error');
});

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.

Idleslider.spec.ts
Failure demos
https://lab.hakdogan.com/practice/slider
playwright · headed · chromium0.00s
# awaiting Run Test · terminal scrolls automatically
Steps
  1. Interacting with slider interaction lab widget
  2. Awaiting deterministic render
  3. Asserting expected state
  4. Cleaning up context
  5. Pass
StatusIdle
BrowserChromium
FrameworkPlaywright + TypeScript
Elapsed (live)--
Specslider.spec.ts