I'm writing some wrapper on top of Puppeteer. I have a general "click" function, and a "getHtml" one:
class Page {
....
async click(selector: string) {
await this.context.evaluate((querySelector, text) => {
const elem = document.querySelector(querySelector) as HTMLInputElement;
if (elem) {
elem.click();
}
}, selector);
}
async getHtml() {//
const html = await this.context.evaluate(() => {
return document.querySelector('html')?.innerHTML;
})
return html;
}
}
As you can see, click() function just receives a querySelector , and then clicks whatever element is found.
Problem is, that if this element click causes navigation, the subsequent operations might encounter this error:
Execution context was destroyed, most likely because of a navigation
For example, if the client code does something like this:
const page = new Page(...)
...
await page.click('someSelector')//If this selector matches a link, navigation is triggered.
await page.getHtml()//Then there is an Error
Is there any way, to check if there is a pending navigation, so that i could conditionally wait for it, within various functions?
I cannot just waitForNavigation by default, within the click function, because this will cause the code to hang, in case there was no navigation caused by the click.
I landed here because I was getting the Execution context was destroyed [...] after calling page.goto() and a subsequent page.content().
// dirty hack to avoid blocking of 'page.waitForNavigation()'
await page.waitForSelector('html')
page.waitForSelector('html') would immediately resolve if there is no subsequent redirects due to setting location.href or History.pushState() and wait (for one redirect) as soon as the navigation succeeds.
In my case it was due to a location.href that was set after page was loaded. In this case content was request as the page was being navigated to a new address.
page.waitForNavigation()page.waitForNavication() always blocks until a navigation succeeds. Just like OP, I could not assume that a navigation always happens and I also could not know when it happens beforehand. I wanted to avoid unnecessary blocking so this method was not a viable option.
If server responds with anything other than a valid HTML payload, page.waitForSelector('html') would block and finally timeout, throwing an error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With