testing-library/user-event

repository·main·Indexed 25 days ago

https://github.com/testing-library/user-event

A library for simulating real user interactions in a web browser environment. Unlike low-level event dispatching, user-event provides a higher-level abstraction that simulates the full sequence of events a real user would trigger, such as clicks and keyboard input, to increase test confidence.

Tokens
2.8K
Snippets
1
Records
24
Agent score
79%

What's inside @testing-library/user-event

  1. What is user-event and why use it?

    main

    Concept: Simulating real user interactions

    user-event is a library designed to simulate real browser events that occur when a user interacts with a web page.

    Unlike lower-level utilities like fireEvent (from dom-testing-library), which simply dispatch a single event, user-event provides a higher-level abstraction that simulates the full sequence of events a real user would trigger. For example, calling userEvent.click(checkbox) does more than just dispatch a click event; it handles the state changes and side effects that a real browser would perform when a checkbox is clicked.

    Key Principle:

    The more your tests resemble the way your software is used, the more confidence they can give you.

  2. How user-event sessions and sub-sessions work together

    main

    The user-event library operates on a hierarchical model of sessions:

    1. Main Session (setupMain): Creates a full environment. It initializes a System (representing the keyboard and pointer state) and a Config. This is the primary entry point for most testing scenarios.
    2. Direct API (setupDirect): Provides a way to get the API and the System instance separately, useful for advanced control or when you don't want the side effects of setupMain (like clipboard stubbing).
    3. Sub-sessions (setupSub): Accessible via the .setup() method on an existing instance. Sub-sessions are designed to allow configuration overrides. Crucially, they share the same system as the parent instance. This ensures that if a user types in a main session and then you create a sub-session, the simulated keyboard state remains consistent.

    Mental Model Summary:

    • State (System): Tracks what keys are pressed and where the pointer is.
    • Configuration (Config): Defines how events are dispatched (delays, clipboard behavior, etc.).
    • API (UserEvent): The collection of methods (click, type, etc.) that use the State and Config to interact with the DOM.
  3. Configure `PointerPressAction` and `PointerMoveAction`

    main

    When passing objects to the pointer method, you can specify detailed interaction parameters.

    PointerPressAction

    Used to simulate pressing a pointer key (like a mouse button).

    • keyDef: The pointerKey to press.
    • target?: The Element to interact with.
    • coords?: The PointerCoords (x, y) for the interaction.
    • node?: The specific Node for caret positioning.
    • offset?: The offset within the target or node.
    • releasePrevious: If true, releases the previous pointer key before pressing this one.
    • releaseSelf: If true, releases the key immediately after pressing it.

    PointerMoveAction

    Used to simulate moving a pointer.

    • target?: The Element to move to.
    • coords?: The PointerCoords (x, y) for the movement.
    • node?: The specific Node for caret positioning.
    • offset?: The offset within the target or node.
    • pointerName?: The name of the pointer to move (e.g., 'mouse').
  4. Configure upload file acceptance with applyAccept

    main

    When using userEvent.upload, the applyAccept option determines if files that do not match the accept attribute of the input element should be automatically discarded.

    • Default: true
    • Usage: Set to false if you want to allow files that do not match the accept criteria to be uploaded during tests.
  5. Configure clipboard behavior with writeToClipboard

    main

    The writeToClipboard option controls whether cut or copy actions write data to the Clipboard API. Since the Clipboard API is often unavailable in test environments, user-event can stub navigator.clipboard.

    • Default (when calling APIs directly): false
    • Default (when using setup()): true
  6. Simulate keyboard input with keyboard()

    main
    The keyboard method allows you to simulate typing a string of text. It parses the provided string into individual key actions based on the keyboardMap configuration. For each key in the sequence, it handles keydown and keyup events, including support for repeated keys and automatic release of previously pressed keys to ensure a realistic simulation of user typing.
  7. Use the `pointer` method for pointer interactions

    main

    The pointer method is an asynchronous function available on a user-event instance used to simulate complex pointer interactions (like mouse or touch movements and presses). It accepts a single PointerInput or an array of PointerInput items, which are processed sequentially.

    PointerInput can be:

    • A string representing a key definition (e.g., a mouse button).
    • An object containing keys and optional position data (target, coords, node, offset).
    • A PointerAction object (either a PointerPressAction or a PointerMoveAction).

    When providing position data:

    • If node is set, offset is treated as the DOM offset.
    • If node is not set, offset is treated as the textContent/value offset on the target.
  8. Initialize a userEvent instance with setup()

    main
    To create a dedicated Instance of userEvent with its own state and configuration, use the setup method. This is the recommended way to use the library as it allows you to configure options that will apply to all subsequent interactions performed by that instance.
  9. Initialize user-event with direct calls using setupDirect

    main

    Use setupDirect when you want to call user-event APIs directly without maintaining a persistent session state, or when you need manual control over the system (input device state). Unlike setupMain, setupDirect uses defaultOptionsDirect, which sets writeToClipboard: false and autoModify: true.

    import userEvent from '@testing-library/user-event';
    
    const { api, system } = userEvent.setupDirect({
      delay: 10,
    });
    
    // Use the returned api
    await api.click(element);
  10. Release all currently pressed keys with releaseAllKeys()

    main
    The releaseAllKeys function ensures that no keys remain in a 'down' state by iterating through all keys currently reported as pressed by the system and triggering a keyup event for each one. This is useful for cleaning up the state after tests involving complex keyboard interactions.