2

I am running a phantom js process to render a webpage. The webpage has many javascripts loaded asynchronously, each running their own functions.

Is there a way to inspect/debug the javascript engine in webkit to know if it is currently executing any javascript line (as opposed to being idle)?

If so, is there a way to tell from which javascript resource it is executing?

Something like pausing the javascript engine, logging the stack trace, then resuming it as normal would do perfectly.

I don't mind reading through the source code of webkit, phantomjs, or render.js, modifying it myself, and re-compiling it from source. I'd like to ask you guys first though in case a feature already exists or if someone's already done it since Google didn't give me any results. Thanks!

user3667125
  • 725
  • 1
  • 7
  • 17
  • you can use performance.getEntries() to get a list of the scripts and their timings, to reconcile against document.scripts. if they are completely mutual, all the scripts are loaded. if all scripts are loaded, and your code is running, you can assume all scripts have "started up". wait another 3500ms to be sure, and if no new entries have appeared, it's probably done loading... you can overload the ajax object to log content fetches to be double sure. – dandavis Apr 09 '15 at 01:49
  • Thanks for the suggestion. From what I read, it seems like performance.getEntries() only log the network timings of the resources. E.g. if a website downloads a javascript, it only logs the request time and receive time. However, what I am interested in is the performance timings of the actual javascript execution, not the network timings. Is there a performance.getEntries() equivalent of that? – user3667125 Apr 09 '15 at 07:37
  • @dandavis There is no `performance.getEntries()` in PhantomJS. Just tried it. Only `performance.timing` is available. – Artjom B. Apr 09 '15 at 07:43
  • i'm saying that it can tell if the script is loaded, and if the script it loaded, and there's no ajax out, then it has run and is presumably finished. probablt not 100% but better than nothing or over-waiting. – dandavis Apr 09 '15 at 07:58

2 Answers2

0

Not really.

Phantom.js is an integration test tool. This mean you shouldn't try to explore internals, only assert the result. The questions you want to ask is: "Can I do X action", "Is this feature working from the end user standpoint".

If you want to know if a certain function is running or called in reaction a X action. Then you're looking at the internals of your program and what you want is a unit test, and you'll probably assert a function is running by stubbing or mocking it. If that's the case then look into sinon.js as a test stubbing helper.

(note that you might run your unit test inside phantom.js - that's okay because you need a runtime to run them)

Simon Boudrias
  • 42,953
  • 16
  • 99
  • 134
  • Sorry, my question was a bit unclear. I'm using phantom.js to capture web pages to disk so I can browse offline. Some pages have comment plug-ins (e.g. facebook, disqus, livefyre), which take very long to load (>5s), so I need to check if all the relevant scripts are downloaded as well as executed. What I'm looking for is a way for render.js to call new Error().stack every 100 millisecond to print the stack trace, but when I try to do that, it says 'stack' is undefined. Is there another way to find the current stack trace of the javascript engine in render.js? – user3667125 Apr 09 '15 at 00:50
0

Detecting whether JavaScript has compiled and run is probably not the right way to solve this. The slowest operations are network requests. You can detect if all requests are done by counting started requests with onResourceRequested and finished requests with onResourceReceived, and then only adding a little static wait time for compilation/running.

Community
  • 1
  • 1
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Yes, that is correct, to capture web pages to disk, phantomjs to should detect when network requests are done, and then adding a wait time afterwards. That is what I am currently doing. However, I made this post not to find a working solution to the problem, but as a learning opportunity. I am currently exploring new (and experimental) ways to detect when to serialize web pages -- for fun, for my own pet project. If it fails, at least I learned something about the javascript engine. With that said, your solution is valid, but I can't accept it because its not exactly what I'm looking for. – user3667125 Apr 09 '15 at 19:45