VALIDATION LABDYNAMIC TABLE

Tables

Dynamic Table

Search generated users, sort by name, filter active users, paginate, validate row counts, and click edit/delete for a specific row.

Advanced

Scenario

Real admin tables combine query state, sorting, filters, pagination, and row actions. Automation must scope locators carefully or it clicks the wrong repeated button.

8 matches
EmailRoleStatusActions
Hasan Akdoğanhasan.qa@hakdogan.comQA LeadActive
Mira Stonemira.admin@hakdogan.comAdminActive
Alex Reedalex.engineer@hakdogan.comEngineerInvited
Noor Khannoor.qa@hakdogan.comQAActive
Page 1 / 2

No row selected.

Live widget · interact freely

Manual test checklist

  • 1Search for Hasan and confirm only matching users remain
  • 2Sort by Name and confirm alphabetical order
  • 3Filter Status to Active and confirm no suspended rows remain
  • 4Use pagination and confirm page count updates
  • 5Click Edit and Delete for a specific row and confirm the action result

Expected result

Search, status filter, sorting, pagination, and row actions compose without losing the selected row or count accuracy.

Automation challenge

Search `Hasan`, sort by name, filter `Active`, assert visible row count, then find the row by text and click its edit/delete button without relying on row index.

Stable selectors

  • Search users[data-testid="dynamic-table-search"]
  • Status filter[data-testid="dynamic-status-filter"]
  • Sort name[data-testid="dynamic-sort-name"]
  • Dynamic users table[data-testid="dynamic-users-table"]
  • Row count[data-testid="dynamic-row-count"]
  • Hasan row[data-testid="dynamic-row-usr-104"]
  • Hasan edit[data-testid="dynamic-edit-usr-104"]
  • Hasan delete[data-testid="dynamic-delete-usr-104"]
  • Action result[data-testid="dynamic-action-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.

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

await page.locator('#dynamic-table-search').fill('Hasan');

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

dynamic-table.spec.ts
ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { test, expect } from '@playwright/test';

test('dynamic table search sort filter and row actions', async ({ page }) => {
  await page.goto('https://lab.hakdogan.com/practice/dynamic-table');

  await page.getByTestId('dynamic-table-search').fill('Hasan');
  await page.getByTestId('dynamic-sort-name').click();
  await page.getByTestId('dynamic-status-filter').selectOption('Active');

  await expect(page.getByTestId('dynamic-row-count')).toContainText('1 match');

  const row = page
    .getByTestId('dynamic-users-table')
    .getByRole('row')
    .filter({ hasText: 'Hasan Akdoğan' });

  await row.getByRole('button', { name: /edit/i }).click();
  await expect(page.getByTestId('dynamic-action-result')).toContainText(
    'Editing Hasan Akdoğan',
  );
});

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.

Mixed: fill() for stable fields, type() / press() where keyboard semantics matter.

Idledynamic-table.spec.ts
Failure demos
https://lab.hakdogan.com/practice/dynamic-table
playwright · headed · chromium0.00s
# awaiting Run Test · terminal scrolls automatically
Steps
  1. Open searchable "Users" grid
  2. Search slice — "Hasan"
  3. Sort ascending by name column
  4. Filter to active memberships
  5. Assert hydrated row quantity
  6. Pass
StatusIdle
BrowserChromium
FrameworkPlaywright + TypeScript
Elapsed (live)--
Specdynamic-table.spec.ts