Skip to content

Instantly share code, notes, and snippets.

@chrisdone
Last active December 30, 2020 20:55
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisdone/7ccd28c3c1389e8e6eef3c694a05d377 to your computer and use it in GitHub Desktop.
Save chrisdone/7ccd28c3c1389e8e6eef3c694a05d377 to your computer and use it in GitHub Desktop.
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

Output

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>
      <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>
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()
}
options.cookieJar.setCookie(
'SESSION_UUID=04930d28-2c5e-45c9-b510-7b52bf8844f7',
'http://localhost:3031/',
function(){}
);
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]) {
console.log(canvas[0].innerHTML);
}
});
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