How does nbconvert executes Javacript ? Can I see the JS console output?

hi all,

I have a notebook that uses Javascript to build some dynamic HTML in the output, and it works fine in JupyterLab – even the export to HTML is working perfectly, when used from the browser.

Now when executing the same notebook from nbconvert the Javascript seems to fail – I’m not sure why yet.

What does nbconvert uses as a front-end ? I saw some references to chromium, but when I run it, I don’t see any chromium processes running. Is there a way to force it to use it ? And would it be possible to capture/display the console output ?

I do have installed playwright – some posts in the internet seem to indicate that nbconvert uses that, but I’m not sure.

I tried --allow-chromium-download, but it didn’t make a difference – also it never complained it couldn’t find chromium …

Any pointers would be most welcome!
cheers

This would depend on the output format. Chromium/playwright is only used for webpdf output.

Thx @krassowski , Yes, I saw that in the doc, so I tried webpdf. But I also tried asciidoc and html … all the same issue.

Now, nbconvert converts a saved notebook correctly. If I execute the notebook in the browser, save it, and then use nbcovert without the --execute.

So I suppose an alternative is to write a small program to do that using chrome --headless and remote control it with DevTools Protocol – there are some nice libraries to do that, I hope I can get jupyter notebook to execute all cells and save.

Any thoughts ?

nbexec, fresh from the oven, will execute a notebook on a headless chromium browser, and save it with the output contents.

It can then be converted to PDF/text/etc with nbconvert.

It offer more debugging options – e.g.: it also optionally captures Javascript console messages, which is great to debug javascript executed for a cell output.

It’s documented, and the code (in Go) is small and simple to read, if anyone is curious.

This could be also implemented using galata (a jupyterlab wrapper around playwright) but that requires a node runtime.

Oh, I missed that one, I could have used it! Thanks for the link.
(edit:
bollwyvl
had pointed it out to me in another thread, I should have seen it)

Fortunately, github.com/go-rod/rod made it easy – and I’m more familiar with Go than node.

The harder part was figuring out how to use jupyterapp Javascript object. Eventually, I found out one can use jupyterapp.commandLinker._commands.execute to execute commands – the rest was simple. Btw, is there an easier way to drive jupyterapp programmatically ?

Would not jupyterapp.commands.execute work too? This is what we use in galata when we want to drive the test using commands, e.g.:

It is using JupyterFrontEnd which inherits from lumino’s Application.

There’s also this weird little thing:

But if in a headless testing/debug situation where expose-app-in-browser is enabled, and you have control of the JS interpreter, there’s no particular use to it.

Thanks for the pointer, I suspected there should exist an easier way. I just randomly browsed code around and tried, and found out that jupyterapp.commandLinker._commands.execute() did the job :slight_smile:

I’m changing it to use the public jupyterapp.commands.execute instead.