Strategies
Strategies define how the library interacts with different table implementations. They handle pagination, sorting, filling, and more.
Strategy Types & Usage
| Strategy Type | Used By Methods | Description |
|---|---|---|
| Pagination | findRow(), findRows(), forEach, map | Navigating to next pages |
| Sorting | sorting.apply() | applying sort order |
| Fill | row.smartFill() | Entering data into cells |
| Header | init(), revalidate() | Finding and parsing column headers |
| Resolution | getCell() | Locating specific cells within a row |
Overview
import { useTable, Strategies } from '@rickcedwhat/playwright-smart-table';
const table = useTable(page.locator('#table'), {
strategies: {
pagination: Strategies.Pagination.click({ next: '.next-btn' }),
sorting: Strategies.Sorting.AriaSort(),
fill: Strategies.Fill.ClickAndType()
}
});Pagination Strategies
Control how the library navigates through pages.
ClickNext
Click a "Next" button to navigate to the next page.
Strategies.Pagination.ClickNext(selector: string | Locator)Example:
strategies: {
pagination: Strategies.Pagination.click({ next: '.pagination .next' })
}ClickPageNumber
Click specific page numbers.
Strategies.Pagination.ClickPageNumber(options: {
pageNumberSelector: string | ((page: number) => Locator),
currentPageSelector?: string
})Example:
strategies: {
pagination: Strategies.Pagination.ClickPageNumber({
pageNumberSelector: (page) =>
page.locator(`.pagination button:has-text("${page}")`)
})
}InfiniteScroll
Handle infinite scroll tables.
Strategies.Pagination.infiniteScroll(options?: {
scrollContainer?: Locator,
waitForNewRows?: number
})Example:
strategies: {
pagination: Strategies.Pagination.infiniteScroll({
scrollContainer: page.locator('.table-container'),
waitForNewRows: 500
})
}Custom Pagination
Create your own pagination logic:
strategies: {
pagination: {
goNext: async ({ page, rootLocator }) => {
// Your custom logic
const nextBtn = page.locator('.custom-next');
if (await nextBtn.isDisabled()) {
return false; // Stop pagination
}
await nextBtn.click();
await page.waitForLoadState('networkidle');
return true; // Continue pagination
}
}
}
> [!NOTE]
> Return `true` if a new page was loaded successfully, or `false` if there are no more pages.Sorting Strategies
Define how sorting is applied.
ClickHeader
Click column headers to sort.
Strategies.Sorting.ClickHeader(options?: {
detectState?: (header: Locator) => Promise<'asc' | 'desc' | null>
})Example:
strategies: {
sorting: Strategies.Sorting.AriaSort()
}Custom Sorting
strategies: {
sorting: {
apply: async ({ columnName, direction, page }) => {
// Custom sort logic
await page.locator(`[data-sort="${columnName}"]`).click();
},
getState: async ({ page }) => {
// Return current sort state
return { column: 'Name', direction: 'asc' };
}
}
}Fill Strategies
Control how cells are filled.
ClickAndType
Click cell, clear, and type (default).
Strategies.Fill.ClickAndType(options?: {
clearFirst?: boolean,
pressEnter?: boolean
})Example:
strategies: {
fill: Strategies.Fill.ClickAndType({
clearFirst: true,
pressEnter: true
})
}DoubleClickAndType
Double-click to enter edit mode.
Strategies.Fill.DoubleClickAndType(options?: {
clearFirst?: boolean
})Custom Fill
strategies: {
fill: async ({ cell, value, columnName }) => {
// Custom fill logic
await cell.dblclick();
await cell.locator('input').fill(value);
await cell.press('Enter');
}
}Header Strategies
Customize header detection.
Default
Standard thead th selector.
Custom
strategies: {
header: async ({ rootLocator }) => {
// Return array of header locators
return rootLocator.locator('.custom-header').all();
}
}Resolution Strategies
Control how cells are resolved within rows.
NthChild
Use nth-child selectors (default).
Strategies.Resolution.NthChild()DataAttribute
Use data attributes to find cells.
Strategies.Resolution.DataAttribute('data-column')Example:
// HTML: <td data-column="email">...</td>
strategies: {
resolution: Strategies.Resolution.DataAttribute('data-column')
}Custom Resolution
strategies: {
getCellLocator: ({ row, columnName, columnIndex }) => {
// Custom cell resolution
return row.locator(`[data-col="${columnName}"]`);
}
}Complete Example
import { useTable, Strategies } from '@rickcedwhat/playwright-smart-table';
const table = useTable(page.locator('#complex-table'), {
headerSelector: 'thead th',
rowSelector: 'tbody tr',
strategies: {
// Pagination
pagination: Strategies.Pagination.click({ next: '.pagination .next' }),
// Sorting
sorting: Strategies.Sorting.AriaSort(),
// Fill
fill: Strategies.Fill.DoubleClickAndType({
clearFirst: true
}),
// Custom resolution
getCellLocator: ({ row, columnName }) => {
return row.locator(`[data-column="${columnName}"]`);
}
}
});
await table.init();Next Steps
See how these strategies are applied in real-world scenarios.