# Query Priority — Jest, Vitest & Testing Library

Source: https://www.skillbyai.com/en/javascript-testing/p-priority

> getByRole first, getByTestId last.

## Accessible queries first

Testing Library documents a priority order. **Queries accessible to everyone**: `getByRole` (by ARIA role and accessible name, e.g. `getByRole('button', { name: /save/i })`), `getByLabelText` (form fields), `getByPlaceholderText` (only if there is no label), `getByText` (non-interactive text) and `getByDisplayValue` (current value of a field). **Semantic queries**: `getByAltText` and `getByTitle`. **Test IDs**: `getByTestId`, for when nothing else is meaningful. `getByRole` doubles as an accessibility check: if you cannot find a button by role and name, a screen-reader user probably cannot either. Role options like `level` for headings, `checked`, `selected` and `expanded` narrow matches further.

## Queries in priority order

All against the rendered DOM via screen.

```tsx
import { render, screen } from '@testing-library/react';

render(<SignupForm />);

screen.getByRole('heading', { level: 1, name: 'Create account' });
screen.getByRole('textbox', { name: 'Email' });          // <label>Email <input type="email" /></label>
screen.getByLabelText('Password');                        // input type=password has no textbox role
screen.getByRole('checkbox', { name: /accept the terms/i });
screen.getByRole('button', { name: 'Sign up' });
screen.getByText(/already have an account/i);
screen.getByAltText('Company logo');

// last resort, for things with no accessible handle (e.g. a canvas chart wrapper):
screen.getByTestId('signup-chart');
```

## Find the role with the tools

`screen.logTestingPlaygroundURL()` prints a link to Testing Playground that suggests the best query for an element, and when a `getByRole` fails, the error lists the roles and names that are present in the DOM.

**Quiz:** Which query does Testing Library recommend trying first for a Save button?

- [ ] getByTitle('Save')
- [ ] getByTestId('save-btn')
- [ ] container.querySelector('.btn-save')
- [x] getByRole('button', { name: 'Save' })

*Answer:* getByRole('button', { name: 'Save' }). Role plus accessible name matches how users and assistive tech find it.
