# testing-library/prefer-screen-queries 📝 Suggest using `screen` while querying. 💼 This rule is enabled in the following configs: ![badge-angular](https://img.shields.io/badge/-Angular-black?style=flat-square&logo=angular&logoColor=white&labelColor=DD0031&color=black) `angular`, ![badge-dom](https://img.shields.io/badge/%F0%9F%90%99-DOM-black?style=flat-square) `dom`, ![badge-marko](https://img.shields.io/badge/-Marko-black?style=flat-square&logo=marko&logoColor=white&labelColor=2596BE&color=black) `marko`, ![badge-react](https://img.shields.io/badge/-React-black?style=flat-square&logo=react&logoColor=white&labelColor=61DAFB&color=black) `react`, ![badge-svelte](https://img.shields.io/badge/-Svelte-black?style=flat-square&logo=svelte&logoColor=white&labelColor=FF3E00&color=black) `svelte`, ![badge-vue](https://img.shields.io/badge/-Vue-black?style=flat-square&logo=vue.js&logoColor=white&labelColor=4FC08D&color=black) `vue`. ## Rule Details DOM Testing Library (and other Testing Library frameworks built on top of it) exports a `screen` object which has every query (and a `debug` method). This works better with autocomplete and makes each test a little simpler to write and maintain. This rule aims to force writing tests using built-in queries directly from `screen` object rather than destructuring them from `render` result. Given the screen component does not expose utility methods such as `rerender()` or the `container` property, it is correct to use the `render` returned value in those scenarios. However, there are 3 exceptions when this rule won't suggest using `screen` for querying: 1. You are using a query chained to `within` 2. You are using custom queries, so you can't access them through `screen` 3. You are setting the `container` or `baseElement`, so you need to use the queries returned from `render` Examples of **incorrect** code for this rule: ```js // calling a query from the `render` method const { getByText } = render(); getByText('foo'); // calling a query from a variable returned from a `render` method const utils = render(); utils.getByText('foo'); // using after render render().getByText('foo'); // calling a query from a custom `render` method that returns an array const [getByText] = myCustomRender(); getByText('foo'); // calling a top-level query with a specific container const popup = screen.getByTestId('modal-dialog'); getByText(popup, 'label'); ``` When you need to query inside a specific subtree, prefer `within(subtree)` over importing or destructuring a top-level query and passing the subtree as the first argument. That keeps the query scoped while preserving the readability this rule encourages. Examples of **correct** code for this rule: ```js import { render, screen, within } from '@testing-library/any-framework'; // calling a query from the `screen` object render(); screen.getByText('foo'); // using after within clause within(screen.getByTestId('section')).getByText('foo'); // querying inside a specific subtree const popup = screen.getByTestId('modal-dialog'); within(popup).getByText('label'); // calling a query method returned from a within call const { getByText } = within(screen.getByText('foo')); getByText('foo'); // calling a method directly from a variable created by within const myWithinVariable = within(screen.getByText('foo')); myWithinVariable.getByText('foo'); // accessing the container and the base element const utils = render(baz); utils.container.querySelector('foo'); utils.baseElement.querySelector('foo'); // calling the utilities function const utils = render(); utils.rerender(); utils.unmount(); utils.asFragment(); // the same functions, but called from destructuring const { rerender, unmount, asFragment } = render(); rerender(); asFragment(); unmount(); // using baseElement const { getByText } = render(, { baseElement: treeA }); // using container const { getAllByText } = render(, { container: treeA }); // querying with a custom query imported from its own module import { getByIcon } from 'custom-queries'; const element = getByIcon('search'); // querying with a custom query returned from `render` const { getByIcon } = render(); const element = getByIcon('search'); ``` ## Further Reading - [Common mistakes with React Testing Library - Not using `screen`](https://kentcdodds.com/blog/common-mistakes-with-react-testing-library#not-using-screen) - [`screen` documentation](https://testing-library.com/docs/queries/about#screen) - [Advanced - Custom Queries](https://testing-library.com/docs/dom-testing-library/api-custom-queries/) - [React Testing Library - Add custom queries](https://testing-library.com/docs/react-testing-library/setup/#add-custom-queries)