admin管理员组

文章数量:1391955

I am trying to perform a controlled scroll on the home feed of a lazy loading website (similar to LinkedIn). But playwright does not support auto-scroll. So I have used the following methods:

  1. Find the "Show more results" button and click it
await page.locator('button:has-text("Show more results")').click();

The issue in this method is that the click goes on an endless loop and times out after default 30 seconds. If I set timeout:0 then it doesn't time out, it goes on for an infinite loop.

  1. While trying to control the click with waitForSelectoras shown below:
for (let i = 0; i < 20; i++) {
     let loadMore = await page.waitForSelector(('button:has-text("Show more results")');
     await loadMore.click({delay: 1000, timeout: 0});
}

It throws Element is not attached to DOM error. Log as below:

elementHandle.click: Element is not attached to the DOM
=========================== logs ===========================
attempting click action
  waiting for element to be visible, enabled and stable
  element is visible, enabled and stable
  scrolling into view if needed
  done scrolling
  performing click action
  <html lang="en" class="theme theme--mercado artdeco os…>…</html> intercepts pointer events
retrying click action, attempt #1
  waiting for element to be visible, enabled and stable
============================================================

The only possible way which could see working is:

for (let i = 0; i < 20; i++) {
    await page.keyboard.down('PageDown');
}

Any suggestions on better controlled scroll with Playwright library would be helpful :) Thank you.

I am trying to perform a controlled scroll on the home feed of a lazy loading website (similar to LinkedIn.). But playwright does not support auto-scroll. So I have used the following methods:

  1. Find the "Show more results" button and click it
await page.locator('button:has-text("Show more results")').click();

The issue in this method is that the click goes on an endless loop and times out after default 30 seconds. If I set timeout:0 then it doesn't time out, it goes on for an infinite loop.

  1. While trying to control the click with waitForSelectoras shown below:
for (let i = 0; i < 20; i++) {
     let loadMore = await page.waitForSelector(('button:has-text("Show more results")');
     await loadMore.click({delay: 1000, timeout: 0});
}

It throws Element is not attached to DOM error. Log as below:

elementHandle.click: Element is not attached to the DOM
=========================== logs ===========================
attempting click action
  waiting for element to be visible, enabled and stable
  element is visible, enabled and stable
  scrolling into view if needed
  done scrolling
  performing click action
  <html lang="en" class="theme theme--mercado artdeco os…>…</html> intercepts pointer events
retrying click action, attempt #1
  waiting for element to be visible, enabled and stable
============================================================

The only possible way which could see working is:

for (let i = 0; i < 20; i++) {
    await page.keyboard.down('PageDown');
}

Any suggestions on better controlled scroll with Playwright library would be helpful :) Thank you.

Share Improve this question asked Apr 30, 2022 at 14:27 CaptV89CaptV89 711 silver badge5 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 2

You could try to use await page.keyboard.press('End'); to scroll to the end of the page and then try it again with your locator on the show more results button.

Alternately you could also try:

await page.locator(('button:has-text("Show more results")').scrollIntoViewIfNeeded();

or more directly await page.locator('button:has-text("Show more results")').click()

because playwright click should automatically scroll the elements into view before trying to click.

I created this auto-scroll function to scroll to the bottom of the page for Shopee (shopee.sg). My app was using a proxy and a VPN.

async function autoScroll(page) {
  const maxScrolls = 100;
  const scrollDelay = 4000;
  let previousHeight = 0;
  let scrollAttempts = 0;

  while (scrollAttempts < maxScrolls) {
    await page.keyboard.down('End');
    await page.waitForTimeout(scrollDelay);
    const currentHeight = await page.evaluate(() => document.body.scrollHeight);
    if (currentHeight === previousHeight) {
      break;
    }
    previousHeight = currentHeight;
    scrollAttempts++;
  }
}

本文标签: