Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Click button if it is present, else click a different button in puppeteer

I am trying to set up an if/else statement in puppeteer to click on a button if it is present, else click on another button. I am doing something like this:

if (document.querySelector('#buttonToClick') !== null) {
    await page.waitForSelector('#buttonToClick');
    await page.click('#buttonToClick');
  } 

else { 
// first click #otherButton and then click #buttonToClick
    await page.waitForSelector('#otherButton');
    await page.click('#otherButton');

    await page.waitForSelector('#buttonToClick');
    await page.click('#buttonToClick');
  }

For some reason I keep falling into the else block even when I go to my Chrome console and do a document.querySelector('#buttonToClick') !==null on the desired page and it is showing as true

UPDATE: The following code seems to be working for me, but I am not sure why

await page.waitFor(3000);

  if ((await page.$('#buttonToClick')) !== null) {
    await page.click('#buttonToClick');
  } else {
    await page.waitForSelector('#otherButton');
    await page.click('#otherButton');

    await page.waitForSelector('#buttonToClick');
    await page.click('#buttonToClick');
  }`

I thought maybe it might have something to do with the way the DOM loads, so I tried:

await page.waitForNavigation({waitUntil: 'domcontentloaded'})
// await page.waitFor(3000)

  if ((await page.$('#buttonToClick')) !== null) {
    await page.click('#buttonToClick');
  } else {
    await page.waitForSelector('#otherButton');
    await page.click('#otherButton');

    await page.waitForSelector('#buttonToClick');
    await page.click('#buttonToClick');
  }

But that didn't work...it only works with await page.waitFor(30000) before the if statement...any ideas why?

like image 542
HaagenDaaS Avatar asked Jan 29 '23 01:01

HaagenDaaS


1 Answers

I don't think that document.querySelector normally exists inside a node.js program. Puppeteer does provide page.$, which is a close analog. It returns a Promise.

Update: With the new information in the question, it sounds like the part of the DOM tree that contains #buttonToClick is constructed after the DOMContentLoaded event. I've had good results using page.waitForNavigation({ waitUntil: 'networkidle0' }), though 'networkidle2' or some other option might be better if you have lingering network connections. See the various options here: https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions

I suspect this should work:

await page.waitForNavigation({ waitUntil: 'networkidle0' });
if (await page.$('#buttonToClick') !== null) {
    await page.click('#buttonToClick');
  } else {
    await page.waitForSelector('#otherButton');
    await page.click('#otherButton');
  }
like image 104
Steve Avatar answered Jan 31 '23 09:01

Steve