조롱 프레이머 모션 v4

Testing Library UI 테스트 게임을 개선했습니다. 아직 시도하지 않았다면 확인하십시오.

work에서 우리의 새로운 UI 노력은 Chakra UI 에 의해 구동되며, 애니메이션을 위해 후드 아래에서 Framer Motion을 사용합니다. 이 모든 작업과 함께 JestReact Testing Library (RTL)을 사용하여 모든 것을 테스트하고 있습니다.

UI 회귀(복사, 스타일 등)를 방어하는 한 가지 좋은 방법은 snapshot testing 입니다. Chakra의 기능과 더 나은 테스트가 점점 더 많아지면서 애니메이션style 속성에 스냅샷 간에 미세한 차이가 있는 문제가 발생했습니다.

RTLrecommends은 이 문제를 해결하기 위해 애니메이션 라이브러리를 모의합니다. 웹에서 framer-motion를 사용하여 이 작업을 수행하는 몇 가지 솔루션이 있지만 현재 버전의 라이브러리( 4._ )에 적합하지 않다고 생각합니다.

framer motion source 을 파헤친 후 motion 내보내기를 객체로 조롱하려는 시도( here 참조)가 motionProxy 을 사용하여 구성되었기 때문에 작동하지 않는다는 것을 깨달았습니다.

말로 충분합니다. 스냅샷 테스트를 안정화하려면 어떻게 해야 합니까?!




// __mocks__/framer-motion.ts

import { CustomDomComponent, CustomMotionComponentConfig } from 'framer-motion/types/render/dom/motion-proxy';
import * as React from 'react';

const actual = jest.requireActual('framer-motion');

// https://github.com/framer/motion/blob/main/src/render/dom/motion.ts
function custom<Props>(
  Component: string | React.ComponentType<Props>,
  _customMotionComponentConfig: CustomMotionComponentConfig = {},
): CustomDomComponent<Props> {
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
  // @ts-ignore
  return React.forwardRef((props, ref) => {
    const regularProps = Object.fromEntries(
      // do not pass framer props to DOM element
      Object.entries(props).filter(([key]) => !actual.isValidMotionProp(key)),
    );
    return typeof Component === 'string' ? (
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      <div ref={ref} {...regularProps} />
    ) : (
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      <Component ref={ref} {...regularProps} />
    );
  });
}

const componentCache = new Map<string, unknown>();
const motion = new Proxy(custom, {
  get: (_target, key: string) => {
    if (!componentCache.has(key)) {
      componentCache.set(key, custom(key));
    }

    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    return componentCache.get(key)!;
  },
});

module.exports = {
  __esModule: true,
  ...actual,
  AnimatePresence: ({ children }: { children: React.ReactChildren }) => <>{children}</>,
  motion,
};


이제 테스트 설정 파일에서 jest.mock('framer-motion')를 호출할 수 있으며 모든 애니메이션 관련 속성이 필터링됩니다.

즐거운 테스트!

좋은 웹페이지 즐겨찾기