Correct way to inject JS files within headless mode?

2,435 views
Skip to first unread message

Michael

unread,
May 8, 2017, 2:41:42 PM5/8/17
to headless-dev
Hi,

I've been trying to understand the https://chromedevtools.github.io/devtools-protocol/tot/ for my development, but I can't quite figure out the proper way to inject JS code into the headless instance.

Originally, I had thought that I would use Page.addScriptToEvaluateOnLoad, but that doesn't seem to do anything for me (it runs, returns a script id, but does not seem to have any effect on the browser). The only things I've been able to do have been running one liners using Runtime.evaluate, but for cases where I'd want to inject either jquery or lodash, I don't see how to make this possible without referencing an external site using script tags as part of the data:text/html I create. I wasn't sure if maybe I needed to use Runtime.compileScript/runScript, but I don't quite understand what the sourceUrl would be if I'm defining the expression. I'm using the chrome-remote-interface library to do all this in NodeJS in an effort to replace a service using PhantomJS.

I'm very new to these DevTools Protocols, so if anyone also happens to know of any other documentation that may shed more light as to what each Domain's methods are actually doing, that would be greatly appreciated.

Thanks,
Michael

Alex Clarke

unread,
May 8, 2017, 2:58:02 PM5/8/17
to Michael, headless-dev
On 8 May 2017 at 19:41, Michael <marczak...@gmail.com> wrote:
Hi,

I've been trying to understand the https://chromedevtools.github.io/devtools-protocol/tot/ for my development, but I can't quite figure out the proper way to inject JS code into the headless instance.

Originally, I had thought that I would use Page.addScriptToEvaluateOnLoad,
That really should work. Note the script gets run very early, before the page load is complete (BTW if the page is already loaded this won't do anything until you navigate.  A common use pattern is to initially load about:blank then call Page.addScriptToEvaluateOnLoad and then navigate to your target page).  If it doesn't work and you have a repro you can share, please file a bug at http://crbug.com. If you can post the bug number here, I'll help get it assigned to the right people.

but that doesn't seem to do anything for me (it runs, returns a script id, but does not seem to have any effect on the browser). The only things I've been able to do have been running one liners using Runtime.evaluate, but for cases where I'd want to inject either jquery or lodash, I don't see how to make this possible without referencing an external site using script tags as part of the data:text/html I create. I wasn't sure if maybe I needed to use Runtime.compileScript/runScript, but I don't quite understand what the sourceUrl would be if I'm defining the expression. I'm using the chrome-remote-interface library to do all this in NodeJS in an effort to replace a service using PhantomJS.

I'm very new to these DevTools Protocols, so if anyone also happens to know of any other documentation that may shed more light as to what each Domain's methods are actually doing, that would be greatly appreciated.

Thanks,
Michael

--
You received this message because you are subscribed to the Google Groups "headless-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to headless-dev+unsubscribe@chromium.org.
To post to this group, send email to headle...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/headless-dev/f5e3768a-dc62-4dcf-b18e-867a529cd367%40chromium.org.

Sami Kyostila

unread,
May 8, 2017, 2:59:54 PM5/8/17
to Michael, headless-dev, Pavel Feldman
Page.addScriptToEvaluateOnLoad should be followed by a navigation to actually trigger the script to be executed when the new page loads. Runtime.evaluate should also work with larger scripts, but (depending on what you're doing) it's probably more practical to set up a local web server that serves a page with <script> as well as the scripts themselves.

(+Pavel for links to DevTools protocol documentation?)

- Sami

--
You received this message because you are subscribed to the Google Groups "headless-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to headless-dev...@chromium.org.

Michael

unread,
May 9, 2017, 3:31:55 PM5/9/17
to headless-dev, marczak...@gmail.com, pfel...@chromium.org
Thanks Alex and Sami! Because of your confirmation of the use of Page.addScriptToEvaluateOnLoad I managed to find out what I was doing wrong. I had to read the js files I wanted to add using fs.readFile in NodeJS to read them as utf-8 strings, since using require did not work. Also, for using Runtime.evaluate it took me a couple minutes to realize that I needed to add all variables with escaped single quotes as part of the expression, eg: 

let expression = '(' + funcName + ')(' + variable1 + '\',\'' + variable2 + '\')'; instead of let expression = '(' + funcName + ')(' + variable1 + ',' + variable2 + ')';

Originally, I was trying to do something along the lines of: funcName.bind(null, variable1, variable2).toString() but that was throwing an unexpected '(' error when evaluated. 
Reply all
Reply to author
Forward
0 new messages