{"revision":"c10276e953456835cdbb1f3a60d58ae1980be353","document":{"id":389,"path":"api-reference/developer-guides/r_run_ui_test_script_screen.md","title":"screen — DOM queries","bundle":null,"doc_type":null,"release":"australia","body":"\n# screen — DOM queries\n\nThe screen API is the primary interface for finding elements on the page tested by a Run UI Test Script step. All query methods pierce shadow roots automatically, so they work with Now Experience components as well as classic Jelly and UI16 pages.\n\n## Query method variants\n\nEach query type comes in the following variants.\n\n|Variant|Returns|Throws when missing?|Async?|\n|-------|-------|--------------------|------|\n|`getBy*`|Single element|Yes, throws immediately|No|\n|`getAllBy*`|Array of elements|Yes, if empty|No|\n|`queryBy*`|Single element or `null`|No|No|\n|`queryAllBy*`|Array, which may be empty|No|No|\n|`findBy*`|Single element|Yes, rejects the Promise|Yes, polls until found|\n|`findAllBy*`|Array of elements|Yes, if empty|Yes, polls until found|\n\nUse `findBy*` when the element appears asynchronously, such as after an API response, animation, or navigation. Use `getBy*` when the element must already exist. Use `queryBy*` to check whether an element is absent.\n\n## Query types\n\nEach variant supports the following query types.\n\n|Type|Finds elements by|Example|\n|----|-----------------|-------|\n|`Role`|ARIA role, implicit or explicit|`screen.getByRole('button', { name: 'Save' })`|\n|`Text`|Visible text content|`screen.findByText('Incident created')`|\n|`LabelText`|Associated `<label>` text|`screen.getByLabelText('Short description')`|\n|`PlaceholderText`|`placeholder` attribute|`screen.getByPlaceholderText('Search…')`|\n|`AltText`|`alt` attribute|`screen.getByAltText('Company logo')`|\n|`Title`|`title` attribute|`screen.getByTitle('Close dialog')`|\n|`TestId`|`data-testid` attribute|`screen.getByTestId('submit-btn')`|\n|`DisplayValue`|Current display value of a form control|`screen.getByDisplayValue('High')`|\n|`Selector`|CSS selector, shadow-piercing|`screen.getBySelector('input[name=\"priority\"]')`|\n\n`getByRole` is the recommended default because it validates accessibility as it queries. Use `getBySelector` only when no accessible query matches.\n\n## screen.waitFor\\(callback, options?\\)\n\nPolls `callback` until it stops throwing. Use this method to wait for a condition that isn't directly an element query.\n\n```\nawait screen.waitFor(() => {\n  expect(screen.getByRole('status')).toHaveTextContent('Complete');\n});\n```\n\nOptions: `{ timeout: 5000, interval: 50 }`, in milliseconds.\n\n## screen.debug\\(element?\\)\n\nLogs the outer HTML of `element`, or the whole page body when omitted, to the browser console, including shadow root contents. Use it when a query doesn't match what you expect.\n\n```\nscreen.debug(); // log the full page\nscreen.debug(screen.getByRole('form')); // log a specific subtree\n```\n\n## Shadow DOM traversal\n\nAll `screen.getBy*`, `screen.findBy*`, and `screen.queryBy*` queries automatically pierce shadow roots. Now Experience components render their content inside shadow roots, which are normally invisible to `document.querySelector`. The ATF testing library traverses these boundaries transparently, so you can query by role or text whether the element is in light DOM or shadow DOM.\n\n`getByRole` resolves accessible names by reading shadow root text content when the host element's own text content is empty, matching the behavior that a screen reader reports.\n\n`getBySelector` uses a custom shadow-piercing CSS selector engine that handles cross-shadow combinators, for example `now-typeahead input`.\n\n"}}