Page.evaluate results in error

Hi,
I’m currently in the process of converting an existing Java Playwright test to k6 with the browser plugin.
I’ve now hit a roadblock at a seemingly innocent piece of code:

    await page.goto('http://172.29.254.144:9980/mic-server/rap?prefLanguage=EN');

    //wait for application to load
    sleep(5);

    //PREREQUITSITES
    Promise.all([page.waitForNavigation({timeout: 1000}),
      page.evaluate("document.rapBusy = false")])
        .then(() => {
          console.log("ok");
        }).catch(e => {
      console.log("err: "+ e);
    });

waitForNavigation will always run into the timeout regardless of how high I set it, page.evaluate will then spit out an error:

Uncaught (in promise) GoError: evaluating JS: execution context changed; most likely because of a navigation
running at github.com/grafana/xk6-browser/common.(*Page).Evaluate-fm (native)
browser at browserTest

There is nothing going on at the browser when this occurs according to the browser window in non-headless mode.

DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403 tid:4DDCD00B1E3989B8FEB89AFD373DCD9E fid:4DDCD00B1E3989B8FEB89AFD373DCD9E event:InteractiveTime eventTime:"2024-03-28 18:23:21.5980008 +0100 CET m=+87.227018001"  category="FrameSession:onPageLifecycle" elapsed="807 ms" iteration_id=269855ff087e05ae source=browser
DEBU[0009] fid:4DDCD00B1E3989B8FEB89AFD373DCD9E furl:http://172.29.254.144:9980/mic-server/rap?prefLanguage=EN timeoutCtx done: context deadline exceeded  category="Frame:WaitForNavigation" elapsed="142 ms" iteration_id=269855ff087e05ae source=browser
DEBU[0009] fid:4DDCD00B1E3989B8FEB89AFD373DCD9E furl:http://172.29.254.144:9980/mic-server/rap?prefLanguage=EN  category="Frame:WaitForNavigation:return" elapsed="0 ms" iteration_id=269855ff087e05ae source=browser               
DEBU[0009]                                               category="Browser:Close" elapsed="0 ms" iteration_id=269855ff087e05ae source=browser                                                                                       
DEBU[0009]                                               category="Browser:GracefulClose" elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                                                                               
DEBU[0009] wsURL:"ws://127.0.0.1:24493/devtools/browser/ac6d2767-a8c8-4118-9092-6acb7a5c598c" method:"Browser.close"  category="connection:Execute" elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                     
DEBU[0009] sid: method:""                                category="Connection:recvLoop:msg.ID:emit" elapsed="0 ms" iteration_id=269855ff087e05ae source=browser                                                                     
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403 tid:4DDCD00B1E3989B8FEB89AFD373DCD9E wsURL:ws://127.0.0.1:24493/devtools/browser/ac6d2767-a8c8-4118-9092-6acb7a5c598c  category="Connection:closeSession" elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                                                                                                                                                                                                   
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403 tid:4DDCD00B1E3989B8FEB89AFD373DCD9E  category="Session:close" elapsed="0 ms" iteration_id=269855ff087e05ae source=browser                                                          
DEBU[0009] sid: method:"Target.detachedFromTarget"       category="Connection:recvLoop:msg.Method:emit" elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                                                                 
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403 tid:4DDCD00B1E3989B8FEB89AFD373DCD9E  category="FrameSession:initEvents:go:session.done" elapsed="0 ms" iteration_id=269855ff087e05ae source=browser                                
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403 tid:4DDCD00B1E3989B8FEB89AFD373DCD9E  category="NewFrameSession:initEvents:go:return" elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                                   
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403 tid:4DDCD00B1E3989B8FEB89AFD373DCD9E  category="Session:readLoop:<-s.done" elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                                              
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403 tid:4DDCD00B1E3989B8FEB89AFD373DCD9E  category="Page:initEvents:go:session.done" elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                                        
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403          category="Browser:initEvents:onDetachedFromTarget" elapsed="0 ms" iteration_id=269855ff087e05ae source=browser                                                             
DEBU[0009] received IO error: websocket: close 1006 (abnormal closure): unexpected EOF, connection is closing: true  category=cdp elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                                       
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403 tid:4DDCD00B1E3989B8FEB89AFD373DCD9E  category="Page:initEvents:go:return" elapsed="0 ms" iteration_id=269855ff087e05ae source=browser                                              
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403 tid:4DDCD00B1E3989B8FEB89AFD373DCD9E  category="Browser:onDetachedFromTarget" elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                                           
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403 tid:4DDCD00B1E3989B8FEB89AFD373DCD9E  category="Browser:onDetachedFromTarget:deletePage" elapsed="0 ms" iteration_id=269855ff087e05ae source=browser                                
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403          category="Page:didClose" elapsed="0 ms" iteration_id=269855ff087e05ae source=browser                                                                                       
DEBU[0009] sid:CC060F67E3A80AB0DC7388590CA7F403 tid:4DDCD00B1E3989B8FEB89AFD373DCD9E  category="Browser:onDetachedFromTarget:return" elapsed="2 ms" iteration_id=269855ff087e05ae source=browser                                    
DEBU[0009] wsURL:"ws://127.0.0.1:24493/devtools/browser/ac6d2767-a8c8-4118-9092-6acb7a5c598c" code:1001  category="connection:Close" elapsed="81 ms" iteration_id=269855ff087e05ae source=browser
DEBU[0009] code:1001                                     category="Connection:close" elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                                                                                    
DEBU[0009] wsURL:ws://127.0.0.1:24493/devtools/browser/ac6d2767-a8c8-4118-9092-6acb7a5c598c  category="Connection:closeAllSessions" elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                                     
DEBU[0009]                                               category="Browser:initEvents:EventConnectionClose" elapsed="0 ms" iteration_id=269855ff087e05ae source=browser                                                             
DEBU[0009] ctx err: <nil>                                category="Browser:initEvents:defer" elapsed="1 ms" iteration_id=269855ff087e05ae source=browser                                                                            
ERRO[0009] Uncaught (in promise) GoError: evaluating JS: execution context changed; most likely because of a navigation                                                                                                             
running at github.com/grafana/xk6-browser/common.(*Page).Evaluate-fm (native)                                                                                                                                                       
browser at browserTest (file:///C:/Users/mmaisrie/RAP.js:43:20(47))  executor=constant-vus scenario=browser 

Any help would be appreciated.

Hi!

Thanks for trying out k6 browser. I apologize for not answering sooner, but I hope that I can help.

I think that the reason that the waitForNavigation times out is that there’s nothing causing a navigation.

page.goto will not resolve until it receives the load event from the document (can be configured via the waitUntil option).

The function waitForNavigation method works the same way: it waits for a page load event to fire, but by the time your code reaches waitForNavigation the event will already have been fired. So it times out waiting for something that will never come.

The use-case for waitForNavigation is to wait for navigation to finish after performing some user action, e.g:

await loginBtn.click(); // resolves when the click action is done
await page.waitForNavigation(); // resolves once the new page has loaded

If I may give some other tips: I would avoid relying on sleep to wait for loading to complete. It is generally better to use waitForSelector to wait for the existence of some element as an indicator that it’s safe to proceed. For instance, if I’m testing a login form then it’s reasonable to wait for the login button to appear:

const loginBtn = page.waitForSelector("#login-button");

Not only is this more robust, but it will also improve the performance of the test since the element is likely going to be available sooner than 5 seconds.

I also want to note that you are not awaiting the Promise returned from Promise.all, which means that the function might exit before either promise has resolved.

I hope that he above information is enough to make your script work. As for the error message, my best guess would be that it’s a combination of the timeout on waitForNavigation and that the function goes out of scope due to not awaiting the Promise.all.

1 Like

Besides what @johanallansson said, you also don’t have to use Promise.all for page.evaluate as it doesn’t return a Promise. So, you can just do:

await page.goto('https://test.k6.io/', { waitUntil: 'networkidle', timeout: 1000 });
// maybe increase this timeout to see if it changes the behavior
page.evaluate("document.rapBusy = false");
console.log("ok");