VALIDATION LABSTATIC TABLE

Tables

Static Table

Practice deterministic table assertions against a fixed Name, Email, Role, Status grid and click an action button inside a specific row.

Beginner

Scenario

Static tables are the first place QA engineers learn row scoping. The important habit is asserting the right cell inside the right row, not matching text somewhere on the page.

Fixed users table for row and cell assertions.

No row action yet.
NameEmailRoleStatusAction
Hasan Akdoğanhasan.qa@hakdogan.comQA LeadActive
Mira Stonemira.admin@hakdogan.comAdminActive
Alex Reedalex.engineer@hakdogan.comEngineerInvited
Yuki Tanyuki.manager@hakdogan.comManagerSuspended

Live widget · interact freely

Manual test checklist

  • 1Find a row by visible name text
  • 2Confirm Email, Role, and Status cells match the expected user
  • 3Click View inside the Hasan Akdoğan row
  • 4Verify the action result names the same row
  • 5Confirm another row action does not mutate table order

Expected result

Rows never change order; locating Hasan Akdoğan exposes the expected email, role, status, and row action result.

Automation challenge

Scope to `static-users-table`, filter the row by text, assert the role/status cells, then click the action button inside that same row.

Stable selectors

  • Static users table[data-testid="static-users-table"]
  • Hasan row[data-testid="static-row-hasan-akdogan"]
  • First name cell[data-testid="static-cell-name-0"]
  • First email cell[data-testid="static-cell-email-0"]
  • Hasan action[data-testid="static-action-hasan-akdogan"]
  • Action result[data-testid="static-table-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. Static rows can be targeted by deterministic ids.

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

await page.locator('[data-testid="static-row-hasan-akdogan"]');

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

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

test('static table row and action assertions', async ({ page }) => {
  await page.goto('https://lab.hakdogan.com/practice/static-table');

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

  await expect(row).toContainText('hasan.qa@hakdogan.com');
  await expect(row).toContainText('QA Lead');
  await expect(row).toContainText('Active');

  await row.getByRole('button', { name: /view/i }).click();
  await expect(page.getByTestId('static-table-action-result')).toContainText(
    '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.

Idlestatic-table.spec.ts
Failure demos
https://lab.hakdogan.com/practice/static-table
playwright · headed · chromium0.00s
# awaiting Run Test · terminal scrolls automatically
Steps
  1. Locating fixed user row
  2. Asserting email cell
  3. Asserting role and status
  4. Clicking row action
StatusIdle
BrowserChromium
FrameworkPlaywright + TypeScript
Elapsed (live)--
Specstatic-table.spec.ts