21. Automating Complex UI Widgets & Dynamic Lists

1. Data Tables & Grids

To verify or click an element inside a dynamic table row:
// Find row containing user email and click its 'Edit' button
const row = page.locator("table tbody tr", { hasText: "jane.doe@example.com" });
await row.getByRole("button", { name: "Edit" }).click();

// Extract all table row texts:
const allNames = await page.locator("table tbody tr td:first-child").allInnerTexts();

---

2. Auto-Complete / Typeahead Dropdowns

Custom dropdowns that query an API as the user types:
const searchInput = page.getByPlaceholder("Search countries");
await searchInput.pressSequentially("Jap", { delay: 100 });

// Wait for floating suggestions dropdown and select target
const option = page.getByRole("option", { name: "Japan" });
await option.click();

---

3. Date Pickers & Calendars

Rather than clicking calendar arrow buttons 50 times, preferred strategies: 1. Directly fill the input if it is editable:
await page.getByLabel("Departure Date").fill("2026-10-15");
2. If read-only, open modal and target precise day:
await page.getByLabel("Choose date").click();
await page.getByRole("gridcell", { name: "15" }).click();

---

4. Infinite Scrolling

async function scrollDownTimes(page: Page, times: number) {
  for (let i = 0; i < times; i++) {
    await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight));
    await page.waitForTimeout(500); // Wait for next batch of items
  }
}

Task

  • Implement parseTableRow:
  • 1. Accept cells: string[].
  • 2. Throw an error if cells has fewer than 3 elements.
  • 3. Return UserRowRecord { id: cells[0], name: cells[1], role: cells[2] }.
πŸ’‘Common doubts
Did you like the problem?
Lesson 21 of 36
TypeScript
Loading code editor…
Next