Skip to content

Troubleshooting

Common issues and solutions when using Playwright Smart Table.

Column Not Found Errors

Problem

Error: Column "Email" not found
Available columns: Name, Position, Office, Age, Start date, Salary

Solutions

1. Check column name spelling and case

Column names are case-sensitive:

typescript
// ❌ Wrong
row.getCell('email'); 

// ✅ Correct
row.getCell('Email');

2. Use headerTransformer to normalize

typescript
const table = useTable(page.locator('#table'), {
  headerTransformer: async ({ text }) => {
    return text.toLowerCase().trim();
  }
});

// Now you can use lowercase
row.getCell('email'); // Works!

3. Check actual headers

typescript
const headers = await table.getHeaders();
console.log('Available columns:', headers);

Table Not Initialized

Problem

Error: Table not initialized. Call init() first.

Solutions

1. Call init() before synchronous methods

typescript
const table = useTable(page.locator('#table'));

// ❌ Wrong - getRowByIndex is sync
const row = table.getRowByIndex(0);

// ✅ Correct
await table.init();
const row = table.getRowByIndex(0);

2. Use async methods (auto-initialize)

typescript
// These methods auto-initialize
const row = await table.findRow({ Name: 'John' }); // ✅
const rows = await table.findRows({}); // ✅

Pagination Not Working

Problem

findRows() only returns results from the first page.

Solutions

1. Configure pagination strategy

typescript
import { Strategies } from '@rickcedwhat/playwright-smart-table';

const table = useTable(page.locator('#table'), {
  strategies: {
    pagination: Strategies.Pagination.click({ next: '.next-button' })
  }
});

2. Check pagination selector

typescript
// Verify the selector works
await page.locator('.next-button').click(); // Should navigate

3. Set maxPages

typescript
const rows = await table.findRows(
  { Office: 'Tokyo' },
  { maxPages: 10 } // Limit search
);

Flaky Tests

Problem

Tests pass sometimes but fail randomly.

Solutions

1. Enable debug mode

typescript
const table = useTable(page.locator('#table'), {
  debug: {
    slow: 500,
    logLevel: 'verbose'
  }
});

2. Wait for table to load

typescript
await page.waitForSelector('#table tbody tr');
await table.init();

3. Use proper waits

typescript
// ❌ Avoid
await page.waitForTimeout(1000);

// ✅ Better
await expect(row.getCell('Status')).toHaveText('Active');

Duplicate Column Names

Problem

Error: Duplicate column names found after transformation: ["Name", "Name"]

Solutions

1. Use headerTransformer to make unique

typescript
const table = useTable(page.locator('#table'), {
  headerTransformer: async ({ text, index }) => {
    // Add index to duplicates
    const normalized = text.trim();
    return `${normalized}_${index}`;
  }
});

2. Use column index

typescript
// Access by index instead
const cell = row.locator('td').nth(2);

Cells Not Found in Row

Problem

getCell() returns wrong cell or throws error.

Solutions

1. Check cell selector

typescript
const table = useTable(page.locator('#table'), {
  cellSelector: 'td' // Default
});

// For custom tables
const table = useTable(page.locator('#table'), {
  cellSelector: '.table-cell'
});

2. Use custom resolution strategy

typescript
strategies: {
  getCellLocator: ({ row, columnName, columnIndex }) => {
    return row.locator(`[data-column="${columnName}"]`);
  }
}

Performance Issues

Problem

Tests are slow when iterating through large tables.

Solutions

1. Use batching

typescript
await table.forEach(async ({ row }) => {
  // Process row
});

2. Limit pages

typescript
const rows = await table.findRows(
  { Department: 'Engineering' },
  { maxPages: 5 } // Don't search entire table
);

3. Use filtering

typescript
// ❌ Slow - gets all rows then filters in code
const allRows = await table.findRows({});
const filtered = allRows.filter(/* ... */);

// ✅ Fast - filters in DOM
const filtered = await table.findRows({ Office: 'Tokyo' });

TypeScript Type Errors

Problem

TypeScript doesn't recognize column names.

Solutions

1. Define table type

typescript
type Employee = {
  Name: string;
  Email: string;
  Office: string;
};

const table = useTable<Employee>(page.locator('#table'));

// Now TypeScript knows the columns
const row = await table.findRow({ 
  Name: 'John', // ✅ Autocomplete works
  InvalidColumn: 'x' // ❌ TypeScript error
});

2. Use Record for dynamic columns

typescript
const table = useTable<Record<string, string>>(page.locator('#table'));

Smart Errors Not Showing

Problem

Not getting helpful error messages with column suggestions or pagination diagnostics.

Solutions

Enable verbose logging

Smart errors (column not found, pagination failures) are emitted automatically. For maximum diagnostic output, enable verbose logging:

typescript
const table = useTable(page.locator('#table'), {
  debug: {
    logLevel: 'verbose'
  }
});

Smart errors are automatic for:

  • getCell() — Column not found (with nearest-match suggestion)
  • findRow() — No matching rows found
  • init() — Empty or duplicate column names detected
  • Pagination — Lists available primitives when navigation fails

Responsive / Mobile Tables

Problem

Table transforms into a list or card view on mobile screens (responsive design).

Solution

The library works on the visible DOM. If the table structure changes significantly (e.g., <table> becomes <div> cards), you may need conditional logic.

typescript
if (isMobile) {
  // Mobile strategy (cards)
  const cards = page.locator('.card');
  // ... customized logic for cards
} else {
  // Desktop strategy (table)
  const table = useTable(page.locator('#table'));
  await table.findRow({ ... });
}

NOTE

SmartRow locators are resilient to minor layout shifts, but fundamental structure changes require different selectors.


Need More Help?