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
add toContainQuerySelector matcher for better errors #106
Comments
Hi, I've been thinking about this, that's the reason for the delayed response. Sorry about that. I'm hesitant of providing this. The argument for the unhelpful error message when On the other hand, the downside is that this custom matcher feels to move away from the testing libraries' guiding principle. It encourages testing the internal markup structure rather than encouraging asserting based more on what the user That being said, I'm open to hear a stronger case for this. Or maybe the input from @kentcdodds and @alexkrolick would be nice. |
I'm opposed. If you want a good error message for something that has a query then just do this: expect(getByTestId('html-element')).toBeInTheDocument() The fact is that if getByTestId('html-element') And that works for me. If there's a general css query selector you'd like to select on that's not one of the supported queries I would recommend you find a way to use one of the supported queries for maintainability/accessibility reasons. It's pretty easy to workaround if you want to use a general query though: expect(document.querySelector('does-not-exist')).not.toBeInTheDocument() That should give you a good error message. |
For me the problem is more around knowing what was actually rendered, not about what element was not found. For example, suppose I have a list element with an empty state. I expect to see the empty state, but I don't, so the test fails. OK, so I can infer that it didn't render the empty state, but I have no idea why without digging in to code. If instead it said "failed to find 'my-empty-state' in As you say, the existing error for the negated version is pretty OK already. It's just the non-negated version which is bad. I'm very uneasy about the naked expect(() => getByTestId('html-element')).not.toThrow(); // err...
// negated: ("expect not to be in the document")
expect(() => getByTestId('html-element')).toThrow(); // what? what is this?! I understand the concern around using native query selectors rather than the helpers. I quite like selenium's expect(document).toContainElement(By.testId('html-element'));
expect(document).toContainElement(By.querySelector('.whatever'));
expect(document).toContainElement(By.name('password'));
// etc. |
You could even try something crazy like this: expect(getByTestId).toFind('html-element');
expect(getByTestId).not.toFind('html-element');
expect(document.querySelector).toFind('.whatever');
expect(document.querySelector).not.toFind('.whatever'); Where the The main limitation of this approach is that if somebody runs a test against something other than the whole document (i.e. Also I'm not sure if it would be necessary to |
Why not this: expect(queryByTestId('html-element')).not.toBeInTheDocument()
|
@alexkrolick true, but the reverse: expect(queryByTestId('html-element')).toBeInTheDocument() produces a bad error message if it fails, which is what @kentcdodds was suggesting If you think it should be a helpful error, maybe that means this is actually a bug in
Which is totally useless. Overall, it means the current state is rather inconsistent / incomplete: expect(getByTestId('html-element')).toBeInTheDocument() // works, good error message on failure, but throws rather than failing and the matcher is only present for appearances sake
expect(getByTestId('html-element')).not.toBeInTheDocument() // never works (either fails or throws)
expect(queryByTestId('html-element')).toBeInTheDocument() // works, and does not throw, but (very) bad error message on failure
expect(queryByTestId('html-element')).not.toBeInTheDocument() // works, and does not throw, with a reasonable-enough error message on failure |
I think we could safely remove the jest-dom/src/to-be-in-the-document.js Lines 9 to 11 in b2b4bd3
|
First, about these two uses: expect(getByTestId('html-element')).toBeInTheDocument()
expect(getByTestId('html-element')).not.toBeInTheDocument() Combining Now, on to the other part: expect(queryByTestId('html-element')).toBeInTheDocument()
expect(queryByTestId('html-element')).not.toBeInTheDocument() I understand your point, but there's hardly something we can do with @alexkrolick's suggestion might help, but I suspect the error message if we let this go through at that point in the code would not be helpful either. Think about it, the matcher was called with |
That's the suggestion, in the same way that getBy prints the DOM when it fails. It helps diagnose the issues much faster than adding debug/prettydom calls. |
Seems like the consensus here was to not add the proposed feature. I'll be closing this for the time being. |
Describe the feature you'd like:
Currently the recommendation for checking if an element exists is:
(abridged from the docs)
But this returns pretty useless errors if the condition is not met. It would be much more useful to combine the
querySelector
with the existence check, such as:(this is also much shorter syntax)
This is comparable to
toContainMatchingElement
from theenzyme-matchers
project.Suggested implementation:
I've tried to match the code style of this project, but might have missed something:
Describe alternatives you've considered:
.not.toBe(null)
or a hypothetical.toExist()
, etc. have similar problems to.toBeInTheDocument
: the returned error is not helpful for diagnosis because it does not include the content which was actually observed when an element is missing.It might be valuable to be able to count the number of occurrences (e.g.
toContainQuerySelector('foo', 4)
to check for exactly 4 occurrences, but I can't think of a self-descriptive method name for this, so as-proposed this checks for 1-or-more, or exactly zero.Teachability, Documentation, Adoption, Migration Strategy:
Recommendation can be updated to:
No migration necessary; existing matchers do not need to change.
The text was updated successfully, but these errors were encountered: