简体   繁体   中英

Puppeteer wait for popup page to load completely before procedding

I am trying to wait for a popup to load completely before proceeding but i am not sure how to accomplish this, currently i am using a await page.waitFor(3000); . Is there a more elegant way to do this and wait for the popup to fully load and then proceed.

below is my relevant part of the code.

        await page.evaluate(async () => {
          await $('#myDataExport').click();
          await $('.export-btn a').click();
        },);
        await page.waitFor(3000);
        const browserPages = await browser.pages();
        const exportPopup = browserPages[browserPages.length - 1]; 

I have also tried to use the below

await Promise.all([
 await page.click('.export-btn a'),
 await page.waitForNavigation({ waitUntil: 'networkidle2' }),
]);

But I get an error Error: Node is either not visible or not an HTMLElement

Any help in this would be really great, Thanks.

I tried to make a working example. You can just ignore the request interception code.

const puppeteer = require('puppeteer')

;(async () => {

    const browser = await puppeteer.launch({headless: false})
    const [page] = await browser.pages()

    // This network interception due to massive ads on the page
    // You can remove this if you like, as this is just an example
    // page.setRequestInterception(true)
    // page.on('request', request => {
    //    if (request.url().startsWith('https://www.w3schools.com/')) {
    //        request.continue()
    //    } else {
    //        request.abort()
    //    }
    // })

    await page.goto('https://www.w3schools.com/tags/att_a_target.asp', {waitUntil: 'domcontentloaded'})
    const [popup] = await Promise.all([
        new Promise(resolve => page.on('popup', resolve)),
   
        // THE LINES COMMENTED BELOW IS JUST AN W3SCHOOL EXAMPLE
        // page.waitForSelector('a[target="_blank"].w3-btn.w3-margin-bottom'),
        // page.click('a[target="_blank"].w3-btn.w3-margin-bottom'),
    
        // YOUR CODE SHOULD LIKE THIS
        page.waitForSelector('.export-btn a'),
        page.click('.export-btn a'),
    ])

    await popup.waitForSelector('#iframeResult')
    await popup.screenshot({path: 'targetpopup.png'})
    await popup.close()

    await browser.close()

})()

Have you tried: browser.once with targetcreated target domain event?

Calling target.page() connects Puppeteer to the tab and generates a Page object.

New tabs aren't opened immediately on click. A way to await events is to create a new promise. [source]

Example:

const newPagePromise = new Promise(resolve => browser.once('targetcreated', target => resolve(target.page()));
await page.click('.export-btn a');
const newPage = await newPagePromise;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM