Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to test debounced hover states? #796

Closed
richiethomas opened this issue Dec 1, 2021 · 1 comment
Closed

How to test debounced hover states? #796

richiethomas opened this issue Dec 1, 2021 · 1 comment

Comments

@richiethomas
Copy link

richiethomas commented Dec 1, 2021

Problem description:

I saw the original issue which resulted in the addition of the userEvent.hover() function. We make frequent use of this userEvent in our codebase and are quite happy with how it works, so thank you for adding it! :-)

We have certain DOM elements which, after the user hovers over them for N # of ms, show a tooltip. We'd like to test both the happy path (i.e. the tooltip shows up when the user hovers for the prescribed # of ms) and the alternate path (ie no tooltip appears when the user hovers for less than the # of ms). The cleanest way I could think of to do this was via something like:

const domElement = getByText('My DOM element');
userEvent.hover(domElement, { timeDuration: 999 })
expect(queryByText('Tooltip Text')).not.toExist();

userEvent.hover(domElement, { timeDuration: 1000 })
expect(getByText('Tooltip Text')).toExist();

The specific name timeDuration is just contrived to illustrate the example. However, after parsing the code for the hover action, there doesn't appear to be any API equivalent to the above.

@ph-fritsche
Copy link
Member

This is the hover action in user-event@14.0.0-beta:

export async function hover(this: UserEvent, element: Element) {
if (!this[Config].skipPointerEventsCheck && !hasPointerEvents(element)) {
throw new Error(
'unable to hover element as it has or inherits pointer-events set to "none".',
)
}
return this.pointer({target: element})
}

There is no magic and no intention to add any. If you want to wait for a specific duration just do so outside of the hover action:

await userEvent.hover(element)

await new Promise(r => setTimeout(r, 500)) // wait for (at least) 500ms
expect(screen.queryByText('Tooltip Text')).not.toBeInTheDocument()

await new Promise(r => setTimeout(r, 200)) // wait another (at least) 200ms
expect(screen.getByText('Tooltip Text')).toBeInTheDocument()

(Note that waiting for something to not have happened might be brittle if the waited duration is too close to the actual threshold as the asynchronous approach per specs gives up control over the order of execution even though it might be predictable.)

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

No branches or pull requests

2 participants