2

This might be a simple question, however I would like to know if there is a simple way of declaring a list of elements which later on you will be working on for example looping through it and looking for an element with a locator provided. I did some reading on https://playwright.dev/ and also some of examples on the internet. Below I am placing my example.

 <tbody class="ant-table-tbody">
    <tr data-row-key="1" class="ant-table-row-0">...</tr>
    <tr data-row-key="1" class="ant-table-row-0">...</tr>
    <tr data-row-key="1" class="ant-table-row-0">...</tr>
    <tr data-row-key="1" class="ant-table-row-0">...</tr>

Now I would like to create a list of elements, once the list is created I would like to narrow it down to just rows which contain "My group" text value and after that I would like to narrow it again to only rows which have "My group" text value but are in "Phase one" text values. All those values are text ones which are displayed in the row. Finally once I have my last list, I would like to select the 1st element from the list and perform a click operation.

I have already found similar topic -> https://stackoverflow.com/questions/66230621/getting-a-list-of-list-elements-using-playwright but I was wondering if you can work more on the more advanced lists because the example in the post is focused only on printing the results where I am would like to actually work on the elements which are in the created list.

I am using Mocha and Chai in my Playwright framework by the way.

I came up with a following solution of mine, however it does not work as expected. Below I am posting my idea.

async selectFristItemInItemCreatePhase() {
await this.page.waitForSelector('tr[class="ant-table-row-0"]', { state:'attached',});

const myItemList = await this.page.$$('tr[class="ant-table-row-0"]');
const myGroupItems = await myItemList.$$('tr:has-text("My Group Value")');
const itemInCreationPhase = await myGroupItems.$$('tr:has-text("Item Creation Phase")');
const firstItemSelected = await itemInCreationPhase[0].click;

return firstItemSelected;

After running it I am getting an error that myItemsList is not a function...

Thanks for your help and support on it.

4
  • I don't understand how these two const myGroupItems = await myItemList.$$('tr:has-text("My Group Value")'); const itemInCreationPhase = await myGroupItems.$$('tr:has-text("Item Creation Phase")'); can work with one table. When you select rows with a certain text, then the same rows won't ever contain another text. Plus that CSS selector doesn't look correct stackoverflow.com/questions/1520429/…
    – pavelsaman
    Jun 7, 2021 at 19:09
  • @pavelsaman in my understanding when you select a row by one of the searched values, you will get that row plus following values with the as well, they will be just filtered by the main value, so I was wondering if you can filter already filtered values. After some testing it seems that it is not possible and I will need to use loops to search for my values. If it goes for CSS selector, I followed the example on the Playwright doc -> await page.click('article:has-text("Playwright")'); await page.click('#nav-bar :text("Contact us")'); Jun 8, 2021 at 8:13
  • The CSS seklector is correct, I was wrong there. But I still don't understand what rows you're trying to select. If you select rows with some text, they filtering these same rows for another text doesn't make sense. Perhaps you can show us a screen, or complete HTML so we could better see what you're trying to do.
    – pavelsaman
    Jun 8, 2021 at 8:17
  • 1
    @pavelsaman I can already tell you that my idea of trying to fetch the data was not a good because it is mostly connected with your explanation. At the moment I am trying to work on const myItemList = await this.page.$$('tr[class="ant-table-row-0"]'); and loop for the element with desired values. Once I come up with a solution, I will share it. Jun 8, 2021 at 8:25

2 Answers 2

2
const myItemList = await this.page.$$('tr[class="ant-table-row-0"]');
const myGroupItems = await myItemList.$$('tr:has-text("My Group Value")');

$$ returns a list, not an object, so you cannot call myitemList.$$ , but use

const myItemList = await this.page.$$('tr[class="ant-table-row-0"]');
const myGroupItems = await myItemList[0].$$('tr:has-text("My Group Value")');

https://playwright.dev/docs/api/class-elementhandle#elementhandleselector

3
  • indeed you are right, thanks for your answer. I kind of played with it more and got something like this. Please see my answer to this question. Jun 10, 2021 at 6:53
  • Please accept and upvote if it helped
    – PDHide
    Jun 10, 2021 at 7:26
  • +1, this is more simple,precise and clear answer. Jun 12, 2021 at 23:19
0

I did some testing and playing with the and with a little bit of help I was able to create a following code which did the trick for me. Hopefully it will help others as well.

async selectFirstItemInItemCreationPhase() {
    await this.page.waitForSelector('tr[class="ant-table-row-0"]', {
      state: 'attached',
    });
    const myItemList = await this.page.$$('tr:has-text("Test Automation Group")');
    const itemsInItemsCreationPhase = await Promise.all(myItemList.map(item => item.$('td:has-text("Item Creation")')));
    const firstItem = await itemsInItemsCreationPhase[0].click();
    return firstItem;
  }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.