laurent
laurent

Reputation: 90863

Image onLoad handler never called in Jest

I'm trying to test loading a dataUrl into an image using Jest. I'm using JSDOM and followed the instruction to add resources: "usable" as an option.

The code works if I run it directly from Node, but when I try to run it within Jest, the image onLoad handler is never called, and so the test never completes.

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

const dom = new JSDOM(`<!DOCTYPE html><p>Hello world</p>`, {
    resources: "usable",
});

global.window = dom.window;
global.document = dom.window.document;
global.navigator = global.window.navigator;

const dataUrlToImage = async (dataUrl) => {
    return new Promise(((resolve, reject) => {
        const img = document.createElement('img');
        img.crossOrigin = 'Anonymous';

        img.onload = function() { // Never called
            console.info('On load called'); 
            resolve(img);
        };

        img.src = dataUrl;
    }));
}

it('tests image loading', async () => {
    const r = await dataUrlToImage('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==');
    expect(!!r).toBe(true); // This is never called
});

Any idea what could be the issue?

Upvotes: 2

Views: 2593

Answers (1)

Sebmaster
Sebmaster

Reputation: 569

Jest relies on an old version of jsdom which only works with canvas@1. The version of jsdom you get now from npm only works with canvas@2.

So I assume you're missing either npm install canvas@1 or npm install canvas-prebuilt@1.

As a side note: jest comes with jsdom built in, instead of requiring your own version, you should instead add testEnvironmentOptions: { resources: "usable" } to your jest.config.js, then you can remove all the jsdom boilerplate.

Upvotes: 4

Related Questions