New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Target creation event listeners are sometimes not executed early enough #2669
Comments
The issue rarely comes up when adding a resolve delay of 50ms to methods returning a new target, but my CI is testing so often that it can still happen. 😄 |
I noticed this only affects newly created pages. When adding Looking into side-effects of that mitigation now and how to mitigate implicitly created targets like e.g. `window.open). |
I dug deep into the lifecycle of targets to find a fix (especially for implicitly created ones) but so far didn't find a solution. I get the impression that when a target is created through e.g. I therefore think this issue can be split in two:
If anyone with more knowledge of pptr internals can confirm my suspicions that'd be great 😄 |
@berstend first of all, thanks for a good repro I could play with! 🎉
In your example, there's a race between your test function and initialization process you run in the The following worked just fine for me: const puppeteer = require('puppeteer');
const delay = ms => new Promise(resolve => setTimeout(resolve, ms))
const PUPPETEER_ARGS = ['--no-sandbox', '--disable-setuid-sandbox']
puppeteer.launch({ args: PUPPETEER_ARGS }).then(async browser => {
// Modify user agent when page is created
async function setupPage(page) {
let ua = await page.browser().userAgent()
ua = ua.replace('HeadlessChrome/', 'Chrome/')
await page.setUserAgent(ua)
}
// Define test case
const testCase = async (index) => {
const page = await browser.newPage()
await setupPage(page);
// await delay(50) // would fix this issue 99% (but not 100%) of the time
const ua1 = await page.evaluate(() => window.navigator.userAgent)
console.log(index, 'ua1', !ua1.includes('HeadlessChrome') ? 'PASS' : 'FAIL')
await page.goto('about:blank')
const ua2 = await page.evaluate(() => window.navigator.userAgent)
console.log(index, 'ua2', !ua2.includes('HeadlessChrome') ? 'PASS' : 'FAIL')
}
// Run many test cases at once
await Promise.all(
[...Array(5)].map((slot, index) => testCase(index))
)
await browser.close()
}) However, for the implicitly-created pages (or the ones that appeared due to Hope this helps! |
Steps to reproduce
Tell us about your environment:
What steps will reproduce the problem?
Please include code that reproduces the issue.
What is the expected result?
PASS
is returned for each testWhat happens instead?
FAIL
Context
Apologies if this has been reported before, I did a thorough search and could only find similar issues: #1378 #386
I'm developing a plugin framework for puppeteer (not a fork but augmenting your guys amazing work) and ran into a couple of edge-case issues with target creation event listeners.
Sometimes the listeners are not executing fast enough when a new target is created, resulting in a page not being modified quick enough for e.g. header modifications to take effect.
Overloading
browser.newPage()
/browserContext.newPage()
to a return with a small delay (e.g. 50ms) fixes this behaviour 99% of the time, but unfortunately not always and also feels like a very brittle solution in general.I assume this is an issue by design (event listeners not being blocking)?
I wonder how to best mitigate this behaviour, other then to add a random delay to methods that return a new target. Would be great to better understand where this problem originates from so I can dig deeper into the puppeteer code to find a reliable workaround. :)
Thanks!
The text was updated successfully, but these errors were encountered: