AG Grid Example
AG Grid is a high-performance table library that is fully virtualized and uses a complex DOM structure.
Configuration
WARNING
AG Grid has a complex DOM that relies on specific class names (e.g. .ag-cell-value) which are internal implementation details. These may change in future AG Grid versions. Using stable test attributes (like data-test-id) is recommended if you have control over the source code.
AG Grid is effectively tested by targeting its specific class names.
Basic Setup
import { useTable, Strategies } from 'playwright-smart-table';
const table = useTable(page.locator('.ag-root-wrapper'), {
// AG Grid standard classes
headerSelector: '.ag-header-cell-text', // Target the text container directly
rowSelector: '.ag-row',
cellSelector: '.ag-cell',
strategies: {
// AG Grid uses aria-sort
sorting: Strategies.Sorting.AriaSort(),
// Custom pagination (if using standard paging)
pagination: Strategies.Pagination.click({ next: '.ag-paging-button[aria-label="Next Page"]' })
}
});
await table.init();Virtualization & Column Virtualization
AG Grid virtualizes both rows (vertical) and columns (horizontal).
Horizontal Scrolling
If columns are off-screen, getCell() won't find them by default. You need a navigation strategy or to use scrollToColumn().
// 1. Scroll to column manually
await table.scrollToColumn('Status');
await row.getCell('Status').click();
// 2. Or configure a strategy to auto-scroll using right arrow
strategies: {
navigation: {
goRight: async () => {
await page.keyboard.press('ArrowRight');
},
goLeft: async () => {
await page.keyboard.press('ArrowLeft');
}
}
}Row Virtualization
For "Infinite Scroll" or "Server Side Row Model" in AG Grid:
The Structure
AG Grid is complex because it splits headers and body content, and often uses row virtualization.
graph TD
subgraph "AG Grid Container"
H[Header Container .ag-header]
B[Body Container .ag-body-viewport]
end
H --> H1[.ag-header-cell]
H --> H2[.ag-header-cell]
B --> R1[.ag-row]
B --> R2[.ag-row]
R1 --> C1[.ag-cell value="Name"]
R1 --> C2[.ag-cell value="Role"]
style H fill:#f9f,stroke:#333,stroke-width:2px
style B fill:#bbf,stroke:#333,stroke-width:2pxstrategies: {
pagination: Strategies.Pagination.infiniteScroll({
scrollContainer: page.locator('.ag-body-viewport'),
})
}Checkbox Selection
AG Grid often has a checkbox column. You can resolve it using getRowByIndex or custom selectors.
test('select row', async ({ page }) => {
const table = useTable(page.locator('#myGrid'));
const row = await table.findRow({ Model: 'Y' });
// Assuming the first column is the checkbox
await row.locator('.ag-selection-checkbox').click();
// Or if it's a named column
await row.getCell('Select').locator('input').check();
});Complete Test Example
test('AG Grid flow', async ({ page }) => {
await page.goto('https://www.ag-grid.com/example/');
const table = useTable(page.locator('#myGrid'), {
headerSelector: '.ag-header-cell-text',
rowSelector: 'div[role="row"]',
cellSelector: 'div[role="gridcell"]',
});
// Sort by Price
await table.sorting.apply('Price', 'desc');
// Find expensive car
const row = await table.findRow({
Make: 'Porsche',
Model: 'Boxster'
});
// Verify
await expect(row.getCell('Price')).toHaveText('72000');
});Next Steps
Learn about advanced patterns, validation, and scraping.