testing-library/playwright-testing-library

Question: Search/query element by id with the Partial name

InduKrish opened this issue · 1 comments

This is the way that we use to query by id.

return await this.screen.queryByTestId('td-CrewMemberVacationAccruals-adjustmentComment-0').click(); 

the question is, Instead of querying by the complete name of the id, is there a way to query the element with the partial name of the id?
something like below: like containing partial text

return await this.screen.queryByTestId('*adjustmentComment*').click(); 

I would like to query just by the name adjustmentComment . Can you please advise how to achieve it?

i have the following test methods to iterate thru the table:

async rowGroup(id) {
        const table = await this.screen.queryByTestId(id)
        const rowGroup = this.within(table).getAllByRole('rowgroup')
        return rowGroup;
    }

    async totalRows(rowGroup) {
        let totalRows = await this.within(rowGroup.nth(1)).getAllByRole('row')
        return totalRows;
    }

    async noOfRows(rowGroup) {
        let noOfRows = await this.within(rowGroup.nth(1)).getAllByRole('row').count()
        return noOfRows;
    }

    async totalCells(totalRows, index) {
        let cellValues = await this.within(totalRows.nth(index)).getAllByRole('cell')
        return cellValues;
    }

    async noOfCells(totalRows, index) {
        let noOfCells = await this.within(totalRows.nth(index)).getAllByRole('cell').count()
        return noOfCells;
    }

   async getCell(id, index) {
        await this.page.waitForTimeout(10000);
        let rowGroup = await this.rowGroup(id)
        let totalRows = await this.totalRows(rowGroup)
        let noOfRows = await this.noOfRows(rowGroup)
        let cellValues = await this.totalCells(totalRows, index)
        let noOfCells = await this.noOfCells(totalRows,index)
        **const originalAccrualDays = await this.within(totalRows.nth(index)).queryAllByRole('cell').within().queryByTestId(/originalAccruedDays/).textContent();**
      // here retrieving using index, but i dont want to go by index as it might change anything and cause the test flaky, 
hence want to query by id. but instead of passing the exact test id, 
i want to buy just the partial text like the above line in bold, so that this method can be used for all the other rows in the table, html view is attached below.
instead of hard coding the test id of the call each time.
        // below is the link with the index of the cell, instead of hard coding the index, would like to query by partial name of the test id
        const originalAccrualDays = await cellValues.nth(3).textContent();
        return originalAccrualDays;
}

```javascript

<img width="1766" alt="Screen Shot 2022-11-09 at 2 55 22 PM" src="https://user-images.githubusercontent.com/113629123/200939845-532bce51-1925-487d-b214-ba7ac647a9a3.png">


```html
<table data-testid="paged-table-CrewMemberVacationAccruals" class="css-1n5gbw2" css="1">
<thead class="css-2006i1">
<tr data-testid="paged-table-header-CrewMemberVacationAccruals" class="css-62m37e"></tr>
</thead>
<tbody class="css-vvv4s9">
<tr data-testid="row-CrewMemberVacationAccruals-0" class="css-1p58oob">
<td data-testid="td-CrewMemberVacationAccruals-employeeId-0" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-name-0" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-seniority-0" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-originalAccruedDays-0" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-adjustedAccruedDays-0" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-adjustmentComment-0" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound1-0" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound2-0" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound3-0" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound4-0" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound5-0" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-remainingAccruedDays-0" class="css-1kxb62c"></td>
<td>
<div data-testid="actions-0" class="css-3p4l1v"></div>
</td>
</tr>
<tr data-testid="row-CrewMemberVacationAccruals-1" class="css-1p58oob">
<td data-testid="td-CrewMemberVacationAccruals-employeeId-1" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-name-1" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-seniority-1" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-originalAccruedDays-1" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-adjustedAccruedDays-1" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-adjustmentComment-1" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound1-1" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound2-1" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound3-1" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound4-1" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound5-1" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-remainingAccruedDays-1" class="css-1kxb62c"></td>
<td></td>
</tr>
<tr data-testid="row-CrewMemberVacationAccruals-2" class="css-1p58oob">
<td data-testid="td-CrewMemberVacationAccruals-employeeId-2" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-name-2" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-seniority-2" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-originalAccruedDays-2" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-adjustedAccruedDays-2" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-adjustmentComment-2" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound1-2" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound2-2" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound3-2" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound4-2" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-awardedRound5-2" class="css-1kxb62c"></td>
<td data-testid="td-CrewMemberVacationAccruals-remainingAccruedDays-2" class="css-1kxb62c"></td>
<td></td>
</tr>
<tr data-testid="row-CrewMemberVacationAccruals-3" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-4" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-5" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-6" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-7" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-8" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-9" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-10" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-11" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-12" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-13" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-14" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-15" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-16" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-17" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-18" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-19" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-20" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-21" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-22" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-23" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-24" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-25" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-26" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-27" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-28" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-29" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-30" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-31" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-32" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-33" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-34" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-35" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-36" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-37" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-38" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-39" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-40" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-41" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-42" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-43" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-44" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-45" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-46" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-47" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-48" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-49" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-50" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-51" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-52" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-53" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-54" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-55" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-56" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-57" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-58" class="css-1p58oob"></tr>
<tr data-testid="row-CrewMemberVacationAccruals-59" class="css-1p58oob"></tr>
<tr id="loader"></tr>
</tbody>
</table>
```html

As I've suggested before, please try to take a look at the Testing Library documentation to answer these sorts of API questions. The *ByTestId queries take a TextMatch for the id parameter, so you can either use a regular expression or a function:

test('get by test ID with function `TextMatch`', async ({ screen }) => {
  const locator = screen.queryByTestId(id => id.includes('adjustmentComment'))

  // ...
})

test('get by test ID with regular expression `TextMatch`', async ({ screen }) => {
  const locator = screen.queryByTestId(/adjustmentComment/)

  // ...
})

For your described case, I think a regular expression makes the most sense.