I love the waitForElement function. However, there are cases where I don't add an element but rather remove existing ones. Is there a similar waitForElementToDisappear function or is there an easy way to achieve that using the existing functions?
await waitForElementToDisappear(() => getByText('my button'))
...
Currently I'm using process.nextTick but that seems like a hack to me:
process.nextTick(() => {
...
done()
})
Could you open this issue in dom-testing-library? That's where this work will be done. I'm thinking I'm in favor.
@kentcdodds I think there's a new GitHub feature that allows owners of a repo to transfer issues to other repos. Can you check if that's the case here?
Forgot about that! Done :)
Now let's discuss.
So you can do this today with:
await wait(() => expect(getByText('my button')).not.toBeInTheDocument())
But that's kinda awkward and having a waitForElementToBeRemoved or something similar would be useful. Just not sure of the best name.
In the meantime, I found out that waitForDomChange actually covers most of my use cases. For explicitly wait for the removal of an element, I think the name you suggested (waitForElementToBeRemoved) is quite a good one. It's a little verbose, but I think that's worth having the name be explicit about what it does.
I'm into it. I say let's do it.
@kentcdodds I think it would have to be queryByText? Otherwise the getByText itself will fail when the element goes away, and the expectation won't be checked.
Also, I wonder if the awkwardness here is something you feel very strongly? I don't personally see a problem with that wait (that's +/- how I've seen this getting done in "selenium era"). Maybe a documentation change would be a way to go instead of increasing the API surface?
edited: I typed it a while ago, and when I commented I saw that you already decided to do it - not trying to argue here, just curious :)
No worries @lgandecki, thanks for providing your perspective. You make good points. I wonder though if there could be several document changes before that thing is actually removed. Like a progress bar for example.
It's true that this is really not a very typical thing and the workaround isn't that challenging (you're right, would need to be a queryBy*). Hmmm...
@kentcdodds @lgandecki I stumbled upon this issue and myself today, I need to check a progress loader has finished, as the main list element to check is always in the dom, I could check individual items within the list element but wanted to give this a try and then use snapshots for asserting that the items are there.
I tried
await wait(() => expect(getByTestId('progress-loader')).not.toBeInTheDocument());
but as stated that fails as the getByTestId fails when the loader is done.
I also tried
await wait(() => expect(queryByTestId('progress-loader')).not.toBeInTheDocument());
but now I get TypeError: expect(...).not.toBeInTheDocument is not a function. If you have any advice for this I'd appreciate it
EDIT:
nvm:
await wait(() => expect(queryByTestId('progress-loader')).toBe(null));
@gabriel403 jest-dom was just updated today to not throw when .toBeInTheDocument is checked against null
This should be closed now the PR was merged and released!
Most helpful comment
@kentcdodds I think it would have to be queryByText? Otherwise the getByText itself will fail when the element goes away, and the expectation won't be checked.
Also, I wonder if the awkwardness here is something you feel very strongly? I don't personally see a problem with that wait (that's +/- how I've seen this getting done in "selenium era"). Maybe a documentation change would be a way to go instead of increasing the API surface?
edited: I typed it a while ago, and when I commented I saw that you already decided to do it - not trying to argue here, just curious :)