You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like to propose adding a built-in helper class or Playwright command that allows users to retrieve the index of a table column by header text and interact with rows dynamically based on that index. This would simplify automating interactions with data tables, which is a common need in end-to-end testing.
Example
`
const { expect } = require('@playwright/test');
class WebTableHelper {
constructor(page) {
this.page = page;
}
// Function to get the index of the header based on its text content with customizable selector
async getIndex(headerText, headerSelector = 'tr:first-child td') {
// The selector is now passed as a parameter with a default value
const elements = await this.page.$$(headerSelector);
// Log the number of header elements found
console.log(`Found ${elements.length} header elements.`);
// Log all the header texts for debugging
for (let index = 0; index < elements.length; index++) {
let elementText = await elements[index].innerText();
// Normalize the header text by removing newlines and extra spaces
elementText = elementText.replace(/\n/g, ' ').replace(/\s+/g, ' ').trim();
console.log(`Normalized Header ${index}: ${elementText}`);
if (elementText.toLowerCase() === headerText.trim().toLowerCase()) {
return index;
}
}
throw new Error(`Header with text "${headerText}" not found`);
}
// Function to check the first row values under the given header
async checkTableValuesForTheNewFirstWebtable(headerText, expectedValueBelowTh, headerSelector, firstRowSelector = `tr:nth-child(2)`) {
const indexLocOfOurValue = await this.getIndex(headerText, headerSelector);
const firstRow = await this.page.$(firstRowSelector); // Adjust for first data row (after header)
const cells = await firstRow.$$('td');
const cell = cells[indexLocOfOurValue];
const tdText = await cell.innerText();
console.log(tdText);
expect(tdText.trim()).toBe(expectedValueBelowTh);
}
// Function to check the last non-empty row values under the given header
async checkTableValuesForTheNewLastNonEmptyRow(headerText, expectedValueBelowTh, headerSelector = `tbody tr:first-child td`, trSelector = `tbody tr`) {
const indexLocOfOurValue = await this.getIndex(headerText, headerSelector);
const rows = await this.page.$$(trSelector);
// Filter rows that contain text (non-empty)
const nonEmptyRows = [];
for (const row of rows) {
const rowText = await row.innerText();
if (rowText.trim().length > 0) {
nonEmptyRows.push(row);
}
}
// Get the last non-empty row
const lastRow = nonEmptyRows[nonEmptyRows.length - 1];
const cells = await lastRow.$$('td');
const cell = cells[indexLocOfOurValue];
const tdText = await cell.innerText();
console.log(tdText);
expect(tdText.trim()).toBe(expectedValueBelowTh);
}
}
module.exports = WebTableHelper;
**EXAMPLE OF USING IT IN TEST
// test.spec.js
const { test } = require('@playwright/test');
const WebTableHelper = require('../pageobjects/webTableHelper');
test('Verify value in the first row of the Webtable', async ({ page }) => {
const helper = new WebTableHelper(page);
await helper.checkTableValuesForTheNewFirstWebtable
// first request has different selectors, these selectors work same as default ones
('currency', 'Afghani', tbody tr:first-child td, tbody tr:nth-child(2));
});
test('Verify value in the last non-empty row of the Webtable', async ({ page }) => {
const helper = new WebTableHelper(page);
await helper.checkTableValuesForTheNewLastNonEmptyRow(Capital(s), 'Harare');
});
});
`
Motivation
Automating interactions with dynamic tables is a common use case in test automation. Currently, developers need to write custom helper functions to find column indices by header text and interact with rows, which leads to redundant code. A built-in Playwright helper class would make this process more straightforward and reusable, reducing boilerplate code in many test suites.
Proposed Solution:
I have developed a helper class that could be used as a starting point for this feature. It supports:
Retrieving the index of a column based on its header text.
Custom selectors to target specific table structures.
Flexible row interaction by referencing the column index.
Text normalization: The class includes functionality for normalizing header text by removing extra spaces and newlines, which can cause issues in matching header text. This ensures that headers are properly matched, even if there are formatting differences.
( However, I am open to further optimizations, and Playwright could implement additional trimming or newline replacement strategies if there are more efficient or optimal approaches to text normalization. This would ensure the command is robust across various table formats and text inconsistencies.)
Proposed API:
While the class implementation is flexible, this feature could also be implemented as Playwright commands or simplified APIs for users. For example:
`
// Command to get the index of a header by its text
const index = await page.getHeaderIndex('Currency', {
selector: 'thead tr th' // Optional: custom header selector
});
// Interact with a row based on header column index
const cellText = await page.getRowCellText(index, { row: 2 });
`
The text was updated successfully, but these errors were encountered:
🚀 Feature Request
I would like to propose adding a built-in helper class or Playwright command that allows users to retrieve the index of a table column by header text and interact with rows dynamically based on that index. This would simplify automating interactions with data tables, which is a common need in end-to-end testing.
Example
`
const { expect } = require('@playwright/test');
class WebTableHelper {
constructor(page) {
this.page = page;
}
}
module.exports = WebTableHelper;
**EXAMPLE OF USING IT IN TEST
// test.spec.js
const { test } = require('@playwright/test');
const WebTableHelper = require('../pageobjects/webTableHelper');
test.describe('Webtable Tests', () => {
test.beforeEach(async ({ page }) => {
await page.goto('https://cosmocode.io/automation-practice-webtable/');
});
test('Verify value in the first row of the Webtable', async ({ page }) => {
const helper = new WebTableHelper(page);
await helper.checkTableValuesForTheNewFirstWebtable
// first request has different selectors, these selectors work same as default ones
('currency', 'Afghani',
tbody tr:first-child td
,tbody tr:nth-child(2)
);});
test('Verify value in the last non-empty row of the Webtable', async ({ page }) => {
const helper = new WebTableHelper(page);
await helper.checkTableValuesForTheNewLastNonEmptyRow(
Capital(s)
, 'Harare');});
});
`
Motivation
Automating interactions with dynamic tables is a common use case in test automation. Currently, developers need to write custom helper functions to find column indices by header text and interact with rows, which leads to redundant code. A built-in Playwright helper class would make this process more straightforward and reusable, reducing boilerplate code in many test suites.
Proposed Solution:
I have developed a helper class that could be used as a starting point for this feature. It supports:
Retrieving the index of a column based on its header text.
Custom selectors to target specific table structures.
Flexible row interaction by referencing the column index.
Text normalization: The class includes functionality for normalizing header text by removing extra spaces and newlines, which can cause issues in matching header text. This ensures that headers are properly matched, even if there are formatting differences.
( However, I am open to further optimizations, and Playwright could implement additional trimming or newline replacement strategies if there are more efficient or optimal approaches to text normalization. This would ensure the command is robust across various table formats and text inconsistencies.)
Proposed API:
While the class implementation is flexible, this feature could also be implemented as Playwright commands or simplified APIs for users. For example:
`
// Command to get the index of a header by its text
const index = await page.getHeaderIndex('Currency', {
selector: 'thead tr th' // Optional: custom header selector
});
// Interact with a row based on header column index
const cellText = await page.getRowCellText(index, { row: 2 });
`
The text was updated successfully, but these errors were encountered: