Skip to content

Instantly share code, notes, and snippets.

@chad3814
Last active November 23, 2021 03:31
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chad3814/5059671 to your computer and use it in GitHub Desktop.
Save chad3814/5059671 to your computer and use it in GitHub Desktop.
waiting for content to be loaded in jsdom
'use strict';
var path = require('path');
var jsdom = require('jsdom');
var dumpBody = function (document) {
console.log('contents of the document:');
console.log(document.body.innerHTML);
};
jsdom.env({
html: path.resolve(__dirname, 'frameExample01.html'),
features: {
FetchExternalResources : ['script', 'frame'],
ProcessExternalResources : ['script', 'frame']
},
done: function (errors, window) {
var doc = window.document;
var leftFrame = doc.getElementsByName('leftFrame')[0];
console.log('readystate:', leftFrame.contentDocument.readyState);
if (leftFrame.contentDocument.readyState === 'complete') {
dumpBody(leftFrame.contentDocument);
} else {
console.log('waiting for the document to be ready');
leftFrame.contentDocument.addEventListener('DOMContentLoaded', dumpBody.bind(null, leftFrame.contentDocument));
}
}
});
<html><body><h1>hi from the right</h1></body></html>
<HTML><title>Frame Example 01</title>
<FRAMESET COLS="80%,20%">
<FRAME NAME="leftFrame" SRC="leftFrame.html">
<FRAME NAME="rightFrame" SRC="frame00.html">
</FRAMESET>
</HTML>
<html>
<body>
<h1>hi from the left</h1>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
</body>
</html>
$ node foo.js
readystate: loading
waiting for the document to be ready
contents of the document:
<h1>hi from the left</h1>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
$
@josep2
Copy link

josep2 commented Jan 7, 2016

Very helpful, thank you.

@zhanwenchen
Copy link

Would you please redo the example using the new API? jsdom.env is deprecated as of jsdom v10.

@liamgbs
Copy link

liamgbs commented Feb 8, 2019

For anyone coming across this with the same problem, you can set window.onload to log out a "loaded" message (or similar) and use jsdom's virtual console to intercept it:

const jsdom = require("jsdom");
const { JSDOM } = jsdom;

const boilerplate =
	`
<!DOCTYPE html>
<html>
   <head>
	  <meta charset="utf-8">
	  <script>

		window.onload = function() {
			console.log("loaded")
		};

	  </script>
   </head>
   <body>
      <div id="hello">Hello, world!</div>
   </body>
</html>
`

const virtualConsole = new jsdom.VirtualConsole();

const doc = new JSDOM(boilerplate,
	{
		virtualConsole,
		runScripts: "dangerously"
	});

function loadDom() {
	return new Promise((resolve, _) => {
		virtualConsole.on("log", log => {if (log === "loaded") resolve(doc)})
	})
}

loadDom()
	.then(doc => console.log(doc.window.document.getElementById("hello").innerHTML))

It feels a bit hacky but it worked for me.

@tokland
Copy link

tokland commented Feb 14, 2021

@liamgbs This works for me:

function loadDom() {
    return new Promise((resolve) => {
        dom.window.addEventListener("load", () => {
            resolve(dom.window);
        });
    });
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment