Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I wait for network idle after click on an element in puppeteer?

How can I wait for network idle after click on an element in puppeteer?

const browser = await puppeteer.launch({headless: false});
await page.goto(url, {waitUntil: 'networkidle'});

await page.click('.to_cart'); //Click on element trigger ajax request
//Now I need wait network idle(Wait for the request complete)
await page.click('.to_cart');

UPD: No navigation after the element was clicked

like image 908
matchish Avatar asked Jan 26 '19 10:01

matchish


People also ask

How to wait for an element in puppeteer?

page.waitForSelector () and page.waitForXPath () is used to wait for an element. By default, the timeout is 30 sec in puppeteer. But we can change it according to the requirement.

How to change the default page timeout in puppeteer?

page.waitForSelector () and page.waitForXPath () is used to wait for an element. By default, the timeout is 30 sec in puppeteer. But we can change it according to the requirement. page.setDefaultTimeout (ms) is used to change the default timeout. page.setDefaultNavigationTimeout (ms) is used to change the navigation timeout.

What is the difference between waituntil and timeout in puppeteer?

The options for page.goto allows us to define an object with timeout and waitUntil. The timeout is how long Puppeteer will wait, in milliseconds, for the page to load before it throws and error and stops running. For waitUntil we can choose from: load, domcontentloaded, networkidle0, networkidle2.

What is explicit Wait in puppeteer?

Explicit wait or static wait is used to wait for a fixed or static time frame. for example, I set explicit wait like 50 sec. it means it will wait 50 sec before executing the next line of code. page.waitFor (time in ms) function is used to perform explicit wait in puppeteer.


Video Answer


2 Answers

I ran into a similar issue and found the workaround function on the Puppeteer Control networkidle wait time issue to suit my needs: https://github.com/GoogleChrome/puppeteer/issues/1353#issuecomment-356561654

Essentially, you can create a custom function, and call that prior to any additional steps:

function waitForNetworkIdle(page, timeout, maxInflightRequests = 0) {
  page.on('request', onRequestStarted);
  page.on('requestfinished', onRequestFinished);
  page.on('requestfailed', onRequestFinished);

  let inflight = 0;
  let fulfill;
  let promise = new Promise(x => fulfill = x);
  let timeoutId = setTimeout(onTimeoutDone, timeout);
  return promise;

  function onTimeoutDone() {
    page.removeListener('request', onRequestStarted);
    page.removeListener('requestfinished', onRequestFinished);
    page.removeListener('requestfailed', onRequestFinished);
    fulfill();
  }

  function onRequestStarted() {
    ++inflight;
    if (inflight > maxInflightRequests)
      clearTimeout(timeoutId);
  }

  function onRequestFinished() {
    if (inflight === 0)
      return;
    --inflight;
    if (inflight === maxInflightRequests)
      timeoutId = setTimeout(onTimeoutDone, timeout);
  }
}

// Example
await Promise.all([
  page.goto('https://google.com'),
  waitForNetworkIdle(page, 500, 0), // equivalent to 'networkidle0'
]);
like image 139
Rob C Avatar answered Oct 22 '22 06:10

Rob C


There are two methods in Puppeteer docs.

  • page.waitForRequest(urlOrPredicate[, options])
  • page.waitForResponse(urlOrPredicate[, options])

Example:

await Promise.all([
    page.waitForRequest(callback), 
    page.waitForResponse(callback)
])
like image 27
Naimur Rahman Avatar answered Oct 22 '22 06:10

Naimur Rahman