# All files / src/user-event/setup setup.ts

100% Statements 12/12
100% Branches 2/2
100% Functions 4/4
100% Lines 12/12

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92

    75x
    14x

    61x

    3x

    18x
    18x
    18x

    18x

    18x

    18x

    18x
    18x

     import { ReactTestInstance } from 'react-test-renderer';
    import { jestFakeTimersAreEnabled } from '../../helpers/timers';
    import { press } from '../press';
    import { TypeOptions, type } from '../type';

    export interface UserEventSetupOptions {
      /**
       * Between some subsequent inputs like typing a series of characters
       * the code execution is delayed per `setTimeout` for (at least) `delay` seconds.
       * This moves the next changes at least to next macro task
       * and allows other (asynchronous) code to run between events.
       *
       * `null` prevents `setTimeout` from being called.
       *
       * @default 0
       */
      delay?: number;

      /**
       * Function to be called to advance fake timers. Setting it is necessary for
       * fake timers to work.
       *
       * @example jest.advanceTimersByTime
       */
      advanceTimers?: (delay: number) => Promise<void> | void;
    }

    /**
     * This functions allow wait to work correctly under both real and fake Jest timers.
     */
    function universalJestAdvanceTimersBy(ms: number) {
      if (jestFakeTimersAreEnabled()) {
        return jest.advanceTimersByTime(ms);
      } else {
        return Promise.resolve();
      }
    }

    const defaultOptions: Required<UserEventSetupOptions> = {
      delay: 0,
      advanceTimers: universalJestAdvanceTimersBy,
    };

    /**
     * Creates a new instance of user event instance with the given options.
     *
     * @param options
     * @returns
     */
    export function setup(options?: UserEventSetupOptions) {
      const config = createConfig(options);
      const instance = createInstance(config);
      return instance;
    }

    export interface UserEventConfig {
      delay: number;
      advanceTimers: (delay: number) => Promise<void> | void;
    }

    function createConfig(options?: UserEventSetupOptions): UserEventConfig {
      return {
        ...defaultOptions,
        ...options,
      };
    }

    export interface UserEventInstance {
      config: UserEventConfig;
      press: (element: ReactTestInstance) => Promise<void>;
      type: (
        element: ReactTestInstance,
        text: string,
        options?: TypeOptions
      ) => Promise<void>;
    }

    function createInstance(config: UserEventConfig): UserEventInstance {
      const instance = {
        config,
      } as UserEventInstance;

      // We need to bind these functions, as they access the config through 'this.config'.
      const api = {
        press: press.bind(instance),
        type: type.bind(instance),
      };

      Object.assign(instance, api);
      return instance;
    }