import * as React from 'react';
import {act, fireEvent, render} from '@testing-library/react';
import Transition from './Transition'; // https://github.com/jsdom/jsdom/issues/1781
// https://github.com/testing-library/dom-testing-library/pull/865
class TransitionEvent extends Event {
elapsedTime: number;
propertyName: string;
pseudoElement: string;
// @ts-ignore TS7006
constructor(type, init: {[key: string]: any} = {}) {
super(type, init);
this.elapsedTime = init.elapsedTime || 0.0;
this.propertyName = init.propertyName || '';
this.pseudoElement = init.pseudoElement || '';
}
}
const DEFAULT_OPACITY = ''; // unassigned
const INITIAL_OPACITY = 0.1;
const ANIMATE_OPACITY = 0.2;
const EXIT_OPACITY = 0.3;
const testEffect = {
initial: {
opacity: INITIAL_OPACITY,
},
animate: {
opacity: ANIMATE_OPACITY,
duration: 'quick2',
},
exit: {
opacity: EXIT_OPACITY,
duration: 'quick2',
},
} as const;
const instantEffect = {
initial: {
opacity: INITIAL_OPACITY,
},
animate: {
opacity: ANIMATE_OPACITY,
duration: 'instant',
},
exit: {
opacity: EXIT_OPACITY,
duration: 'instant',
},
} as const;
describe('', () => {
beforeEach(() => {
jest.clearAllMocks();
jest.useFakeTimers();
global.TransitionEvent = TransitionEvent;
});
it('renders children', () => {
const wrapper = render(
test content
);
expect(wrapper.queryByText('test content')).toBeTruthy();
});
it('does not apply any style when not support transition', () => {
// @ts-ignore TS2322
global.TransitionEvent = undefined;
const wrapper = render();
expect(
(wrapper.container.firstElementChild as HTMLElement).style.opacity
).toBe(DEFAULT_OPACITY);
});
it('fires onTransitionStart as a fallback when not support transition', () => {
// @ts-ignore TS2322
global.TransitionEvent = undefined;
const onTransitionStart = jest.fn();
render(
);
expect(onTransitionStart).toHaveBeenCalledTimes(1);
});
it('fires onTransitionEnd as a fallback when not support transition', () => {
// @ts-ignore TS2322
global.TransitionEvent = undefined;
const onTransitionEnd = jest.fn();
render(
);
expect(onTransitionEnd).toHaveBeenCalledTimes(1);
});
it.each`
delay | fillMode | before | after
${0} | ${'none'} | ${ANIMATE_OPACITY} | ${DEFAULT_OPACITY}
${0} | ${'forwards'} | ${ANIMATE_OPACITY} | ${ANIMATE_OPACITY}
${0} | ${'backwards'} | ${ANIMATE_OPACITY} | ${DEFAULT_OPACITY}
${0} | ${'both'} | ${ANIMATE_OPACITY} | ${ANIMATE_OPACITY}
${100} | ${'none'} | ${null} | ${DEFAULT_OPACITY}
${100} | ${'forwards'} | ${null} | ${ANIMATE_OPACITY}
${100} | ${'backwards'} | ${INITIAL_OPACITY} | ${DEFAULT_OPACITY}
${100} | ${'both'} | ${INITIAL_OPACITY} | ${ANIMATE_OPACITY}
`(
'fills $delay ms delayed transition with "$fillMode" mode',
({delay, fillMode, before, after}) => {
const wrapper = render(
);
if (before !== null) {
expect(
(wrapper.container.firstElementChild as HTMLElement).style.opacity
).toBe(`${before}`);
}
act(() => {
jest.runAllTimers();
wrapper.rerender(
);
});
// @ts-ignore TS2345
fireEvent.transitionEnd(wrapper.container.firstElementChild);
expect(
(wrapper.container.firstElementChild as HTMLElement).style.opacity
).toBe(`${after}`);
}
);
it('accepts effect prop as a function that returns an effect', () => {
const effectFunction = jest.fn(() => testEffect);
const wrapper = render();
expect(
(wrapper.container.firstElementChild as HTMLElement).style.opacity
).toBe(`${ANIMATE_OPACITY}`);
expect(effectFunction).toHaveBeenCalledWith(false);
});
it('fires onTransitionEnd after instant transition', () => {
const onTransitionEnd = jest.fn();
render(
);
expect(onTransitionEnd).toHaveBeenCalledTimes(1);
});
});