Skip to content
Advertisement

Puppeteer to invoke javascript function from an external .js file

Any one has a idea on how to invoke a javascript function from puppeteer which is not inline but in an external .js file. If its inline within the html->head->script tag it works but not if the script tag points to an external .js file

Sample HTML File

JavaScript

Sample Javascript file

JavaScript

Puppeteer code sample

JavaScript

Advertisement

Answer

First of all, [name="link"] should be [name="arivalink"] to match your DOM. I assume that’s a typo.

As another aside, I recommend using the Promise.all navigation pattern instead of waitForTimeout which can cause race conditions (although this doesn’t appear to be related to the problem in this case).

As for the main issue, the external file is working just fine, so that’s a red herring. You can prove that by calling page.evaluate(() => fileFunction()) right after navigating to sample.html.

The real problem is that when you navigate with window.location.replace('https://www.geeksforgeeks.org');, Chromium isn’t pushing that action onto the history stack. It’s replacing the current URL, so page.goBack() goes back to the original about:blank rather than sample.html as you expect. about:blank doesn’t have fileFunction in it, so Puppeteer throws.

Now, when you click [name="link"] with Puppeteer, that does push the history stack, so goBack works just fine.

You can reproduce this behavior by loading sample.html in a browser and navigating it by hand without Puppeteer.

Long story short, if you’re calling a function in browser context using evaluate that runs window.location.replace, you can’t rely on page.goBack. You’ll need to use page.goto to get back to sample.html.

There’s an interesting nuance: if you use page.click to invoke JS that runs location.replace("..."), Puppeteer will push the history stack and page.goBack will behave as expected. If you invoke the same JS logic with page.evaluate(() => location.replace("..."));, Puppeteer won’t push the current URL to the history stack and page.goBack won’t work as you expect. The evaluate behavior better aligns with “manual” browsing (i.e. as a human with a mouse and keyboard on a GUI).

Here’s code to demonstrate all of this. Everything goes in the same directory and node index.js runs Puppeteer (I used Puppeteer 9.0.0).

script.js

JavaScript

sample.html

JavaScript

index.js

JavaScript
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement