chenglou / react-motion

A spring that solves your animation problems.
MIT License
21.68k stars 1.15k forks source link

how to test animations #566

Open loicpw opened 5 years ago

loicpw commented 5 years ago

Hi, I'm using StaggeredMotion and spring to create a basic animation, and I'm trying to implement automated tests to check the animation is running as expected when triggered, however I can't figure out how to correctly implement this.

The idea is doing something like this:

describe('test animation', () => {
    let clock;

    beforeEach(() => {
        clock = sinon.useFakeTimers();
    })

    afterEach(() => {
        clock.restore();
    });

    it('animation should progress', () => {
        [...]
        clock.tick(200);
        // check the state of some nodes here
        [...]
    });
});

But this doesn't seem to work as expected (I'm using a create-react-app environment), so I think I'm missing something important. Sorry if the question is dummy but I couldn't find examples about achieving this. I would appreciate if anyone could help ?

loicpw commented 5 years ago

Eventually using mocks like you're doing in react-motion tests, if anyone is interested here's how I proceed to get consistent tests:

I ended up using the following libs:

[...]
const sinon = require('sinon'); 
const createMockRaf = require('mock-raf'); 
import rewiremock from 'rewiremock';

[...]

describe('test animation', () => {
    let StaggeredMotion; 
    let mockRaf;

    beforeEach(() => {
        mockRaf = createMockRaf();
        mockRaf.raf.cancel = mockRaf.cancel;
        sinon.stub(window, 'requestAnimationFrame').callsFake(mockRaf.raf);
        StaggeredMotion = rewiremock.proxy('react-motion/lib/StaggeredMotion', {
            raf: mockRaf.raf,
            'performance-now': mockRaf.now,
        });
    });

    afterEach(() => {
        global.requestAnimationFrame.restore();
    });

    it('animation should progress ...', () => {
        [...]
        mockRaf.step({ count: 10 });
        [...]
    });
});