Using plugins with Jest (aurelia-ui-virtualization)

I’ve added aurelia-ui-virtualization to a component and it broke all my unit tests.

Here is an example test:

it('testing search', async done => {
    component = StageComponent.withResources()
        .inView('<c-form-select search.bind="customsearch"></c-form-select>')
        .boundTo({
            customSearch: 1,
        });

    try {
        await bootStrapEnvironment(component);
        expect(component.viewModel.search).toBe(false);
        done();
    } catch (e) {
        done.fail(e);
    }
});

I’m getting the following error:

      at ViewCompiler.Object.<anonymous>.ViewCompiler._compileElement (node_modules/aurelia-templating/src/view-compiler.ts:466:26)
      at ViewCompiler.Object.<anonymous>.ViewCompiler._compileNode (node_modules/aurelia-templating/src/view-compiler.ts:145:19)
      at ViewCompiler.Object.<anonymous>.ViewCompiler._compileElement (node_modules/aurelia-templating/src/view-compiler.ts:488:29)
      at ViewCompiler.Object.<anonymous>.ViewCompiler._compileNode (node_modules/aurelia-templating/src/view-compiler.ts:145:19)
      at ViewCompiler.Object.<anonymous>.ViewCompiler._compileElement (node_modules/aurelia-templating/src/view-compiler.ts:488:29)
      at ViewCompiler.Object.<anonymous>.ViewCompiler._compileNode (node_modules/aurelia-templating/src/view-compiler.ts:145:19)
      at ViewCompiler.Object.<anonymous>.ViewCompiler._compileNode (node_modules/aurelia-templating/src/view-compiler.ts:169:29)
      at ViewCompiler.Object.<anonymous>.ViewCompiler.compile (node_modules/aurelia-templating/src/view-compiler.ts:113:10)
      at HtmlBehaviorResource.Object.<anonymous>.HtmlBehaviorResource.compile (node_modules/aurelia-templating/src/html-behavior.ts:339:44)
      at ViewCompiler.Object.<anonymous>.ViewCompiler._compileElement (node_modules/aurelia-templating/src/view-compiler.ts:448:38)

TypeError: Cannot read property ‘attrToRemove’ of undefined

I believe it is because it is not registering the plugin. I’ve tried to add it in the jest-pretest.tsfile and while bootstrapping, but I’m not having much luck.

Does anyone have an example of how they add plugins to a ComponentTester object?

This is an open source project so if you want more details on the code, see this branch: GitHub - bindable-ui/bindable at dd/virtual-select-multiple

If I update the jest-pretest.ts file to add the plugin like so:

global.bootStrapEnvironment = async component => {
    component.bootstrap(au =>
        au.use
            .standardConfiguration()
            .plugin('aurelia-ui-virtualization')
            .feature('src'),
    );
    await component.create(bootstrap);
};

Then I get:
Error: Cannot find module ‘/Users/dustin/dev/bindable/aurelia-ui-virtualization’ from ‘aurelia-loader-nodejs.js’

If I point the plugin to node_modules/aurelia-ui-virtualization then I get this error:
TypeError: Cannot read property ‘bind’ of undefined

I’ve added this question to StackOverflow as well with a bit more details and code examples: node.js - Aurelia Jest with aurelia-ui-virtualization plugin unit testing errors - Stack Overflow

1 Like

I found a solution. I learned jsdom does not implement requestAnimationFrame. I added polyfill and made it gobal in my jest-pretest.ts file:

// Add requestAnimationFrame pollyfill to fix aurelia-ui-virtualiztion issues
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
// MIT license
(function(window, rAF, cAF) {
    var lastTime = 0,
        vendors = ['ms', 'moz', 'webkit', 'o'],
        x;

    for (x = 0; x < vendors.length && !window[rAF]; ++x) {
        window[rAF] = window[vendors[x] + 'RequestAnimationFrame'];
        window[cAF] = window[vendors[x] + 'CancelAnimationFrame'] || window[vendors[x] + 'CancelRequestAnimationFrame'];
    }

    if (!window[rAF]) {
        window[rAF] = function(callback) {
            var currTime = new Date().getTime(),
                timeToCall = Math.max(0, 16 - (currTime - lastTime)),
                id = window.setTimeout(function() {
                    callback(currTime + timeToCall);
                }, timeToCall);

            lastTime = currTime + timeToCall;

            return id;
        };
    }

    if (!window[cAF]) {
        window[cAF] = function(id) {
            window.clearTimeout(id);
        };
    }
})(global.window, 'requestAnimationFrame', 'cancelAnimationFrame');

global.requestAnimationFrame = global.window.requestAnimationFrame;
2 Likes