3

Appreciate if anyone can help

Running in to this issue and searching around has not yielded a result regarding the puppeteer dialog modal. As such I am struggling to determine which path to take.

modal dialog

This modal dialog appears when clicking on :

await frame.click ("ul#P11_MAIN_CONTAINER_cards a:nth-child(1) > span")

This oracle Apex dialog.modal doesn't seem to have id or name only src. I am unable to access the elements in this dialog/modal .

I wonder if you have any guidance on this issue type, furthermore how does puppeteer cater to this type of "popup"

contentFrame[0] is valid contentFrame2 is valid at the base page.

  • unable to get the iframe inside the dialog/modal

  • this oracle apex modal dialog appears after the click and thus blocks the puppeteer, so how does one go about handling dialog/modal? popup?

  • does this require a targetcreated method? if so how does target created work on this part?

  • or does a new tab ( like this below ) require a const page2 = await browser.newPage();?

 tabindex="-1" role="dialog" class="ui-dialog ui-corner-all ui-widget ui-widget-content ui-front ui-dialog--apex t-Dialog--wizard ui-draggable ui-resizable" aria-describedby="apex_dialog_1" aria-labelledby="ui-id-1" style="position: fixed; height: 90%; width: 90%; top: 5%; left: 5%; max-width: 100%;">.........

Appreciate if anyone have anything to share.

    const puppeteer = require('puppeteer')
const config = require('../lib/config')
const homePage  =  require('../pages/HomePage')
const homePageObjects = require('../pageObjects/homePageObjects')
const loginPage  =  require('../pages/LoginPage')
const helper = require('../lib/helper')


describe('Home Menu Tests',() => {
    let browser
    let page

    
    before(async function(){
        browser = await puppeteer.launch({
            ignoreHTTPSErrors: true,
            headless:config.isHeadless,
            slowMo:config.slowMo,
            devtools:config.isDevtools,
            timeout:config.launchTimeout,
            Args: ['--disable-notifications','--disable-web-notification-custom-layouts'
            ,'--user-data-dir=/home/aspats3/ess/profile','--disable-features=site-per-process' ],
            executablePath:'/usr/bin/google-chrome-stable',
         
            
        })
        
        page = await browser.newPage()
        
        page.setDefaultNavigationTimeout(0);
        await page.setDefaultTimeout(config.waitingTimeout)
        await page.setViewport({
            width:config.viewRepotWidth,
            height:config.viewRepotHeight,  
      
        })
       

  
        await helper.loadUrl(page,config.baseUrl);
        await loginPage.Login(page,'AB0001','concept');

    })

    //after(async function() {
      //  await homePage.Logout(page)
        //await browser.close()
        
    //})
    


    it('Verify My Team - List  ',async()=>{
         
 
        await page.reload({ waitUntil: ["networkidle0", "domcontentloaded"] });
        await helper.hover(page,homePageObjects.homeMenu);
        await page.waitFor(3000);
        await helper.clickX(page,"//a[@id='WJ2000']");
        await page.waitForNavigation({ waitUntil: ["networkidle0", "domcontentloaded"] });
        await page.waitFor(8000);
        //await helper.shouldExistX (page,"//*[contains(.,'Team Details')]")
        //await helper.shouldExistX (page,"//*[contains(.,'Management')]")
        //await helper.shouldExistX (page,"//*[contains(.,'Leave')]")
        //await helper.shouldExistX (page,"//*[contains(.,'Timesheets')]")
        await page.waitForSelector('iframe');
        await page.waitForSelector('#P1_IFRAME')
        console.log('childFrames count:', page.mainFrame().childFrames().length);
        console.log('pageFrames count:', page.frames().length);

        const iframeHandles = await page.$$('iframe');
        
        console.log('contentFrame[0] is valid:', await iframeHandles[0].contentFrame() !== null);
        console.log('contentFrame[1] is valid:', await iframeHandles[1].contentFrame() !== null);


        const elementHandle = await page.$('div#P1_LAUNCHER iframe');
        const frame = await elementHandle.contentFrame();
        await page.waitFor(8000);


        const newPagePromise = new Promise(x => browser.on('targetcreated', target => x(target.frame()))); 
        
    
        await frame.click ("ul#P11_MAIN_CONTAINER_cards a:nth-child(1) > span")   click this for dialog modal iframe
  
  
        await frame.waitForNavigation({ waitUntil: ["networkidle0", "domcontentloaded"] });
        await page.waitFor(20000);
  
  
  //  from  here on cant get into dialog modal iframe ( nested iframe ) 
               //`
bbr
  • 41
  • 1
  • 3
  • Have you tried `page.frames`? https://stackoverflow.com/questions/46529201/puppeteer-how-to-fill-form-that-is-inside-an-iframe – Dan McGhan Apr 01 '20 at 19:45
  • @Dan McGhan appreciate the reply @ these crazy time. its kinda new to this learning as i get into it. this base page loads an iframe . Click the button frame.click ("ul#P11_MAIN_CONTAINER_cards a:nth-child(1) > span") then this popup modal occurs , so had difficulty on accessing this modal dialog page . so to answer this , yes i have tried that. with : //const frame1 = await page.frames().find(f => f.url().includes('f?p=110:5:')) //const frames = await page.frames(); //console.log('frame>>>', await frames[1].name()); still figuring out . – bbr Apr 02 '20 at 05:48

1 Answers1

2

What you can do solve your issue is to create a new async function and inside of it you can put Puppeteer's page.evaluate() function. Then click on the button and load up the modal (grab the modal by its aria-labbelledby attribute) and put its contents inside a variable. This entire function should be outside of your main function.

Then in your main function you can call this grabTheModal() function after you go to the URL.

You can do all that like this:

let modalContents;

const grabTheModal = async(page) => {
    await page.evaluate(async () => {
        await new Promise((resolve, reject) => {
            frame.click ("ul#P11_MAIN_CONTAINER_cards a:nth-child(1) > span")
            setTimeout(() => {
                const modal = document.querySelector('[aria-labelledby=ui-id-2]'); // Grab the modal by its aria label
                modalContents = modal.innerHTML;
                resolve();
            }, 500)
        });
    });
}

const getModalContents = async() => {
    let browser = await puppeteer.launch();
    let page = await browser.newPage()
    await page.goto(url, {waitUntil: 'load'}); //Remember to add your own URL in the url variable
    await grabTheModal(page);
    await browser.close();
    console.log(modalContents)
}
getModalContents();
Ludolfyn
  • 1,806
  • 14
  • 20
  • appreciate this . will give it a go . will report back. – bbr Apr 02 '20 at 05:52
  • @bbr I see that I actually made a mistake. I'm calling the wrong function inside of the `getModalContents()`. I've fixed it now, so maybe just retry this. Sorry about that. – Ludolfyn Apr 02 '20 at 06:54
  • 1
    nothing to it , i am still thinking/wrapping my head around this approach. really appreciate for the path/direction shown. will report back. – bbr Apr 02 '20 at 08:08