1

I have an interesting element to locate in playwright.

There is a list of rows that comes up when I visit a URL. The number of records that comes from an API called on that page is say 400 but only first 100 rows from those records are shown in the page. Also there are empty divs created in HTML, like for example in this case since total records were 400 so code will create say 4 empty divs and fill the first div with 100 row elements and rest of the 3 divs will be empty. When user scrolls then following happens -

A. Initially only 1-100 records are shown in the first div. Please note that the other records are not even there in the HTML.

B. When user scrolls till the point the 101th element just enters the viewport, then the elements from 101 till 200 gets populated and displayed in second div.

C. When user scroll such that the last element of the first set i.e. 100th element goes beyond the top of the viewport then the first div becomes empty. So now the first div is empty and second one has 100 elements from 101-200 and rest of the 2 divs are empty.

And so on D, E, F and G...See below pattern for better understanding :

A.

<div class="gridRowContainer">
 <div>100 elements here(1-100)...</div>
 <div></div>
 <div></div>
 <div></div>
</div>

B.

<div class="gridRowContainer">
 <div>100 elements here(1-100)...</div>
 <div>100 elements here(101-200)...</div>
 <div></div>
 <div></div>
</div>  

C. elements from 1-100 are NOT visible because they just passed the top of viewport

<div class="gridRowContainer">
 <div></div>
 <div>100 elements here(101-200)...</div>
 <div></div>
 <div></div>
</div> 

D.

<div class="gridRowContainer">
 <div></div>
 <div>100 elements here(101-200)...</div>
 <div>100 elements here(201-300)...</div>
 <div></div>
</div>

E. elements from 101-200 are NOT visible because they just passed the top of viewport

 <div class="gridRowContainer">
   <div></div>
   <div></div>
   <div>100 elements here(201-300)...</div>
   <div></div>
 </div>

F.

 <div class="gridRowContainer">
   <div></div>
   <div></div>
   <div>100 elements here(201-300)...</div>
   <div>100 elements here(301-400)...</div>
 </div>

G. elements from 201-300 are NOT visible because they just passed the top of viewport

 <div class="gridRowContainer">
   <div></div>
   <div></div>
   <div></div>
   <div>100 elements here(301-400)...</div>
 </div>

. . .

What I want to do : Each element that are displayed inside each of these 4 divs looks like this <div>Some random text</div> except for one div <div>Target text</div>. I want to extract the text from this div.

Currently I have a locator that successfully extract this text by getByText() method. It is able to do that because this element comes in the list of first 100 elements. However if this element was present somewhere in the list starting from 101-200 or 201-300 or 301-400, then it won't be visible when we land on the page unless we scroll past the point where we display the div that has the target element.

What I want to know: I want an approach that could help me tackle this problem where I am able to locate the required target element no matter in which div it lies.

utkarsh-k
  • 836
  • 8
  • 17

1 Answers1

0

How about keep on scrolling till you find your target:

 const sizes = await page.evaluate(() => {
    const browserHeight = window.innerHeight;
    const pageHeight = document.body.scrollHeight;
    return { browserHeight, pageHeight };
  });

  for (let i = 0; i < sizes.pageHeight; i += sizes.browserHeight) {
    await page.mouse.wheel(0, i);
    console.log("scrolled to", i);
    await page.waitForTimeout(1000);
    if (await page.getByText("Target text").isVisible()) 
      break;
  }
Vishal Aggarwal
  • 1,929
  • 1
  • 13
  • 23
  • `while (!(await page.getByText("Target text").isVisible())) {await page.mouse.wheel(0, 100);}` - I tried it but somehow the `page.mouse.wheel` is executing but the scrolling is not happening in the page and finally the test times out. Please note that I have increased the timeout to 3 minutes and it is sufficient time. – utkarsh-k Aug 11 '23 at 05:06
  • Also `page.mouse.wheel` is working fine in other pages of my app. Only in the page where my target is, it is not working somehow. I have tried `page.keyboard.press("PageDown")` `page.keyboard.press("DownArrow")`. Both these are also not working in this page. Anything that could potentially be stopping the scroll? – utkarsh-k Aug 11 '23 at 07:12
  • If it's working in other pages , do they also have lazy loading? – Vishal Aggarwal Aug 11 '23 at 10:07
  • In other pages I mean that `page.mouse.wheel` or `page.keyboard.press("PageDown")` are working fine i.e the scrolling ways from playwright are working fine. I don't know why the same methods are not working in the page where my target is. I ran playwright in debug mode and found that code is going inside the while loop and the `page.mouse.wheel` is getting executed but scroll is not reflecting in the UI. In UI the scrollbar stays at the top only. I am not able to figure out why that is happening or what alternative I could try to test the scrolling on this page. – utkarsh-k Aug 12 '23 at 09:53
  • @utkarsh-k, please see the updated answer. – Vishal Aggarwal Aug 12 '23 at 18:04
  • thank you for sharing the updated answer. Actually the condition inside the while loop i.e the locator `page.locator('div[class="gridRowContainer"] div')` will always be present because initially during the page load. 4 divs are created inside the `
    `. There is something else going on. The code always goes inside the while loop, executes `page.mouse.wheel(0, 100)` and then comes back again inside the while loop and do the same and so on but scroll doesn't happen in the UI. I really appreciate your help though. thank you
    – utkarsh-k Aug 14 '23 at 10:21
  • @utkarsh-k , I have completely revised the code based on your comments taking different approach . Please try and let me know if it works. – Vishal Aggarwal Aug 15 '23 at 11:43
  • thanks for sharing. I will update you as soon as I try. – utkarsh-k Aug 28 '23 at 09:40
  • The scrolling is not happening. I don't know why. Also in doc it is mentioned that `page.mouse.wheel` will not wait for scrolling to finish. Isn't it the cause? https://playwright.dev/docs/api/class-mouse#mouse-wheel – utkarsh-k Aug 28 '23 at 12:24
  • I assume, it works manually? – Vishal Aggarwal Aug 28 '23 at 15:58
  • There is something happening with this page. When I simply add say await page.mouse.wheel(0, 40) then also it doesn't scroll. I don't know where to look now. – utkarsh-k Aug 28 '23 at 16:42
  • If it works with same playwright code on other pages, then there is something wrong with this page , not with playwright code . – Vishal Aggarwal Aug 28 '23 at 16:44