VALIDATION LAB•USER TABLE — SEARCH + SORT
Tables
User Table — Search + Sort
Search by partial name/email, sort by signups asc/desc, paginate, and verify the visible row count + page metadata reflect every operation.
Why this matters in QA
Every admin grid is a derivative of this module. Bugs hide in: page resets-on-filter, sort breaks after re-render, the visible count drifts from the API's `total`. Senior QA always asserts both.
| Role | Status | |||
|---|---|---|---|---|
| Alex Carter | alex@hakdogan.com | qa | Active | 1,442 |
| Gizem Akar | gizem@hakdogan.com | admin | Active | 2,304 |
| Hugo Wallace | hugo@hakdogan.com | qa | Active | 728 |
| Ivy Petrov | ivy@hakdogan.com | user | Active | 1,119 |
Live widget · interact freely
Manual test checklist
- 1Type 'mira' — table reduces to one row
- 2Click Signups twice — flips asc → desc → first row is 'Gizem'
- 3Filter to zero matches — confirm an empty state, not a blank table
- 4Filter, then paginate — confirm the page resets to 1
- 5Confirm `users-row-0` selector exists for stable assertions
Expected result
Searching 'mira' filters to one row; sorting Signups desc puts 'Gizem' first (2,304 signups); pagination metadata shows 'Page 1 / N · K matches'.
Automation challenge
Drive the search, then sort, then paginate, asserting the metadata `users-page` matches `Page X / Y · K matches` at every step. Use `.first()` and `.nth()` to lock to specific rows; never absolute index.
Stable selectors
- Search input
[data-testid="users-search"] - Sort by name
[data-testid="users-sort-name"] - Sort by signups
[data-testid="users-sort-signups"] - Row template
[data-testid="users-row-{i}"] - Page metadata
[data-testid="users-page"] - Empty state
[data-testid="users-empty"]
Reference Playwright spec
1234567891011121314
import { test, expect } from '@playwright/test';
test('user table search + sort + paginate', async ({ page }) => {
await page.goto('https://lab.hakdogan.com/data-api/user-table');
await page.getByTestId('users-search').fill('mira');
await expect(page.getByTestId('users-row-0')).toContainText('Mira');
await expect(page.getByTestId('users-page')).toContainText('1 matches');
await page.getByTestId('users-search').fill('');
await page.getByTestId('users-sort-signups').click();
await page.getByTestId('users-sort-signups').click();
await expect(page.getByTestId('users-row-0')).toContainText('Gizem');
});