Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Puppeteer go to a different page

I'm trying to get my script to go to a new page after successfully logging in, however, it attempts to go to the next page before login is complete.

  const page = await browser.newPage();

  page.goto('https://website/login');

  page.once('load', async () => {
    console.log('Page loaded!');
    // Login script here
  });

I can't figure out how to go to a new link after logging in though, my original solution was to just do;

// go to stats
await page.goto('https://www.website/stats');

However, since the page is already defined, this doesn't really wait for anything.

Is it possible to have a callback in the .click() function to go to a new page after?

like image 641
itsPav Avatar asked Jan 27 '23 23:01

itsPav


1 Answers

The correct way to navigate via a click and wait for page load is to use Promise.all() and page.waitForNavigation(), like this:

await Promise.all([
    page.waitForNavigation(),
    page.click('#some-link')
]);

However, when you are navigating via page.goto(), the above is not necessary, because page.goto() waits for page load automatically.

In both cases, you can customize which event it waits for, using the waitUntil option, which defaults to the load event.

page.goto(url[, options])

  • url URL to navigate page to. The url should include scheme, e.g. https://.
  • options Navigation parameters which might have the following properties:
    • timeout Maximum navigation time in milliseconds, defaults to 30 seconds, pass 0 to disable timeout. The default value can be changed by using the page.setDefaultNavigationTimeout(timeout) method.
    • waitUntil When to consider navigation succeeded, defaults to load. Given an array of event strings, navigation is considered to be successful after all events have been fired. ...

Putting this together, an example of logging in would be:

const page = await browser.newPage();

await page.goto('https://website/login');

await page.type('input[type="email"]', '[email protected]');
await page.type('input[type="password"]', 'pass1234');
await Promise.all([
    page.waitForNavigation(),
    page.click('button')
]);

// Now we are on the home page (or wherever we end up after logging in)

Some other notes:

  • You may need to use page.waitForSelector() or other forms of waiting if the page load event fires before the input field is ready.
  • You could alternatively submit the login form by pressing the Enter key with the keyboard. This would still require the Promise.all() pattern, but means you don't need a selector for the submit button. You may need to .click() one of the input fields depending on how the page is implemented (e.g. if the page does not use autofocus).
like image 169
Seth Holladay Avatar answered Jan 29 '23 13:01

Seth Holladay