0

The below code is working fine with the added delay of 75secs but that delay is not static, it changes according to the size of the file so I want to remove that delay and substitute that with a better solution. After clicking on "Save & Continue" button, the page fetches data for 2-4 mins and then it clicks on the "Let's start" button.

I tried delay function and it's working fine with it but since fetching the data is not static, I want a better solution.

//function to add delays
const delay = (time) => new Promise((resolve) => setTimeout(resolve, time));

//another save and continue click
const saveContBtn2 = await page.waitForSelector(
  '::-p-xpath(//button[text()="Save & Continue"])'
);
await saveContBtn2.click();

//let's start click
await delay(75000);
const letsStart = await page.waitForSelector(
  '::-p-xpath(//button[text()="Let\'s start"])'
);
await letsStart.click();
5
  • If the request takes between 2 and 4 minutes, there's no way to tell in advance. Does page.waitForSelector not wait that long? If not I'm sure there's an option to increase the wait time
    – Phix
    Commented Jul 8 at 5:22
  • No. "page.WaitForSelector()" doesn't wait that long. It throws timeout error. Commented Jul 8 at 5:24
  • Have you checked for the second part of my question to see if you can increase the timeout?
    – Phix
    Commented Jul 8 at 5:26
  • That is not working. Commented Jul 8 at 5:36
  • How about waitForResponse, waitForFunction or waitForSelector? If the Let's Start button appears only after the response arrives, then you can just remove the delay and increase the timeout on the waitForSelector to 5 minutes. But answering this requires seeing the actual page, or a reproduction of it. See minimal reproducible example
    – ggorlen
    Commented Jul 8 at 14:50

2 Answers 2

0

Don't use manual delays. All waiting functions in Puppeteer can be configured for longer timeouts. You only need to update

const letsStart = await page.waitForSelector(
  '::-p-xpath(//button[text()="Let\'s start"])'
);

to

const letsStart = await page.waitForSelector(
  '::-p-xpath(//button[text()="Let\'s start"]',
  {timeout: TIMEOUT} // You can pass 0 here to disable timeout entirely
);
7
  • This is not working. Commented Jul 8 at 5:46
  • Describe what happens when you add this option.
    – Kinan Dira
    Commented Jul 8 at 5:53
  • Throws this error. The xpath is correct. TimeoutError: Waiting for selector ::-p-xpath(//button[text()="Let's start"]) failed: Waiting failed: 60000ms exceeded Commented Jul 8 at 6:04
  • It is very unlikely that this is a problem with puppeteer. Try the below to make sure the timeout set is correct and that you are running the latest version of your code: var TIMEOUT = 600000; System.Console.WriteLine(TIMEOUT + ""); const letsStart = await page.waitForSelector( '::-p-xpath(//button[text()="Let\'s start"]', {timeout: TIMEOUT} );
    – Kinan Dira
    Commented Jul 8 at 6:11
  • It is the latest version and the timeout is correct and with your code, it's giving the same timeout error. Also, "System.Console.WriteLine()" is a C# code. I'm coding in puppeteer. Commented Jul 8 at 6:44
0

Puppeteer has an inbuilt function called page.waitForNetworkIdle();. Refer to the docs.

It waits till all the network requests have stopped, so it automatically handles any duration of wait times.

Hence, you can change your code to:

const saveContBtn2 = await page.waitForSelector('::-p-xpath(//button[text()="Save & Continue"])');
await saveContBtn2.click();

await page.waitForNetworkIdle();

const letsStart = await page.waitForSelector('::-p-xpath(//button[text()="Let\'s start"])');
await letsStart.click();

If after downloading the resource, you need some time to render the second button, use the timeout argument to the page.waitForSelector(...). Refer to the docs.

const GLOBAL_TIMEOUT = 60_000;
const saveContBtn2 = await page.waitForSelector('::-p-xpath(//button[text()="Save & Continue"])');
await saveContBtn2.click();

await page.waitForNetworkIdle();

const letsStart = await page.waitForSelector('::-p-xpath(//button[text()="Let\'s start"])', options = {timeout: GLOBAL_TIMEOUT});
await letsStart.click();

Or, you can set a timeout globally for the Page via:

page.setDefaultTimeout(GLOBAL_TIMEOUT);

For more details, refer to the docs.

Not the answer you're looking for? Browse other questions tagged or ask your own question.