SoftwareTestPilot
Dataintermediate hidden bug 14 min

Dynamic / Shifting Tables — Practice in Playwright, Selenium & Cypress

Practice automating dynamic tables whose columns and rows re-order on refresh. Anchor by header text and row identity instead of brittle position selectors.

Live element

Hidden bug planted — try to catch it

🐞 Sort High→Low and watch your test catch a defect.

Locators cheat-sheet

data-testidRoleAccessible labelWhat it is
products-tabletableProducts tableThree rows: name + price.
sort-pricebuttonSort by priceToggles ascending / descending price sort. 🐞 Descending is broken on purpose.
row-namecellProduct name cellUse nth-row selectors to assert order after sorting.
row-pricecellProduct price cellNumeric price value used to verify sort correctness.

Reference solutions

import { test, expect } from '@playwright/test';

test('descending price sort orders highest first', async ({ page }) => {
  await page.goto('/practice/dynamic-table');
  const frame = page.frameLocator('iframe[title="Dynamic table live widget"]');

  // First click = ascending, second click = descending.
  await frame.getByTestId('sort-price').click();
  await frame.getByTestId('sort-price').click();

  const prices = await frame.getByTestId('row-price').allTextContents();
  const numeric = prices.map(Number);

  // 🐞 With the planted bug, this assertion FAILS — descending order is broken.
  expect(numeric).toEqual([...numeric].sort((a, b) => b - a));
});
Try it in the Practice Hub Open learning module