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.

1 Like

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

1 Like

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 ?

1 Like

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.

2 Likes

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.

2 Likes

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.

1 Like