Milad ranjbar
Milad ranjbar

Reputation: 589

Puppeteer reload the page until some specific style changed

I want to open the web browser and continue reloading until the reloaded page has different style then move to next functions to execute unless continue reloading.

let's say i have a P tag then reload the page because display: block:

<p id="notYetStarted" style="display: block;">You need to reload the page if u can read me!</p>

but stop reloading the page because the display property of P tag is display: none; for now (and in this case instead of reloading, continue execute other codes):

<p id="notYetStarted" style="display: none;">You need to reload the page if u can read me!</p>

i tried to use Recursive function but not working:

(async () => {
    try {
//init a browser tab and wait until completely loaded then go to next step
        const browser = await puppeteer.launch({headless:false, args: ['--no-sandbox'] });
        const page = await browser.newPage();
        await page.setViewport({width:1366, height: 768})
        await page.goto(url, { waitUntil: 'networkidle2' });

// wait for Recursive function to be resolve
        await checkPTag(page)
// we are here because p.display:none
// continue execute other codes :)
    }catch(err) {
        console.log(err)
    }
})();

const checkPTag = (page) => {
  return new Promise(async (resolve, reject) => {
//search the dom for p tag and check it's display property
    let result = await isPTagAvailable(page)
    if(result === 'not started') {
      //reload the page cz p.display:block
      await page.reload({ waitUntil: ["networkidle0", "domcontentloaded"] })

//Recursive calling again
        await checkPTag(page)
    }else if(result === 'started') {
//no need reload the page cz p.none
      resolve('started')
    }
  })
}


const isPTagAvailable = (page) => {
  return new Promise (async (resolve, reject) => {
    await page.waitForSelector('#body');

    const pTags = await page.$$eval(
        '#body',
          nodes =>
            nodes.map(element => {
              const p = element.querySelector('p#notYetStarted');
              console.log(p)
            return JSON.parse(JSON.stringify(getComputedStyle(element, null).display));
            } )    
        );
    const pDisplay = pTags[0]

    if(pDisplay === 'block') {
      resolve('not started')
    }else {
      resolve('started')
    } 
  })
}

the above code open a web browser and wait until dom completely loaded and get the display value of P tag and since it is block then reload the page so far so good but then if display value changing to none but still it is try to reload the page. sry for long code

Upvotes: 3

Views: 3039

Answers (1)

Edi Imanto
Edi Imanto

Reputation: 2509

I think your code is just loading the same cache as the first request. So you should add some random number in the end of the URL to make sure the response isn't the same as the cache of the first response.

const puppeteer = require ('puppeteer')

const urlPage = 'http://localhost/testing/test_display_none.html'

;(async () => {

    const browser = await puppeteer.launch ({
        headless: false,
        devtools: false
    })

    const [page] = await browser.pages ()

    page.setDefaultNavigationTimeout(0)

    const functionToExecute = async () => {
        // Code to run if P tag display is none (hidden)
        console.log ('P tag display = none\n Executing next defined function...')
    }

    const ifTagPdisplayed = async () => {

        const openPage = await page.goto ( urlPage + '?r=' + Date.now() , { waitUntil: 'networkidle2', timeout: 0 } )

        const elemExist = await page.waitForSelector ('#notYetStarted', { timeout: 0 })

        const getDisplay = await page.evaluate ( () => document.querySelector('#notYetStarted').style.display === 'none' )

        if ( !getDisplay ) {
            await ifTagPdisplayed ()
        } else {
            await functionToExecute ()
        }

    }

    await ifTagPdisplayed ()

})()

Upvotes: 1

Related Questions