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

feat: add prefer-find-by rule #144

Merged
merged 1 commit into from Jun 3, 2020

Conversation

gndelia
Copy link
Collaborator

@gndelia gndelia commented May 22, 2020

This one tackle #127

While current code works, I still have to polish some stuff and add more scenarios (and update the docs)


## Further Reading

TBD
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would link to findBy query doc here, as it mentions that findBy is a shortcut for waitFor + getBy. I would use the text from that callout as the main inspiration for this url in the description at the top.

@Belco90
Copy link
Member

Belco90 commented May 23, 2020

Looking good so far!

```js
const submitButton = await findByText('foo');

const submitButton = await screen.findAllByRole('table');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would add some correct usages of waitFor here as well.


## When Not To Use It

TBD
Copy link
Member

@benmonro benmonro May 23, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
TBD
Don't use this rule if you don't care if people aren't following best practices of testing library.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't go that direct here. Better something nicer like "Not encouraging use of findBy shortcut from testing library best practices".

docs: {
description: 'Suggest using find* instead of waitFor to wait for elements',
category: 'Best Practices',
recommended: false,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not recommend this one?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be recommended, indeed.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"warn" or "error" ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice question. I think warn is enough? This rules doesn't prevent any malfunctioning code, just warns about a preferred way of writing it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added warn

messages: {
preferFindBy: 'Prefer {{queryVariant}}{{queryMethod}} method over using await {{fullQuery}}'
},
fixable: null,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we not make the simple ones fixable?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still a draft Ben. Leave the guy work on this! We are discussing in the original issue if addressing it here or in a 2nd PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was just an idea. Not trying to clock this or anything...

@gndelia
Copy link
Collaborator Author

gndelia commented May 25, 2020

I pushed a new version.

  • CI passes: More test cases!
  • Docs updated: I added links, details, and more examples

still pending to make it fixable


type Options = [];
export type MessageIds = 'preferFindBy';
// TODO check if this should be under utils.ts - there are some async utils
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have ASYNC_UTILS in utils.ts but it includes more methods than here.

Copy link
Member

@Belco90 Belco90 May 26, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe it's a good idea to keep all different async utils under an enumerate type and then build ASYNC_UTILS from all the enumerate options?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

after giving some though, I am not sure of moving this one out. It's not a list of all wait methods, but just a list of the ones this rule cares about. Not sure how useful it could be outside of here, as it's not all the wait methods. Either way, we could centralize them in the future if we see the chance

@Belco90
Copy link
Member

Belco90 commented May 26, 2020

I pushed a new version.

* CI passes: More test cases!

* Docs updated: I added links, details, and more examples

still pending to make it fixable

Nice work mate. It would be nice to have the fixable code here, but let me know what you think about it and if you prefer to address it in a separated PR in the future.

@gndelia gndelia marked this pull request as ready for review May 29, 2020 23:04
@gndelia
Copy link
Collaborator Author

gndelia commented May 29, 2020

This PR is ready to be reviewed.

I gave suggestions a try (instead of directly fixing the code), but the problem is that types in ESLint 6 differ from ESLint 7. I have a local branch with the suggestions which I believe are working, but the tests always pass for the suggestions; It's like I cannot force them to fail. I believe that once #138 is finished, suggestions should work better

So this PR goes without suggestions for fix available 😞

Copy link
Member

@Belco90 Belco90 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good mate, thanks for your work! I just requested couple of extra examples and tests, everything else seems fine. We are leaving the fix step for a future PR then right?

docs/rules/prefer-find-by.md Outdated Show resolved Hide resolved
docs/rules/prefer-find-by.md Show resolved Hide resolved
tests/lib/rules/prefer-find-by.test.ts Show resolved Hide resolved
@gndelia gndelia force-pushed the feature/prefer/find-by branch 3 times, most recently from e649e9d to 03ed88c Compare May 31, 2020 19:11
@gndelia
Copy link
Collaborator Author

gndelia commented May 31, 2020

BTW, I added the new rule to the main README.

image

Looking good mate, thanks for your work! I just requested couple of extra examples and tests, everything else seems fine. We are leaving the fix step for a future PR then right?

yes. The problem is that when testing suggestions, no matter what the expected output I write, the tests always passes. Let's look at this example.

code: `
            const submitButton = await ${waitMethod}(() => screen.${queryMethod}('foo', { name: 'baz' }))
          `,
          errors: [{
            messageId: 'preferFindBy',
            data: {
              queryVariant: queryMethod.includes('All') ? 'findAllBy': 'findBy',
              queryMethod: queryMethod.split('By')[1],
              fullQuery: `${waitMethod}(() => screen.${queryMethod}('foo', { name: 'baz' }))`,
            },
            suggestions: [{
              messageId: 'preferFindBy',
              // this expected output should match the suggestion output of the rule
              output: `const submitButton = await screen.${queryMethod.includes('All') ? 'findAllBy': 'findBy'}${queryMethod.split('By')[1]}('foo', { name: 'baz' })`
            }]
          }]
        })

No matter what output I write in the test, the tests pass, making me think that there's something wrong with the test assertion declaration.

I think the problem might be solved with ESlint 7 - furthermore, the contract changed in that version so it'll be easier to implement once that is solved.

We could probably go with that in another PR, does that sound good for you?

@Belco90
Copy link
Member

Belco90 commented Jun 1, 2020

@gndelia that sounds good. I remember I had a similar problem when implementing the fix for the waitFor migration. We can wait a little bit until we find proper way to test it, but I think we should go for fix rather than suggestion as there is just single way of changing a getBy + waitFor by a findBy.

Copy link
Member

@Belco90 Belco90 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a small text update in the rule description and we are ready to go!

@@ -0,0 +1,78 @@
# Use `find*` query methods to wait for elements instead of waitFor (prefer-find-by)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use here same description from README please?

Suggested change
# Use `find*` query methods to wait for elements instead of waitFor (prefer-find-by)
# Suggest using `findBy*` methods instead of the `waitFor` + `getBy` queries (prefer-find-by)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

@Belco90
Copy link
Member

Belco90 commented Jun 2, 2020

I've been thinking about this rule name. Could we regret it in the future for being so generic? Could we have in the future other cases where we prefer findBy over other options? I don't know if could be worth it to think about a better name for the rule. ESLint rules names should be short tho, but I'd like to think about it. Could something like no-get-by-wait-for-combo work? Maybe I'm overthinking around this.

@benmonro
Copy link
Member

benmonro commented Jun 2, 2020

I think when it comes to rule names less is more. Either prefer-find-by or no-wait-for-get

@gndelia
Copy link
Collaborator Author

gndelia commented Jun 2, 2020

we could expand the rules or rename (breaking change) if we get a collision in the future. Not sure which other use case findBy* offers, to prefer it over something else...

@Belco90 Belco90 merged commit 7a9af37 into testing-library:master Jun 3, 2020
@Belco90
Copy link
Member

Belco90 commented Jun 3, 2020

🎉 This PR is included in version 3.2.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants