Skip to content

docs: rework disappearance guide to provide more guidance #499

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

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

kimroen
Copy link

@kimroen kimroen commented Jun 12, 2020

Makes a number of changes to the disappearance guide, moving it in a direction where it recommends
more of the best practices that have appeared since the last time it was uses, as well as taking a stronger
stance of which of multiple options are recommended.

This PR came about because I was answering some questions related to appearance and disappearance, and the people I was hadn't found the answers they were looking for in this guide.

In more detail, the changes are:

  • Recommend findBy over waitFor
  • Recommend waitForElementToBeRemoved over waitFor
  • Use matchers from jest-dom in examples instead of checking for null and then mentioning jest-dom later
  • Remove inline setup-instructions for jest-dom and instead link to docs
  • Smaller code example changes (split up separate examples in the same code fence to multiple fences)
  • Use the word document instead of DOM most places
  • Use screen in all examples
  • Add explicit expect statements in all the examples for consistency

Makes a number of changes to the disappearance guide, moving it in a direction where it recommends
more of the best practices that have appeared since the last time it was uses, as well as taking a stronger
stance of which of multiple options are recommended.

In more detail, the changes are:

- Prioritize `findBy` over `waitFor`
- Use matchers from `jest-dom` in examples instead of checking for `null` and then mentioning `jest-dom` later
- Remove inline setup-instructions for `jest-dom` and instead link to docs
- Recommend `waitForElementToBeRemoved` over `waitFor`
- Smaller code example changes (split up separate examples in the same code fence to multiple fences)
- Use the word `document` instead of `DOM` most places
- Use `screen.` in all examples
- Add explicit `expect` statements in all the examples for consistency
})
})
```

Polling like this is not as efficient as observing for mutations using
`waitForElementToBeRemoved`, but sometimes it's the best option.
Copy link
Author

@kimroen kimroen Jun 12, 2020

Choose a reason for hiding this comment

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

Are there any good examples of when waitFor would work and waitForElementToBeRemoved wouldn't in this context? If not, then maybe it shouldn't have equal space on this page.

Copy link
Member

Choose a reason for hiding this comment

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

agree 👍

If not, I wouldn't even mention a "negated" waitFor as an alternative to waitForElementToBeRemoved

Copy link
Author

Choose a reason for hiding this comment

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

I agree, I've removed the waitFor option here ✨

Copy link
Member

@afontcu afontcu left a comment

Choose a reason for hiding this comment

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

This is great! Thank you for taking the time 🤗

I left some comments here and there, but I love the general direction of this ❤️

kimroen and others added 2 commits June 12, 2020 13:03
Changes "you can use" to "you need to use" and removes a redundant clause from the sentence.

Co-authored-by: Adrià Fontcuberta <[email protected]>

```javascript
test('movie title appears', async () => {
// element is initially not present...
Copy link
Member

Choose a reason for hiding this comment

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

Maybe add an extra assertion to check that it's not present initially?

// element is initially not present...
expect(movieTitle).not.toBeInTheDocument()

Copy link
Author

@kimroen kimroen Jun 12, 2020

Choose a reason for hiding this comment

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

Maybe, but I feel that isn't entirely relevant and detracts a little from what we're trying to show in this example. Also, asserting that things don't exist is covered further down on the page.

If we did do that though, there should also be code here to do something that would make the title appear after asserting it isn't here, and I'm not sure it makes sense to get into that here.

We could add a comment saying as much after the assertion, like this:

test('movie title appears', async () => {
  expect(screen.queryByText('the lion king')).not.toBeInTheDocument()
  
  // pretend we do something here that should make the title appear

  const movieTitle = await screen.findByText('the lion king')
  expect(movieTitle).toBeInTheDocument()
})

But I think it might be better to alter the comment in the test to something that makes it clearer that this would be part of a longer test:

Suggested change
// element is initially not present...
// ...code setting up a page that will eventually contain a movie title

Do you think the last suggestion would help, or is there maybe something else we could do to alleviate the confusion or lack of clarity we are hoping to fix by adding this assertion?

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 the first suggestion is much clearer instead of changing the comment tbh

Copy link
Author

Choose a reason for hiding this comment

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

I think the first suggestion is much clearer instead of changing the comment tbh

Fair! In your mind, what is it that is unclear that adding this assertion solves? Or is there something else that makes it so you want it to be added?

Copy link
Member

Choose a reason for hiding this comment

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

On the other hand, you're right with not wanting to have things in here that you'll explain later, so maybe the changed comment is indeed a better option to go with here...

Maybe we can make a full example (like the second suggestion) later on the page? 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think there's value in keeping the first examples minimal, without having to decipher fake application code. Expanding on the comment and making clear this is a snippet of a larger test should be good.

@kimroen
Copy link
Author

kimroen commented Jun 16, 2020

I've been trying to think of a good example where we would want to assert that something is present, disappears and is not present, and I'm struggling. I think this is change is valuable without an extra example though, so maybe a good way forward could be to merge it and then work on an example separately if we feel that would add clarity?

@MichaelDeBoey Do you have a specific example we could add, and would you be interested in adding that in a separate PR?

@afontcu I think I have addressed all your comments - are you okay with merging this as it is?

@kimroen
Copy link
Author

kimroen commented Jun 16, 2020

Actually, I'll go in and remove the waitFor variant for waiting for elements to be removed.

@kimroen kimroen requested a review from afontcu June 16, 2020 07:52
Comment on lines +39 to +40
These do more or less the same thing (`findBy` uses `waitFor` under the hood),
but the `findBy` version results in simpler code and a better error message.
Copy link
Member

Choose a reason for hiding this comment

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

Okay, this is interesting.

I'm not sure I agree on the statement (I believe using waitFor is more explicit, and helps the test conveying meaning) but that's entirely personal. The question here is whether if docs should showcase two ways of doing the same thing 🤔

If we agree on findBy being simpler and packed with a better error message, then I'd say this is the way docs should suggest 👍

waitFor is useful for other stuff (such as waiting for XHR requests to happen, or other). It might appear somewhere else in docs.

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 this is the last bit that needs some attention, then we can merge!

@kimroen
Copy link
Author

kimroen commented Jun 16, 2020

Some relevant comments by @kentcdodds over here: testing-library/react-testing-library#673 (comment)

test('movie title no longer present in document', async () => {
// element is present
const movie = screen.queryByText('the mummy')
await waitForElementToBeRemoved(movie)
Copy link
Author

Choose a reason for hiding this comment

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

I see @kentcdodds commented over here that this should receive a callback, not the element directly: testing-library/react-testing-library#673 (comment)

I feel like I've seen that doing it this way works too though, so I'm not sure.

Copy link
Member

@afontcu afontcu Jun 16, 2020

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

might be worth expanding on this section later with a note about working with React, because sometimes the node gets destroyed and replaced, making these types of tests either pass or fail when they shouldn't

Comment on lines +39 to +40
These do more or less the same thing (`findBy` uses `waitFor` under the hood),
but the `findBy` version results in simpler code and a better error message.
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
These do more or less the same thing (`findBy` uses `waitFor` under the hood),
but the `findBy` version results in simpler code and a better error message.
These do more or less the same thing (`findBy` uses `waitFor` under the hood),
but the `findBy` version produces errors more like a `getBy` query,
instead of a general-purpose timeout error.

})
```

Using
`waitForElementToBeRemoved` works by using a
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the waitFor style should also be documented here, particularly for working with React, when the node reference itself is unstable but a retryable query inside a callback would work.

Comment on lines +73 to +74
As opposed to waiting for removal, this is for when you are at a point in your
test where you know an element shouldn't be present.
Copy link
Collaborator

Choose a reason for hiding this comment

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

This section can be tightened up. It's unclear what "this" refers to here. Also, we shouldn't assume jest-dom is installed and should mention the null check.

Suggested change
As opposed to waiting for removal, this is for when you are at a point in your
test where you know an element shouldn't be present.
If you want to assert that an element is not present _right now_,
rather than testing that it is present and will disappear, use
`queryBy` instead of `getBy` for the query, and then assert that
nothing was found.

@alexkrolick alexkrolick added good first issue 🏁 Good for newcomers help wanted 👋 Extra attention is needed hacktoberfest 🎃 labels Oct 1, 2020
@alexkrolick
Copy link
Collaborator

There are a few open items on this, but it's almost there. Adding some labels for visibility. Hoping someone can finish it off!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
good first issue 🏁 Good for newcomers help wanted 👋 Extra attention is needed
Projects
Status: In progress
Development

Successfully merging this pull request may close these issues.

5 participants