itsPav
itsPav

Reputation: 612

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?

Upvotes: 8

Views: 29597

Answers (2)

Kashif
Kashif

Reputation: 21

Same as the solution below, however if i've understood correctly, you should have the click event first and then wait for navigation.

await Promise.all([
page.click('button'),
page.waitForNavigation(),
]);

Upvotes: 0

Seth Holladay
Seth Holladay

Reputation: 9539

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).

Upvotes: 12

Related Questions