Skip to main content

Pointer

pointer(input: PointerInput): Promise<void>

The pointer API allows to simulate interactions with pointer devices. It accepts a single pointer action or an array of them.

type PointerInput = PointerActionInput | Array<PointerActionInput>

Our primary target audience tests per jest in a jsdom environment and there is no layout in jsdom. This means that different from your browser the elements don't exist in a specific position, layer and size.
We don't try to determine if the pointer action you describe is possible at that position in your layout.

Pointer action

There are two types of actions: press and move.

Pressing a button or touching the screen

A pointer action is a press action if it defines a key to be pressed, to be released, or both.

pointer({keys: '[MouseLeft]'})

You can declare multiple press actions (on the same position) at once which will be resolved to multiple actions internally. If you don't need to declare any other properties you can also just supply the keys string.

pointer({keys: '[MouseLeft][MouseRight]'})
// or
pointer('[MouseLeft][MouseRight]')

In order to press a button without releasing it, the button name is suffixed with >.
For just releasing a previously pressed button, the tag is started with /.

pointer('[MouseLeft>]') // press the left mouse button
pointer('[/MouseLeft]') // release the left mouse button

Which buttons are available depends on the pointerMap.

Moving a pointer

Every pointer action that is not a press action describes a pointer movement.

You can declare which pointer is moved per pointerName property. This defaults to mouse.

Note that the mouse pointer (pointerId: 1) is also the only pointer that always exists and has a position. A touch pointer only exists while the screen is touched and receives a new pointerId every time. For these pointers, we use the "button" name from the press action as pointerName.

pointer([
// touch the screen at element1
{keys: '[TouchA>]', target: element1},
// move the touch pointer to element2
{pointerName: 'TouchA', target: element2},
// release the touch pointer at the last position (element2)
{keys: '[/TouchA]'},
])

Pointer position

PointerTarget

interface PointerTarget {
target: Element
coords?: PointerCoords
}

The PointerTarget props allows to describe the position of the pointer on the document.
The coords you provide are applied as-is to the resulting MouseEvent and can be omitted.
The target should be the element receiving the pointer input in the browser. This is the topmost element that can receive pointer event at those coordinates.

SelectionTarget

interface SelectionTarget {
node?: Node
offset?: number
}

Pointer actions can alter the selection in the document.
In the browser every pointer position corresponds with a DOM position. This is a DOM node and a DOM offset which usually translates to the character closest to the pointer position.
As all character in a no-layout environment are in the same layout position we assume a pointer position to be closest to the last descendant of the pointer target.

If you provide offset, we assume the pointer position to be closest to the offset-th character of target.textContent.

If you also provide node, we treat node and offset as the exact DOM position to be used for any selection.

// element: <div><span>foo</span><span>bar</span></div>
// | marking the cursor.
// [ ] marking a selection.

pointer({target: element, offset: 2, keys: '[MouseLeft]'})
// => <div><span>fo|o</span><span>bar</span></div>

pointer([{target: element, offset: 2, keys: '[MouseLeft>]'}, {offset: 5}])
// => <div><span>fo[o</span><span>ba]r</span></div>

pointer({target: element, node: element, offset: 1, keys: '[MouseLeft]'})
// => <div><span>foo</span>|<span>bar</span></div>