Skip to content

Conversation

@jgonet
Copy link
Member

@jgonet jgonet commented Jan 25, 2022

Description

Supersedes #1762.

Needs to be synchronized with software-mansion/react-native-reanimated#2885.

This PR introduces a new test API fireGestureHandler(handler, eventList), allowing to test handlers bound to a given gesture (or gesture handler).

handler can be one of two things:

  1. a gesture component queried by getByTestId (testID must be used directly on handler, e.g. <RotationGestureHandler testID="rotation">),
  2. a gesture opaque structure queried by getByHandlerTestId (testID can be set via withTestId(name), e.g. Gesture.Pan().withTestId('pan')).

eventList contains events that should be emitted to provided handler. State change events must have state field. Subsequent ACTIVE events can have state field omitted. Every entry can have additional attributes for a given handler type (e.g. translationX for Pan).

fireGestureHandler is typed and can be parametrized with all Gestures and Gesture Handlers (e.g. fireGestureHandler<PanGesture>, fireGestureHandler<LongPressGestureHandler>).

Example test

import React from 'react';
import { render } from '@testing-library/react-native';
import { Text } from 'react-native';
import {
  GestureHandlerRootView,
  Gesture,
  GestureDetector,
  State,
} from '../index';
import { fireGestureHandler, getByGestureTestId } from 'gesture-handler';
import { cleanup } from '@testing-library/react-native';

beforeEach(cleanup);

const mockedEventHandlers = () => {
  return {
    begin: jest.fn(),
    start: jest.fn(),
    active: jest.fn(),
    end: jest.fn(),
    finish: jest.fn(),
  };
};

function SingleHandler({ handlers, treatStartAsUpdate }) {
  const pan = Gesture.Pan()
    .onBegin(handlers.begin)
    .onStart(treatStartAsUpdate ? handlers.active : handlers.start)
    .onUpdate(handlers.active)
    .onEnd(handlers.end)
    .onFinalize(handlers.finish)
    .withTestId('pan');

  return (
    <GestureHandlerRootView>
      <GestureDetector gesture={pan}>
        <Text>v2 API test</Text>
      </GestureDetector>
    </GestureHandlerRootView>
  );
}

it('sends events with additional data to handlers', () => {
  const panHandlers = mockedEventHandlers();
  render(<SingleHandler handlers={panHandlers} treatStartAsUpdate />);
  fireGestureHandler<PanGesture>(getByGestureTestId('pan'), [
    { state: State.BEGAN, translationX: 0 },
    { state: State.ACTIVE, translationX: 10 },
    { translationX: 20 },
    { translationX: 20 },
    { state: State.END, translationX: 30 },
  ]);

  expect(panHandlers.active).toBeCalledTimes(3);
  expect(panHandlers.active).toHaveBeenLastCalledWith(
    expect.objectContaining({ translationX: 20 })
  );
});

TODO

  • Allow parametrizing the fireGestureHandler with handler, e.g. fireGestureHandler<PanGesture>(...) or fireGestureHandler<PanGestureHandler>(...).
  • Add tests for FAIL and CANCEL events.
  • Implicitly add missing states if not specified.
  • Add documentation

Test plan

Ran yarn test -i Events.

@jgonet
Copy link
Member Author

jgonet commented Jan 27, 2022

Good point, fixed in 45f7d9e.

@jgonet jgonet merged commit 273fa03 into main Feb 3, 2022
@jgonet jgonet deleted the @jgonet/jest-events branch February 3, 2022 12:29
@Andarius
Copy link
Contributor

Andarius commented Feb 28, 2022

Hey @jakub-gonet @j-piasecki , do you know when a release including isJest and fireGestureHandler will be uploaded?
Writing jest tests triggers a lot of warning and is limited for now (no way to test this for instance)

<GestureDetector gesture={tap}>
   <View testID="background" style={[styles.background]} />
</GestureDetector>

Or do you have a nightly build of master to use ?

@j-piasecki
Copy link
Member

Hi @Andarius! We have just released a new version that, among others, contains the testing API.

@virdesai
Copy link
Contributor

virdesai commented Mar 2, 2022

@jakub-gonet @j-piasecki is it expected that without Fabric enabled, the RNGestureHandlerButton with handlerType="NativeViewGestureHandler" no longer is getting assigned a testID when checking the snapshot in a jest test? when I comment out this line or change it to testID: this.props.testID ?? child.props.testID, or ...(this.props.testID ? { testID: this.props.testID } : {}), it exists as I'd expect. from reading the docs, using withTestId doesn't seem to be made for this situation

Suggested PR here: #1910

I could be wrong and this may be something that needs to be handled higher up instead of only assigning testID to the cloned element if one was provided to the handler

j-piasecki pushed a commit that referenced this pull request Mar 3, 2022
…signed (#1910)

Fix related to comment [here](#1844 (comment)) about `RNGestureHandlerButton` with `handlerType="NativeViewGestureHandler"` having missing testIDs when they were previously provided and assigned. The `testID` on the child being cloned within `createHandler` was being removed by the `testID` being set within the render function even the `testID` on the handler was not set. Now it will only assign a `testID` as a prop on the cloned element if a `testID` was provided to the handler.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants