Skip to content

Instantly share code, notes, and snippets.

Last active Dec 30, 2020
What would you like to do?
Querying my Halogen DOM with jsdom

Querying my Halogen DOM with jsdom

I need a way to run my Halogen (PureScript) based web UI offline at compile-time, in order to generate "screenshots" (DOM captures) and run test suites.

Here's my initial attempt.

Build the docker image

Make a directory and put Dockerfile in it, then run this command in there:

docker image build . -t jsdom

Run jsdom

In the same directory as jsdom.js, run this:

docker run --net=host --rm -v`pwd`:`pwd` -w`pwd` jsdom node jsdom.js


Here's what my output looked like:

<div class="cell-wrapper" style=""><div class="cell"><div class="cell-header"><div class="cell-name" title="Click to edit cell's name">(unnamed)</div><button class="delete-cell" title="Delete this cell">×</button></div><div class="cell-body"><div class="editor-boundary-wrap clickable-to-edit" title="Click to edit"><div class="misc">123</div></div></div></div></div>

Read this as:

  1. Blank line because the canvas is empty, and we're querying the server for the initial canvas contents.
  2. Finally, the last line of HTML output is a snapshot of the current DOM, which includes the part I want:
  <div class="cell-wrapper" style="">
    <div class="cell">
      <div class="cell-header">
        <div class="cell-name" title="Click to edit cell's name">(unnamed)</div>
        <button class="delete-cell" title="Delete this cell">×</button>
      <div class="cell-body">
        <div class="editor-boundary-wrap clickable-to-edit"
             title="Click to edit">
          <div class="misc">123</div>
FROM alpine
RUN apk add --update nodejs npm && \
npm install --save-dev jsdom xhr2
const jsdom = require("jsdom");
const { JSDOM } = jsdom;
const resourceLoader = new jsdom.ResourceLoader({
strictSSL: false,
userAgent: "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"
const cookieJar = new jsdom.CookieJar({});
const options = {
resources: resourceLoader,
runScripts: 'dangerously',
pretendToBeVisual: true,
cookieJar: new jsdom.CookieJar()
JSDOM.fromURL("http://localhost:3031/editor/document-11", options).then(dom => {
dom.window.HTMLCanvasElement.prototype.getContext = function(){
// We don't support getting the context, so ignore this.
const observer = new dom.window.MutationObserver(function(list, _observer){
const canvas = dom.window.document.getElementsByClassName('canvas');
if (canvas[0]) {
observer.observe(dom.window.document.body, {
attributes: true, childList: true, subtree: true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment