jsdom: Can't load external css

Basic info:

  • Node.js version: v8.1.3
  • jsdom version: v11.1.0

Minimal reproduction case

let jsdom = require('jsdom');
const JSDOM = jsdom.JSDOM;

const domString = `
    <!DOCTYPE html>
    <html>
        <head>
            <title>Test</title>
            <link rel="stylesheet" href="./test.css">
        </head>
        <body>
            <p class="test">test content</p>
        </body>
    </html>
`;
const dom = new JSDOM(domString, {
    resources: 'usable'
});
const window = dom.window;
const document = window.document;
let color = window.getComputedStyle(document.querySelector('p'), null).getPropertyValue('color');

console.log(document.querySelector('p').textContent);  // test content
console.log('p\'s color', color);  // empty

When run node test/index.js in terminal, the second output is empty. My directory hierarchy as follows:

-test
  -- index.js
  -- test.css

I just write a simple rule in test.css:

.test{
    color: red
}

I’ve trawled the documentation and tried lots of variations but nothing works.

About this issue

  • Original URL
  • State: open
  • Created 7 years ago
  • Reactions: 1
  • Comments: 19 (7 by maintainers)

Most upvoted comments

@jokyspy hi, try this sample:

// index.js
const jsdom = require('jsdom');
const { JSDOM } = jsdom;
const path = require('path');

const absolutePath = path.join(__dirname, 'style.css');
const { window } = new JSDOM(
    `
    <html>
    <head>
        <link rel="stylesheet" href="file://${absolutePath}">.    
    </head>
    <body></body>
    </html>
    `, {
        resources: 'usable'
    }
);

window.onload = function () {
    console.log('Body background color: ' + window.getComputedStyle(window.document.body).backgroundColor);
};

setTimeout(() => {}, 1000);
/* style.css */
body {
    background: red;
}
node index.js
Body background color: red

The files should be in the same folder.

It decides to not load the stylesheet here as whatwg-url returns a failure for the relative path.

Replacing the relative path ./test.css with an absolute file:// URL will work, as well as providing an absolute file:// URL in the JSDOM constructor’s url option. Since there’s a note about this in the README, I believe this is expected behaviour.

Like in browsers, CSS takes some time to load. You need to wait for the load event on window.

Hey guys, It’s finally working for me! 😁

Check this PR: https://github.com/podcodar/exercises/pull/1

Ah OK. No, that’s not an event, that’s a function you define as in the example (“Inside the HTML you supply to jsdom”).

You need to use the usual window.addEventListener("load", ...) pattern to wait for the stylesheets to load.

I’ve never heard of the onModulesLoaded event, so no, not that. The normal load event on window.

As for pseudo-elements, that sounds like a separate issue, not related to this one, so I won’t talk about it in this thread.