Skip to content

(#513) Add function to find row in table by text#514

Open
alexaveldanez wants to merge 1 commit intochocolatey:mainfrom
alexaveldanez:find-row-in-tables
Open

(#513) Add function to find row in table by text#514
alexaveldanez wants to merge 1 commit intochocolatey:mainfrom
alexaveldanez:find-row-in-tables

Conversation

@alexaveldanez
Copy link
Contributor

@alexaveldanez alexaveldanez commented Jan 29, 2026

Description Of Changes

Adds function to find the first row with specified text in a table and return the locator of that row.

Motivation and Context

This will help automating manual tests.

Testing

  1. From CCM website run node "C:\Program Files (x86)\Yarn\bin\yarn.js" up '@chocolatey-software/playwright@alexaveldanez/choco-theme#head=find-row-in-tables&workspace=@chocolatey-software/playwright'
  2. In CCM website delete row-in-table.ts file from choco-licensed-management-ui\src\ChocolateySoftware.ChocolateyManagement.Web.Mvc\playwright\functions
  3. In CCM website go to software.spec.ts and update the import to import { findRowInTable } from '@choco-playwright/functions/find-row-in-table';
  4. In CCM website go to administration-users-lockout-enabled.spec.ts and update the import to import { findRowInTable } from '@choco-playwright/functions/find-row-in-table';
  5. From CCM run yarn playwright-functionality software.spec.ts administration-users-lockout-enabled.spec.ts.
  6. All tests should pass.

Operating Systems Testing

Change Types Made

  • Bug fix (non-breaking change).
  • Feature / Enhancement (non-breaking change).
  • Breaking change (fix or feature that could cause existing functionality to change).
  • Documentation changes.
  • PowerShell code changes.

Change Checklist

  • Requires a change to the documentation.
  • Documentation has been updated.
  • Tests to cover my changes, have been added.
  • All new and existing tests passed?
  • PowerShell code changes: PowerShell v3 compatibility checked?

Related Issue

#513

Fixes #513

Adds function to find the first row with specified text in a table and
return the locator of that row.
@alexaveldanez alexaveldanez self-assigned this Jan 29, 2026
@st3phhays
Copy link
Member

The audit flow will be fixed in this PR #507.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new Playwright helper function findRowInTable to assist with test automation. The function searches for a row containing specific text within a table and handles pagination automatically by clicking through pages until the row is found.

Changes:

  • Added find-row-in-table.ts function that searches tables for rows with specific text content
  • Includes pagination support by clicking "Next" button and checking aria-disabled attribute
  • Returns the locator of the first matching row or throws an error if not found

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


const ariaDisabled = await btnNext.getAttribute('aria-disabled');

if (ariaDisabled) {
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The condition if (ariaDisabled) checks for any truthy value, but getAttribute() returns string | null. This means the check will treat the string "false" as truthy and incorrectly break the loop. The condition should explicitly check for the value "true": if (ariaDisabled === 'true') to properly determine when the Next button is disabled.

Suggested change
if (ariaDisabled) {
if (ariaDisabled === 'true') {

Copilot uses AI. Check for mistakes.
/**
* Finds the first row with specific text in a table and returns the locator for that row.
* @function findRowInTable
* @param {Locator} table - The locator for the table.
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSDoc documents a table parameter that is never used in the function implementation. This documentation is misleading and should either be removed (if the parameter is removed) or updated to reflect the actual usage. The current implementation searches for rows in the entire page, not scoped to a specific table.

Copilot uses AI. Check for mistakes.
await waitForTables(page);
}

throw new Error(`${text} not found in the table after checking all pages.`);
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message uses template literal syntax but doesn't escape the text parameter, which could lead to confusing error messages if the search text contains special characters or is very long. Consider wrapping the text in quotes for clarity: throw new Error(\Row with text "${text}" not found in the table after checking all pages.`);`

Suggested change
throw new Error(`${text} not found in the table after checking all pages.`);
throw new Error(`Row with text "${text}" not found in the table after checking all pages.`);

Copilot uses AI. Check for mistakes.
Comment on lines +18 to +32
while(true) {
const row = page.locator('tr', { has: page.locator('td', { hasText: text })});

if (await row.count() > 0) {
return row.first();
}

const ariaDisabled = await btnNext.getAttribute('aria-disabled');

if (ariaDisabled) {
break;
}

await btnNext.click();
await waitForTables(page);
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function could enter an infinite loop if the "Next" button doesn't have an aria-disabled attribute when it reaches the last page. Consider adding a timeout or maximum page count as a safety mechanism. Additionally, if the Next button doesn't exist on the page at all, the getAttribute() call on line 25 could throw an error. Add existence checks or error handling to make the function more robust.

Copilot uses AI. Check for mistakes.
* @returns {Locator} - Locator for the row.
*/

export const findRowInTable = async(table: Locator, page: Page, text: string) => {
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The table parameter is declared but never used in the function body. All locator operations use page.locator() directly instead of scoping to the provided table. Either remove this parameter if it's not needed, or use it to scope the row search to a specific table (e.g., table.locator('tr', ...)). Based on the function's purpose, it appears the parameter should be removed since the function searches the entire page.

Copilot uses AI. Check for mistakes.
* @returns {Locator} - Locator for the row.
*/

export const findRowInTable = async(table: Locator, page: Page, text: string) => {
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space between async and the opening parenthesis. This should be async (table: Locator, page: Page, text: string) to match the formatting convention used in other functions in this codebase (see convert-to-file-path.ts:15, expand-section.ts:17, wait-for-tables.ts:11).

Suggested change
export const findRowInTable = async(table: Locator, page: Page, text: string) => {
export const findRowInTable = async (table: Locator, page: Page, text: string) => {

Copilot uses AI. Check for mistakes.
* @returns {Locator} - Locator for the row.
*/

export const findRowInTable = async(table: Locator, page: Page, text: string) => {
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function signature is missing an explicit return type. According to the codebase convention, all async functions should specify their return type (see examples in convert-to-file-path.ts:15, expand-section.ts:20, wait-for-tables.ts:11). Add : Promise<Locator> after the parameter list to match this pattern.

Copilot uses AI. Check for mistakes.
export const findRowInTable = async(table: Locator, page: Page, text: string) => {
const btnNext = page.getByRole('link', { name: 'Next' });

while(true) {
Copy link

Copilot AI Jan 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space after while. The code has while(true) but should be while (true) to match standard formatting conventions.

Suggested change
while(true) {
while (true) {

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add functionality to find a row in a table by text in Playwright testing

2 participants