await page.title() in puppeteer hangs during *after* page navigation

Viewed 574

EDIT/UPDATE: Here are a couple of interesting additional facts: I had imagined that the problem was that I was hitting page.title() at some "vunlnerable" point in the page transition so since I was not getting any replies to this query, I decided to try to narrow things down a little more.

Even though I am too new to node/js/puppeteer/dom to practically discover much in the underlying system code, I decided to see what else I could glean from the application level and so with the idea that I was hitting a vulnerable point I added a long delay after the page transition - allowing the system to completely settle in the final destination page before attempting to read the title.

Strangely this did not correct the problem. i.e., something that is happening is making the page.title() function fail regardless of when it is called - once whatever is causing the problem has occurred.

I also discovered that it seems to alternate - it will work, and then fail, which is strange since the code is being restarted on each iteration. It suggests that something in the page's context is being damaged by a previous instance. So I discovered that manually refreshing the page in chrome after it has landed eliminates the problem. However, page.reload() works correctly but does not prevent the subsequent hang in page.title(). Even stranger - once the failure occurs, the next time I execute the program, it will work again - even though the page context has not been changed.

I also discovered the the page.url() function continues to function properly. (unfortunately I need the title to determine if I have landed or I would just use the URL)

I also discovered I missed some of what was going on in puppeteer during the failure. I have attached a few more debug traces which show that it is stuck repeatedly creating/destroying target objects.

IDK if this is helpful to anyone. I really would like to understand what is happening and move forward with this experiment, but as it stands I feel like I have run into an actual puppeteer bug and nothing seems to allow for a useable workaround. Fortunately this is just a learning project, so I can redirect to some other area, but I would still like to resolve this.

+++ original post: I have been trying to find ways to deal with a particular case where wait for navigation does not suffice because there may be more than one navigation.

I began a simple strategy of just monitoring the title and url properties and trapping context destruction with try catch and thought it was a solution - and it does usually work.

However, not always. Indeed if I attach it to a tab and begin navigating manually in that tab it appears I can do so indefinitely without error. I can see the page transitions in the log, as well as occasional execution context errors being trapped, but everything works correctly and the executing program never loses control.

However, if I initiate the page navigations from within my application then sometimes the code fragment below will hang on the call to page.title(). No error is generated and it stays hung permanently. I am not sure what I might be doing previously that could cause this unrelated code to fail - I am not (explicitly) attaching any event listeners or any thing else of that nature that could be hanging around to interfere. Its a pretty vanilla program in the context of puppeteer.

Through my experiments I had thought it would be safe to call page.title() at any time and the worst that would happen would be an error, but it appears that if I hit the timing just right as the page is being destroyed/navigated from it will hang.

If I interrupt the execution after it hangs, I can see it looping endlessly in websocket and browser modules. (the attached screenshots show the 3 code blocks its stuck cycling in.)

Any insight is appreciated.

const  axios  =  require('axios');
const  puppeteer  =  require('puppeteer');
        
// here is the startup/chrome environ    
async function Init() { // attach to running chrome port 9222
// retrieve the browser's debugging info as a json file in response
const  response  =  await  axios.get(`http://localhost:9222/json/version`);  
const  {  webSocketDebuggerUrl  }  =  response.data;   // Connecting the instance using `browserWSEndpoint`
//connect to brower and get a browser object to operate on.  
                 
browser  =  await  puppeteer.connect({  browserWSEndpoint: webSocketDebuggerUrl , defaultViewport:  null });  
                return browser
            }
    
// test routine that demonstrates the failure @ call to await page.title();
async function test(page){    
    for (let x = 0; x < 1000; x++) {
    try {
    title1 = await page.title();
    console.log(title1)
    console.log(x)
    await delay(250);
   } catch (error) { console.log(error) }
}
    
    
    //fragment that initiates navigation    
try {
      aSelector = "some selector text"
      await page.waitForSelector(aSelector, { timeout: 5000 })
      await page.click(aSelector, { timeout: 5000 });
      console.log("submit form success")
     } catch (error) {console.log("submit fail"}
 console.log("exit submit form");
 await test(page);
// end frag

debug trace

debug trace

debug trace

debug trace

debug trace

enter image description here

enter image description here

0 Answers
Related