-
Notifications
You must be signed in to change notification settings - Fork 141
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
feat(rule): add no-await-sync-events rule #240
feat(rule): add no-await-sync-events rule #240
Conversation
Thanks! I'll try to review it during the weekend. Although I don't know if there is something pending since it's a draft PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM thanks @J-Huang
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The rule implementation itself seems fine, but we need to improve few things:
- handle
userEvent.type
special cases better - make tests more confident
- add the rule to README
docs/rules/no-await-sync-events.md
Outdated
|
||
Functions in the event object provided by Testing Library, including | ||
fireEvent and userEvent, do NOT return Promise, with an exception of | ||
`userEvent.type`. Some examples are: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is technically true, but you don't need to always wait for it. From user-event doc:
To be clear, userEvent.type always returns a promise, but you only need to await the promise it returns if you're using the delay option. Otherwise everything runs synchronously and you can ignore the promise.
So should this rule report about userEvent.type
if no delay option passed? I think so
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with that ☝️ we should only await if the delay option is used. It would be great if we can cover that scenario with the rule
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agree. upgraded
the rule is, only if userEvent.type with delay option, await is valid. For all the other cases, it disallows await.
lib/utils.ts
Outdated
@@ -63,6 +63,11 @@ const ASYNC_UTILS = [ | |||
'waitForDomChange', | |||
]; | |||
|
|||
const ASYNC_EVENTS = [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These are SYNC_EVENTS actually, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't say there are events either - there are helpers or utilities.. Events would be "tab", "input", "change", "click" and so on... 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
initially thought it should be no-await-sync-utils, but feel not so correct...I can rename it to utils if it makes more sense.
}); | ||
|
||
ruleTester.run(RULE_NAME, rule, { | ||
valid: [ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You need to include more tests for checking userEvent
and fireEvent
non-related to Testing Library are not reported so they are valid with await
operator.
There is an ongoing refactor for v4 of the plugin which actually will check that for all rules out of the box, so I don't know if you prefer to wait for that version to be released.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Belco90
Do you mean how about if userEvent or fireEvent are user named objects, it should not apply the rule? Or, if extra functions are added to those objects, for those cases, await may be valid?
In order to ensure that, it has to check if the property name in userEvent or fireEvent is one of the expected event names, such as click, type, tab and so on. Even those methods can be overridden. Am I misunderstanding the question?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The former, so we don't report const declared by the user with the same name. As mentioned, the internal refactor for v4 will pass some helpers to all rules to check this generically, so I'm not sure if you prefer to wait for that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarification.
will refactor the code by then if needed.
invalid: [ | ||
// sync events with await operator are not valid | ||
...eventFunctions.map(func => ({ | ||
code: `() => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you write more realistic code here? So you end up with something like:
import { fireEvent } from '@testing-library/framework'
import userEvent from '@testing-library/user-event'
import MyComponent from './MyComponent'
it('should report sync event awaited', async () => {
render(<MyComponent />)
await ${func}('foo')
await findByQuery('some element')
})
and then check in the errors which line the error should appear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an extra correct example and I think it would be ready, apart from what we want to do with checking if reported objects are from Testing Library modules or not.
|
||
const baz = () => { | ||
// ... | ||
await userEvent.type(textInput, 'abc', {delay: 1000}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add an extra correct example for userEvent.type
without await and delay please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
updated
Not sure why CI chokes. My main computer died, so I just made a commit through github web page UI to my forked repo. |
@all-contributors please add @J-Huang for code, test and docs |
I've put up a pull request to add @J-Huang! 🎉 |
🎉 This PR is included in version 3.10.0 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Feature request:
#219
All functions in "fireEvent" and "userEvent" are synchronous, meaning it's wrong to add "await" operator for those function calls, with an exception of userEvent.type.
This new rule "no-await-sync-events" disallows adding "await" for those function calls in order to avoid errors.