-
Notifications
You must be signed in to change notification settings - Fork 470
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(screen): Add screen export which has all queries bound to the body #412
Conversation
Oh, and to be clear, I have no intention of removing existing functionality from |
e55904d
to
87407c8
Compare
This pull request is automatically built and testable in CodeSandbox. To see build info of the built libraries, click here or the icon next to each commit SHA. Latest deployment of this branch, based on commit fcc1e2b:
|
I would also consider calling it |
Codecov Report
@@ Coverage Diff @@
## master #412 +/- ##
=====================================
Coverage 100% 100%
=====================================
Files 21 22 +1
Lines 370 374 +4
Branches 86 87 +1
=====================================
+ Hits 370 374 +4
Continue to review full report at Codecov.
|
@kentcdodds Liked Eg.:
After:
(or you could call it |
Just a thought but what about adding the queries to window.document? I've thought for a long time it'd be nice to have them built into the browsers living side by side with document.querySelector |
I really like the look of this! Is there anything we could do to improve the error message in the environments where the global Importing page and getting null seems a little confusing. Or perhaps this isn't as much of a problem as I think, I'm still quite new to this library and don't fully understand when |
What about just exporting it from the root?
Ie `import {getByText} from "@testing-library/react"`
|
I feel like doing that would elevate
We have In any case, if we were to add events to this
All the (unbound) queries are already exported from the root. Also, part of the benefit that we get from a namespace like |
Just adding to the mix the fact that in react-native a page is called screen. |
Personally, I really like this idea @kentcdodds. The suggestion made by earlier I am not sure whether it makes sense to use Maybe we could expose the |
Cool. I like that you can change to a new framework and just update the
This is why I haven't been destructuring the render result in RTL. Intellisense on the
👍 yes, if we do that
🤔
I have been using import {page, user, render} from '@testing-library/react'
test('does x', () => {
render(<Comp />)
user.click(page.getByText('Sign In'))
user.type(await page.findByLabelText('Username'), 'Kent')
user.type(await page.findByLabelText('Password'), 'abc123')
user.click(page.getByRole('button', {name: 'Submit'}))
expect(await page.findByText('Welcome')).toBeInTheDocument()
}) |
I'd love to great what @Gpx has to say about including user-event as an export from DOM Testing Library (or maybe even moving it into this project completely). |
What is the difference of...? const page = render(<Thing />)
// page.queryXXXXXXX
// page.getByXXXXX |
This comment has been minimized.
This comment has been minimized.
@trevorwright @AlgusDark this is a feature of DOM Testing Library, not the React wrapper.
|
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 makes a lot more sense with the afterEach(cleanup)
recommendation. One less footgun when dealing with component libraries and portals 👍
I quite like your bottom code snippet :) Makes sense to me! |
To be clear, people shouldn't need to do that because it's automatic. I like your suggestion and I'll implement that 👍 |
87407c8
to
b3bf65f
Compare
I think this should be merged and we can start updating docs etc. Then we can discuss the |
Actually...
Should we call it screen as well? Keep it consistent? What do you think @bcarroll22? I'm fine with calling it a screen for web. |
@kentcdodds In case this wasn't by accident: You can batch suggestions into a single commit. You need to switch to the "Files changed" tab though. |
This looks like a good improvement. Totally on board 👍 Regarding the |
Sorry it took me a couple days to get to this, holidays have things crazy 😬 I'm cool with working on getting As far as the user-event stuff goes, if that one becomes a top level export, we're almost just have to rename So I'm good on the screen export, and the other part for us would essentially be changing |
831beb4
to
fcc1e2b
Compare
Let's open a new issue to discuss the adoption of I'm going to make a PR for docs before I merge this. If anyone would like to add a PR for the TypeScript typings that would be super duper :) |
🎉 This PR is included in version 6.11.0 🎉 The release is available on:
Your semantic-release bot 📦🚀 |
@kentcdodds Curious on your thought on how this plays with Previous: test('test 1', () => {
const { usernameInput, passwordInput, getByLabelText } = renderComponent()
...
}
function renderComponent() {
const utils = render(<MyComponent />)
return {
...utils,
usernameInput: utils.getByLabelText(/username/i),
passwordInput: utils.getByLabelText(/password/i),
}
} Ideally, to fully lean in to the experience benefit of not updating the destructuring, we wouldn't return keys for elements/utils like We could just tack on to the |
@babramczyk Our team uses this pattern a lot, especially when you are writing tests for larger more complex features. It allows for simple management of selectors so that if the label changes from It really helps when you write some sort of custom code for helping RTL easily interact with your feature, and allowing you to continually reuse that code. One thing we will do in larger features is also use this pattern to namespace the features a bit, for example (somewhat simplified) const renderComponent = () => {
const utils = render(<MyComponent />)
const setSelectedDate = () => {}
const selectedDateValue = () => {}
const setFilter = () => {}
return {
...utils,
header: {
setSelectedDate,
selectedDateValue,
setFilter,
}
}
}
// later in tests
const { header } = renderComponent();
header.setSelectedDate(new Date());
expect(header.selectedDateValue()).toBe('Today'); |
Yeah, I think it's fine to stick with that pattern. I definitely wouldn't recommend monkey-patching on to |
Hey @kentcdodds i'm trying to use this setup and i keep getting 'page' as undefined when I try to import it...either from my utils file or directly from @testing-library/react ....trying to use this b/c i have customRender setup based on RTL docs for redux. Thanks for any direction! |
It ended up getting called |
ok, cool, yes I was using screen before and was getting jest error |
What: Add page export which has all queries bound to the body
Why: Drastically simplifies using queries in tests
How: Added a
page.js
file (and test) which will callgetQueriesForElement(document.body)
if there's a document.body globally available (if there's not, then folks will have to create their own queries which is fine because people without a global document are used to doing a lot of manual work. I still don't understand why they do this...)Checklist:
This needs more discussion, but let me be clear... Despite this being a tiny PR, this is a huge deal. Observe:
Before:
After:
This is a much better experience IMO and it's what I think we should recommend in all our docs. A big benefit to this is that it's framework agnostic, so it will help avoid issues like testing-library/react-testing-library#538 (which has honestly always been a point of annoyance for me).
I'd love to hear what people think. I think we can merge this today, get the docs and TS stuff updated, then we can finally deal with the other PRs I've been neglecting.