Search code examples
javascriptnode.jspuppeteerheadless-browser

Puppeteer `waitForNavigation` always return timeout


This question might have been asked previously but all the existing solutions in Stackoverflow were not able to help me. I have the following snippet:

const puppeteer = require('puppeteer');

const loginFn = async () => {
  const browser = await puppeteer.launch();

  const deviceWidth = 1920;
  const deviceHeight = 1080;

  const page = await browser.newPage();

  await page.setCacheEnabled(false);
  await page.setViewport({ width: deviceWidth, height: deviceHeight });
  await page.setUserAgent(
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
  );
  await page.goto('https://testwebsite.com/');

  await page.click('.qrNYy');
  await page.waitForSelector('input[type="email"]');
  await page.waitForSelector('input[type="password"]');

  await page.type('input[type="email"]', 'test@gmail.com');
  await page.type('input[type="password"]', 'test123');

  await Promise.all([
    page.click('.ffwHVz'),
    page.waitForNavigation({
      waitUntil: 'networkidle0',
    }),
  ]);

  await page.screenshot({ path: 'example.png' });
  await browser.close();
}

(async () => {
  await loginFn();
})();

I always get TimeoutError: Navigation timeout of 30000 ms exceeded error, I tried all options for waitUntil including networkidle0, networkidle2, load and domcontentloaded to no avail (these came from googling and stackoverflow). I also used Promise.all on click and waitForNavigation as suggested by many of those aforementioned solutions but I can't seem to bypass this issue.

Is it because of the website itself? Is this a case to case basis depending on the website itself or is it my code? Note: testwebsite.com is just a sample but that's what exactly happens on the site I'm testing on, I can't seem to get thru no matter how hard I try. Can anyone help me here?


Solution

  • Puppeteer doc for waitForNavigation states:

    This resolves when the page navigates to a new URL or reloads

    Being an SPA, Coinmarketcap doesn't reload page or navigate to another page when logging in or registering, so waitForNavigation won't work here.

    Instead I suggest that you wait for an element which is only present when a user is logged in. This will probably work (untested):

      await Promise.all([
        page.click('.ffwHVz'),
        page.waitForSelector('.icon-User-Filled'),
      ]);