{"id":15023064,"url":"https://github.com/testing-library/jasmine-dom","last_synced_at":"2026-03-12T14:39:23.751Z","repository":{"id":38095505,"uuid":"281156287","full_name":"testing-library/jasmine-dom","owner":"testing-library","description":"🦥 Custom Jasmine matchers to test the state of the DOM","archived":false,"fork":false,"pushed_at":"2024-12-02T14:28:40.000Z","size":177,"stargazers_count":46,"open_issues_count":4,"forks_count":10,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-10-21T12:34:07.613Z","etag":null,"topics":["testing"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/testing-library.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-07-20T15:34:05.000Z","updated_at":"2025-04-17T02:02:28.000Z","dependencies_parsed_at":"2024-04-15T07:39:18.566Z","dependency_job_id":"6a483362-f5d2-4535-860a-ad74477bf210","html_url":"https://github.com/testing-library/jasmine-dom","commit_stats":{"total_commits":85,"total_committers":8,"mean_commits":10.625,"dds":0.5176470588235293,"last_synced_commit":"8ff7df1940cb0a54466e9ce55995ceb4cdd91e1b"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/testing-library/jasmine-dom","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testing-library%2Fjasmine-dom","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testing-library%2Fjasmine-dom/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testing-library%2Fjasmine-dom/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testing-library%2Fjasmine-dom/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/testing-library","download_url":"https://codeload.github.com/testing-library/jasmine-dom/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testing-library%2Fjasmine-dom/sbom","scorecard":{"id":875149,"data":{"date":"2025-08-11","repo":{"name":"github.com/testing-library/jasmine-dom","commit":"941174968b3d99249d27e3ddc6e4bcec9b4c6e89"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.2,"checks":[{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/validate.yml:46: update your workflow using https://app.stepsecurity.io/secureworkflow/testing-library/jasmine-dom/validate.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/validate.yml:49: update your workflow using https://app.stepsecurity.io/secureworkflow/testing-library/jasmine-dom/validate.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/validate.yml:54: update your workflow using https://app.stepsecurity.io/secureworkflow/testing-library/jasmine-dom/validate.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/validate.yml:62: update your workflow using https://app.stepsecurity.io/secureworkflow/testing-library/jasmine-dom/validate.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/validate.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/testing-library/jasmine-dom/validate.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/validate.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/testing-library/jasmine-dom/validate.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/validate.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/testing-library/jasmine-dom/validate.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/validate.yml:36: update your workflow using https://app.stepsecurity.io/secureworkflow/testing-library/jasmine-dom/validate.yml/main?enable=pin","Info:   0 out of   4 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":4,"reason":"Found 6/13 approved changesets -- score normalized to 4","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/validate.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 25 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-24T05:41:45.060Z","repository_id":38095505,"created_at":"2025-08-24T05:41:45.060Z","updated_at":"2025-08-24T05:41:45.060Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30428514,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-12T14:34:45.044Z","status":"ssl_error","status_checked_at":"2026-03-12T14:09:33.793Z","response_time":114,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["testing"],"created_at":"2024-09-24T19:58:41.764Z","updated_at":"2026-03-12T14:39:23.720Z","avatar_url":"https://github.com/testing-library.png","language":"JavaScript","readme":"\u003cdiv align=\"center\"\u003e\n\u003ch1\u003ejasmine-dom\u003c/h1\u003e\n\n\u003ca href=\"https://www.joypixels.com/profiles/emoji/sloth/_/5.0\"\u003e\n  \u003cimg\n    height=\"80\"\n    width=\"80\"\n    alt=\"sloth\"\n    src=\"https://github.com/testing-library/jasmine-dom/blob/main/other/sloth.png?raw=true\"\n  \u003e\n\u003c/a\u003e\n\n\u003cp\u003eCustom Jasmine matchers to test the state of the DOM\u003c/p\u003e\n\n\u003c/div\u003e\n\n---\n\n[![Build Status][build-badge]][build]\n[![Code Coverage][coverage-badge]][coverage]\n[![semantic-release][semantic-release-badge]][semantic-release]\n[![version][version-badge]][package]\n[![downloads][downloads-badge]][npmtrends]\n[![MIT License][license-badge]][license]\n\n\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-7-orange.svg?style=flat-square)](#contributors-)\n\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n\n[![PRs Welcome][prs-badge]][prs]\n[![Code of Conduct][coc-badge]][coc]\n[![Discord][discord-badge]][discord]\n\n[![Watch on GitHub][github-watch-badge]][github-watch]\n[![Star on GitHub][github-star-badge]][github-star]\n[![Tweet][twitter-badge]][twitter]\n\n## The problem\n\nYou want to use [Jasmine][jasmine] to write tests that assert various things about the state of the DOM. As part of that goal, you want to avoid all the repetitive patterns that arise in doing so. Checking for an element's attributes, its text content, its css classes, you name it.\n\n## This solution\n\nThe `jasmine-dom` library provides a set of custom Jasmine matchers that you can use to extend Jasmine. These will make your tests more declarative, clear to read and to maintain.\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Usage](#usage)\n- [Custom matchers](#custom-matchers)\n  - [`toBeDisabled`](#tobedisabled)\n  - [`toBeEnabled`](#tobeenabled)\n  - [`toBeEmptyDOMElement`](#tobeemptydomelement)\n  - [`toBeInTheDocument`](#tobeinthedocument)\n  - [`toBeInvalid`](#tobeinvalid)\n  - [`toBeRequired`](#toberequired)\n  - [`toBeValid`](#tobevalid)\n  - [`toBeVisible`](#tobevisible)\n  - [`toContainHTML`](#tocontainhtml)\n  - [`toContainElement`](#tocontainelement)\n  - [`toHaveAccessibleDescription`](#tohaveaccessibledescription)\n  - [`toHaveAccessibleName`](#tohaveaccessiblename)\n  - [`toHaveAttribute`](#tohaveattribute)\n  - [`toHaveClassName`](#tohaveclassname)\n  - [`toHaveFocus`](#tohavefocus)\n  - [`toHaveFormValues`](#tohaveformvalues)\n  - [`toHaveStyle`](#tohavestyle)\n  - [`toHaveTextContent`](#tohavetextcontent)\n  - [`toHaveValue`](#tohavevalue)\n  - [`toHaveDisplayValue`](#tohavedisplayvalue)\n  - [`toBeChecked`](#tobechecked)\n  - [`toBePartiallyChecked`](#tobepartiallychecked)\n  - [`toHaveErrorMessage`](#tohaveerrormessage)\n  - [`toHaveDescription`](#tohavedescription)\n- [Inspiration](#inspiration)\n- [Other Solutions](#other-solutions)\n- [Guiding Principles](#guiding-principles)\n- [Contributors](#contributors)\n- [LICENSE](#license)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Installation\n\nThis module is distributed via [npm][npm] which is bundled with [node][node] and should be installed as one of your project's `devDependencies`.\n\nUsing npm:\n\n```\nnpm install --save-dev @testing-library/jasmine-dom\n```\n\nor for installation using [yarn][yarn] package manager:\n\n```\nyarn add --dev @testing-library/jasmine-dom\n```\n\n## Usage\n\n### With JavaScript\n\nYou should have a directory for helpers specified inside the `/helpers` array in your `jasmine.json` file, for example:\n\n```json\n{\n\t\"spec_dir\": \"src/__tests__\",\n\t\"spec_files\": [\"**/*.test.js\"],\n\t\"helpers\": [\"helpers/**/*.js\"],\n\t\"stopSpecOnExpectationFailure\": false,\n\t\"random\": false\n}\n```\n\nMake a new file inside that directory, import `@testing-library/jasmine-dom` and add the matchers like so:\n\n```javascript\nimport JasmineDOM from '@testing-library/jasmine-dom';\n\nbeforeAll(() =\u003e {\n\tjasmine.addMatchers(JasmineDOM);\n});\n```\n\n### With TypeScript\n\nInstall the type definitions with:\n\n```\nnpm install --save-dev @types/testing-library__jasmine-dom\n```\n\nAdd `\"@testing-library/jasmine-dom\"` to `/compilerOptions/types` in the tests `tsconfig`, for example:\n\n```json\n{\n\t\"compilerOptions\": {\n\t\t\"types\": [\"jasmine\", \"node\", \"@testing-library/jasmine-dom\"]\n\t}\n}\n```\n\nFollow the [JavaScript instructions](#with-javascript) to add the matchers.\n\n\n### With Angular\n\nFollow the [TypeScript instructions](#with-typescript) to install the type definitions, making sure to include the types in `tsconfig.spec.json`, the configuration file used for the test environment.\n\nAdd the matchers in the test setup file, which is typically located in `src/test.ts`:\n\n```ts\nimport { getTestBed } from '@angular/core/testing';\nimport { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';\nimport JasmineDOM from '@testing-library/jasmine-dom';\n\nbeforeAll(() =\u003e {\n\tjasmine.addMatchers(JasmineDOM);\n});\n\ngetTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting(), {});\n```\n\nIf your project was created with Angular 15 or later, you will not have a test setup file, so you will need to create one. Create a `test.ts` file in `src` with the code shown in the previous step, and then add the path to it in `angular.json` in `/projects/\u003cyour-project\u003e/architect/test/options/main`:\n\n```json\n{\n\t\"projects\": {\n\t\t\"myProject\": {\n\t\t\t\"architect\": {\n\t\t\t\t\"test\": {\n\t\t\t\t\t\"builder\": \"@angular-devkit/build-angular:karma\",\n\t\t\t\t\t\"options\": {\n\t\t\t\t\t\t\"polyfills\": [\"zone.js\", \"zone.js/testing\"],\n\t\t\t\t\t\t\"tsConfig\": \"tsconfig.spec.json\",\n\t\t\t\t\t\t\"assets\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"glob\": \"**/*\",\n\t\t\t\t\t\t\t\t\"input\": \"public\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t],\n\t\t\t\t\t\t\"main\": \"src/test.ts\",\n\t\t\t\t\t\t\"styles\": [\"src/styles.css\"],\n\t\t\t\t\t\t\"scripts\": []\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n```\n\n## Matchers\n\nThis library is meant to be a Jasmine version of `@testing-library/jest-dom` library. As such, it provides the same set of matchers and the same functionality for each one, with a couple of minor diferences:\n\n- `toBeEmpty()` is not included, in favor of `toBeEmptyDOMElement()`\n- `toBeInTheDOM()` is not included, since it's deprecated\n- `toHaveClass()` is renamed as `toHaveClassName()` to prevent name collision with Jasmine's `toHaveClass()`\n\n### `toBeDisabled`\n\n```typescript\ntoBeDisabled();\n```\n\nThis allows you to check whether an element is disabled from the user's\nperspective.\n\nIt matches if the element is a form control and the `disabled` attribute is\nspecified on this element or the element is a descendant of a form element with\na `disabled` attribute.\n\nAccording to the specification, the following elements can be\n[actually disabled](https://html.spec.whatwg.org/multipage/semantics-other.html#disabled-elements):\n`button`, `input`, `select`, `textarea`, `optgroup`, `option`, `fieldset`.\n\n#### Examples\n\n```html\n\u003cbutton data-testid=\"button\" type=\"submit\" disabled\u003esubmit\u003c/button\u003e\n\u003cfieldset disabled\u003e\u003cinput type=\"text\" data-testid=\"input\" /\u003e\u003c/fieldset\u003e\n\u003ca href=\"...\" disabled\u003elink\u003c/a\u003e\n```\n\n```javascript\nexpect(getByTestId('button')).toBeDisabled();\nexpect(getByTestId('input')).toBeDisabled();\nexpect(getByText('link')).not.toBeDisabled();\n```\n\n\u003chr /\u003e\n\n### `toBeEnabled`\n\n```typescript\ntoBeEnabled();\n```\n\nThis allows you to check whether an element is not disabled from the user's\nperspective.\n\nIt works like `not.toBeDisabled()`. Use this matcher to avoid double negation in\nyour tests.\n\n\u003chr /\u003e\n\n### `toBeEmptyDOMElement`\n\n```typescript\ntoBeEmptyDOMElement();\n```\n\nThis allows you to assert whether an element has content or not.\n\n#### Examples\n\n```html\n\u003cspan data-testid=\"not-empty\"\u003e\u003cspan data-testid=\"empty\"\u003e\u003c/span\u003e\u003c/span\u003e\n```\n\n```javascript\nexpect(getByTestId('empty')).toBeEmptyDOMElement();\nexpect(getByTestId('not-empty')).not.toBeEmptyDOMElement();\n```\n\n\u003chr /\u003e\n\n### `toBeInTheDocument`\n\n```typescript\ntoBeInTheDocument();\n```\n\nThis allows you to assert whether an element is present in the document or not.\n\n#### Examples\n\n```html\n\u003cspan data-testid=\"html-element\"\u003e\u003cspan\u003eHtml Element\u003c/span\u003e\u003c/span\u003e \u003csvg data-testid=\"svg-element\"\u003e\u003c/svg\u003e\n```\n\n```javascript\nexpect(getByTestId(document.documentElement, 'html-element')).toBeInTheDocument();\nexpect(getByTestId(document.documentElement, 'svg-element')).toBeInTheDocument();\nexpect(queryByTestId(document.documentElement, 'does-not-exist')).not.toBeInTheDocument();\n```\n\n\u003e Note: This matcher does not find detached elements. The element must be added\n\u003e to the document to be found by toBeInTheDocument. If you desire to search in a\n\u003e detached element please use: [`toContainElement`](#tocontainelement)\n\n\u003chr /\u003e\n\n### `toBeInvalid`\n\n```typescript\ntoBeInvalid();\n```\n\nThis allows you to check if an element, is currently invalid.\n\nAn element is invalid if it has an\n[`aria-invalid` attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-invalid_attribute)\nwith no value or a value of `\"true\"`, or if the result of\n[`checkValidity()`](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation)\nis `false`.\n\n#### Examples\n\n```html\n\u003cinput data-testid=\"no-aria-invalid\" /\u003e\n\u003cinput data-testid=\"aria-invalid\" aria-invalid /\u003e\n\u003cinput data-testid=\"aria-invalid-value\" aria-invalid=\"true\" /\u003e\n\u003cinput data-testid=\"aria-invalid-false\" aria-invalid=\"false\" /\u003e\n\n\u003cform data-testid=\"valid-form\"\u003e\n\t\u003cinput /\u003e\n\u003c/form\u003e\n\n\u003cform data-testid=\"invalid-form\"\u003e\n\t\u003cinput required /\u003e\n\u003c/form\u003e\n```\n\n```javascript\nexpect(getByTestId('no-aria-invalid')).not.toBeInvalid();\nexpect(getByTestId('aria-invalid')).toBeInvalid();\nexpect(getByTestId('aria-invalid-value')).toBeInvalid();\nexpect(getByTestId('aria-invalid-false')).not.toBeInvalid();\n\nexpect(getByTestId('valid-form')).not.toBeInvalid();\nexpect(getByTestId('invalid-form')).toBeInvalid();\n```\n\n\u003chr /\u003e\n\n### `toBeRequired`\n\n```typescript\ntoBeRequired();\n```\n\nThis allows you to check if a form element is currently required.\n\nAn element is required if it is having a `required` or `aria-required=\"true\"`\nattribute.\n\n#### Examples\n\n```html\n\u003cinput data-testid=\"required-input\" required /\u003e\n\u003cinput data-testid=\"aria-required-input\" aria-required=\"true\" /\u003e\n\u003cinput data-testid=\"conflicted-input\" required aria-required=\"false\" /\u003e\n\u003cinput data-testid=\"aria-not-required-input\" aria-required=\"false\" /\u003e\n\u003cinput data-testid=\"optional-input\" /\u003e\n\u003cinput data-testid=\"unsupported-type\" type=\"image\" required /\u003e\n\u003cselect data-testid=\"select\" required\u003e\u003c/select\u003e\n\u003ctextarea data-testid=\"textarea\" required\u003e\u003c/textarea\u003e\n\u003cdiv data-testid=\"supported-role\" role=\"tree\" required\u003e\u003c/div\u003e\n\u003cdiv data-testid=\"supported-role-aria\" role=\"tree\" aria-required=\"true\"\u003e\u003c/div\u003e\n```\n\n```javascript\nexpect(getByTestId('required-input')).toBeRequired();\nexpect(getByTestId('aria-required-input')).toBeRequired();\nexpect(getByTestId('conflicted-input')).toBeRequired();\nexpect(getByTestId('aria-not-required-input')).not.toBeRequired();\nexpect(getByTestId('optional-input')).not.toBeRequired();\nexpect(getByTestId('unsupported-type')).not.toBeRequired();\nexpect(getByTestId('select')).toBeRequired();\nexpect(getByTestId('textarea')).toBeRequired();\nexpect(getByTestId('supported-role')).not.toBeRequired();\nexpect(getByTestId('supported-role-aria')).toBeRequired();\n```\n\n\u003chr /\u003e\n\n### `toBeValid`\n\n```typescript\ntoBeValid();\n```\n\nThis allows you to check if the value of an element, is currently valid.\n\nAn element is valid if it has no\n[`aria-invalid` attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-invalid_attribute)s\nor an attribute value of `\"false\"`. The result of\n[`checkValidity()`](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/HTML5/Constraint_validation)\nmust also be `true` if it's a form element.\n\n#### Examples\n\n```html\n\u003cinput data-testid=\"no-aria-invalid\" /\u003e\n\u003cinput data-testid=\"aria-invalid\" aria-invalid /\u003e\n\u003cinput data-testid=\"aria-invalid-value\" aria-invalid=\"true\" /\u003e\n\u003cinput data-testid=\"aria-invalid-false\" aria-invalid=\"false\" /\u003e\n\n\u003cform data-testid=\"valid-form\"\u003e\n\t\u003cinput /\u003e\n\u003c/form\u003e\n\n\u003cform data-testid=\"invalid-form\"\u003e\n\t\u003cinput required /\u003e\n\u003c/form\u003e\n```\n\n```javascript\nexpect(getByTestId('no-aria-invalid')).toBeValid();\nexpect(getByTestId('aria-invalid')).not.toBeValid();\nexpect(getByTestId('aria-invalid-value')).not.toBeValid();\nexpect(getByTestId('aria-invalid-false')).toBeValid();\n\nexpect(getByTestId('valid-form')).toBeValid();\nexpect(getByTestId('invalid-form')).not.toBeValid();\n```\n\n\u003chr /\u003e\n\n### `toBeVisible`\n\n```typescript\ntoBeVisible();\n```\n\nThis allows you to check if an element is currently visible to the user.\n\nAn element is visible if **all** the following conditions are met:\n\n- it does not have its css property `display` set to `none`\n- it does not have its css property `visibility` set to either `hidden` or\n  `collapse`\n- it does not have its css property `opacity` set to `0`\n- its parent element is also visible (and so on up to the top of the DOM tree)\n- it does not have the\n  [`hidden`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/hidden)\n  attribute\n- if `\u003cdetails /\u003e` it has the `open` attribute\n\n#### Examples\n\n```html\n\u003cdiv data-testid=\"zero-opacity\" style=\"opacity: 0\"\u003eZero Opacity Example\u003c/div\u003e\n\u003cdiv data-testid=\"visibility-hidden\" style=\"visibility: hidden\"\u003eVisibility Hidden Example\u003c/div\u003e\n\u003cdiv data-testid=\"display-none\" style=\"display: none\"\u003eDisplay None Example\u003c/div\u003e\n\u003cdiv style=\"opacity: 0\"\u003e\n\t\u003cspan data-testid=\"hidden-parent\"\u003eHidden Parent Example\u003c/span\u003e\n\u003c/div\u003e\n\u003cdiv data-testid=\"visible\"\u003eVisible Example\u003c/div\u003e\n\u003cdiv data-testid=\"hidden-attribute\" hidden\u003eHidden Attribute Example\u003c/div\u003e\n```\n\n```javascript\nexpect(getByText('Zero Opacity Example')).not.toBeVisible();\nexpect(getByText('Visibility Hidden Example')).not.toBeVisible();\nexpect(getByText('Display None Example')).not.toBeVisible();\nexpect(getByText('Hidden Parent Example')).not.toBeVisible();\nexpect(getByText('Visible Example')).toBeVisible();\nexpect(getByText('Hidden Attribute Example')).not.toBeVisible();\n```\n\n\u003chr /\u003e\n\n### `toContainHTML`\n\n```typescript\ntoContainHTML(htmlText: string)\n```\n\nAssert whether a string representing a HTML element is contained in another\nelement. The string should contain valid html, and not any incomplete html.\n\n#### Examples\n\n```html\n\u003cspan data-testid=\"parent\"\u003e\u003cspan data-testid=\"child\"\u003e\u003c/span\u003e\u003c/span\u003e\n```\n\n```javascript\n// These are valid uses\nexpect(getByTestId('parent')).toContainHTML('\u003cspan data-testid=\"child\"\u003e\u003c/span\u003e');\nexpect(getByTestId('parent')).toContainHTML('\u003cspan data-testid=\"child\" /\u003e');\nexpect(getByTestId('parent')).not.toContainHTML('\u003cbr /\u003e');\n\n// These won't work\nexpect(getByTestId('parent')).toContainHTML('data-testid=\"child\"');\nexpect(getByTestId('parent')).toContainHTML('data-testid');\nexpect(getByTestId('parent')).toContainHTML('\u003c/span\u003e');\n```\n\n\u003e Chances are you probably do not need to use this matcher. We encourage testing\n\u003e from the perspective of how the user perceives the app in a browser. That's\n\u003e why testing against a specific DOM structure is not advised.\n\u003e\n\u003e It could be useful in situations where the code being tested renders html that\n\u003e was obtained from an external source, and you want to validate that that html\n\u003e code was used as intended.\n\u003e\n\u003e It should not be used to check DOM structure that you control. Please use\n\u003e [`toContainElement`](#tocontainelement) instead.\n\n\u003chr /\u003e\n\n### `toContainElement`\n\n```typescript\ntoContainElement(element: HTMLElement | SVGElement | null)\n```\n\nThis allows you to assert whether an element contains another element as a\ndescendant or not.\n\n#### Examples\n\n```html\n\u003cspan data-testid=\"ancestor\"\u003e\u003cspan data-testid=\"descendant\"\u003e\u003c/span\u003e\u003c/span\u003e\n```\n\n```javascript\nconst ancestor = getByTestId('ancestor');\nconst descendant = getByTestId('descendant');\nconst nonExistantElement = getByTestId('does-not-exist');\n\nexpect(ancestor).toContainElement(descendant);\nexpect(descendant).not.toContainElement(ancestor);\nexpect(ancestor).not.toContainElement(nonExistantElement);\n```\n\n\u003chr /\u003e\n\n### `toHaveAccessibleDescription`\n\n```typescript\ntoHaveAccessibleDescription(expectedAccessibleDescription?: string | RegExp)\n```\n\nThis allows you to assert that an element has the expected\n[accessible description](https://w3c.github.io/accname/).\n\nYou can pass the exact string of the expected accessible description, or you can\nmake a partial match passing a regular expression, or by using\n[jasmine.stringContaining](https://jasmine.github.io/api/edge/jasmine#.stringContaining)/[jasmine.stringMatching](https://jasmine.github.io/api/edge/jasmine#.stringMatching).\n\n#### Examples\n\n```html\n\u003ca data-testid=\"link\" href=\"/\" aria-label=\"Home page\" title=\"A link to start over\"\u003eStart\u003c/a\u003e\n\u003ca data-testid=\"extra-link\" href=\"/about\" aria-label=\"About page\"\u003eAbout\u003c/a\u003e\n\u003cimg src=\"avatar.jpg\" data-testid=\"avatar\" alt=\"User profile pic\" /\u003e\n\u003cimg src=\"logo.jpg\" data-testid=\"logo\" alt=\"Company logo\" aria-describedby=\"t1\" /\u003e\n\u003cspan id=\"t1\" role=\"presentation\"\u003eThe logo of Our Company\u003c/span\u003e\n```\n\n```js\nexpect(getByTestId('link')).toHaveAccessibleDescription();\nexpect(getByTestId('link')).toHaveAccessibleDescription('A link to start over');\nexpect(getByTestId('link')).not.toHaveAccessibleDescription('Home page');\nexpect(getByTestId('extra-link')).not.toHaveAccessibleDescription();\nexpect(getByTestId('avatar')).not.toHaveAccessibleDescription();\nexpect(getByTestId('logo')).not.toHaveAccessibleDescription('Company logo');\nexpect(getByTestId('logo')).toHaveAccessibleDescription('The logo of Our Company');\n```\n\n\u003chr /\u003e\n\n### `toHaveAccessibleName`\n\n```typescript\ntoHaveAccessibleName(expectedAccessibleName?: string | RegExp)\n```\n\nThis allows you to assert that an element has the expected\n[accessible name](https://w3c.github.io/accname/). It is useful, for instance,\nto assert that form elements and buttons are properly labelled.\n\nYou can pass the exact string of the expected accessible name, or you can make a\npartial match passing a regular expression, or by using\n[jasmine.stringContaining](https://jasmine.github.io/api/edge/jasmine#.stringContaining)/[jasmine.stringMatching](https://jasmine.github.io/api/edge/jasmine#.stringMatching).\n\n#### Examples\n\n```html\n\u003cimg data-testid=\"img-alt\" src=\"\" alt=\"Test alt\" /\u003e\n\u003cimg data-testid=\"img-empty-alt\" src=\"\" alt=\"\" /\u003e\n\u003csvg data-testid=\"svg-title\"\u003e\u003ctitle\u003eTest title\u003c/title\u003e\u003c/svg\u003e\n\u003cbutton data-testid=\"button-img-alt\"\u003e\u003cimg src=\"\" alt=\"Test\" /\u003e\u003c/button\u003e\n\u003cp\u003e\u003cimg data-testid=\"img-paragraph\" src=\"\" alt=\"\" /\u003e Test content\u003c/p\u003e\n\u003cbutton data-testid=\"svg-button\"\u003e\u003csvg\u003e\u003ctitle\u003eTest\u003c/title\u003e\u003c/svg\u003e\u003c/p\u003e\n\u003cdiv\u003e\u003csvg data-testid=\"svg-without-title\"\u003e\u003c/svg\u003e\u003c/div\u003e\n\u003cinput data-testid=\"input-title\" title=\"test\" /\u003e\n```\n\n```javascript\nexpect(getByTestId('img-alt')).toHaveAccessibleName('Test alt');\nexpect(getByTestId('img-empty-alt')).not.toHaveAccessibleName();\nexpect(getByTestId('svg-title')).toHaveAccessibleName('Test title');\nexpect(getByTestId('button-img-alt')).toHaveAccessibleName();\nexpect(getByTestId('img-paragraph')).not.toHaveAccessibleName();\nexpect(getByTestId('svg-button')).toHaveAccessibleName();\nexpect(getByTestId('svg-without-title')).not.toHaveAccessibleName();\nexpect(getByTestId('input-title')).toHaveAccessibleName();\n```\n\n\u003chr /\u003e\n\n### `toHaveAttribute`\n\n```typescript\ntoHaveAttribute(attr: string, value?: any)\n```\n\nThis allows you to check whether the given element has an attribute or not. You\ncan also optionally check that the attribute has a specific expected value or\npartial match using a RegExp.\n\n#### Examples\n\n```html\n\u003cbutton data-testid=\"ok-button\" type=\"submit\" disabled\u003eok\u003c/button\u003e\n```\n\n```javascript\nconst button = getByTestId('ok-button')\n\nexpect(button).toHaveAttribute('disabled')\nexpect(button).toHaveAttribute('type', 'submit')\nexpect(button).not.toHaveAttribute('type', 'button')\n\nexpect(button).toHaveAttribute('type', /sub/))\nexpect(button).toHaveAttribute('type', /but/))\n```\n\n\u003chr /\u003e\n\n### `toHaveClassName`\n\n```typescript\ntoHaveClassName(...classNames: string[], options?: {exact: boolean})\n```\n\nThis allows you to check whether the given element has certain classes within\nits `class` attribute.\n\nYou must provide at least one class, unless you are asserting that an element\ndoes not have any classes.\n\n#### Examples\n\n```html\n\u003cbutton data-testid=\"delete-button\" class=\"btn extra btn-danger\"\u003eDelete item\u003c/button\u003e\n\u003cbutton data-testid=\"no-classes\"\u003eNo Classes\u003c/button\u003e\n```\n\n```javascript\nconst deleteButton = getByTestId('delete-button');\nconst noClasses = getByTestId('no-classes');\n\nexpect(deleteButton).toHaveClassName('extra');\nexpect(deleteButton).toHaveClassName('btn-danger btn');\nexpect(deleteButton).toHaveClassName('btn-danger', 'btn');\nexpect(deleteButton).not.toHaveClassName('btn-link');\n\nexpect(deleteButton).toHaveClassName('btn-danger extra btn', { exact: true }); // to check if the element has EXACTLY a set of classes\nexpect(deleteButton).not.toHaveClassName('btn-danger extra', { exact: true }); // if it has more than expected it is going to fail\n\nexpect(noClasses).not.toHaveClassName();\n```\n\n\u003chr /\u003e\n\n### `toHaveFocus`\n\n```typescript\ntoHaveFocus();\n```\n\nThis allows you to assert whether an element has focus or not.\n\n#### Examples\n\n```html\n\u003cdiv\u003e\u003cinput type=\"text\" data-testid=\"element-to-focus\" /\u003e\u003c/div\u003e\n```\n\n```javascript\nconst input = getByTestId('element-to-focus');\n\ninput.focus();\nexpect(input).toHaveFocus();\n\ninput.blur();\nexpect(input).not.toHaveFocus();\n```\n\n\u003chr /\u003e\n\n### `toHaveFormValues`\n\n```typescript\ntoHaveFormValues(expectedValues: {\n  [name: string]: any\n})\n```\n\nThis allows you to check if a form or fieldset contains form controls for each\ngiven name, and having the specified value.\n\n\u003e It is important to stress that this matcher can only be invoked on a [form][]\n\u003e or a [fieldset][] element.\n\u003e\n\u003e This allows it to take advantage of the [.elements][] property in `form` and\n\u003e `fieldset` to reliably fetch all form controls within them.\n\u003e\n\u003e This also avoids the possibility that users provide a container that contains\n\u003e more than one `form`, thereby intermixing form controls that are not related,\n\u003e and could even conflict with one another.\n\nThis matcher abstracts away the particularities with which a form control value\nis obtained depending on the type of form control. For instance, `\u003cinput\u003e`\nelements have a `value` attribute, but `\u003cselect\u003e` elements do not. Here's a list\nof all cases covered:\n\n- `\u003cinput type=\"number\"\u003e` elements return the value as a **number**, instead of\n  a string.\n- `\u003cinput type=\"checkbox\"\u003e` elements:\n  - if there's a single one with the given `name` attribute, it is treated as a\n    **boolean**, returning `true` if the checkbox is checked, `false` if\n    unchecked.\n  - if there's more than one checkbox with the same `name` attribute, they are\n    all treated collectively as a single form control, which returns the value\n    as an **array** containing all the values of the selected checkboxes in the\n    collection.\n- `\u003cinput type=\"radio\"\u003e` elements are all grouped by the `name` attribute, and\n  such a group treated as a single form control. This form control returns the\n  value as a **string** corresponding to the `value` attribute of the selected\n  radio button within the group.\n- `\u003cinput type=\"text\"\u003e` elements return the value as a **string**. This also\n  applies to `\u003cinput\u003e` elements having any other possible `type` attribute\n  that's not explicitly covered in different rules above (e.g. `search`,\n  `email`, `date`, `password`, `hidden`, etc.)\n- `\u003cselect\u003e` elements without the `multiple` attribute return the value as a\n  **string** corresponding to the `value` attribute of the selected `option`, or\n  `undefined` if there's no selected option.\n- `\u003cselect multiple\u003e` elements return the value as an **array** containing all\n  the values of the [selected options][].\n- `\u003ctextarea\u003e` elements return their value as a **string**. The value\n  corresponds to their node content.\n\nThe above rules make it easy, for instance, to switch from using a single select\ncontrol to using a group of radio buttons. Or to switch from a multi select\ncontrol, to using a group of checkboxes. The resulting set of form values used\nby this matcher to compare against would be the same.\n\n[selected options]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLSelectElement/selectedOptions\n[form]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement\n[fieldset]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFieldSetElement\n[.elements]: https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/elements\n\n#### Examples\n\n```html\n\u003cform data-testid=\"login-form\"\u003e\n\t\u003cinput type=\"text\" name=\"username\" value=\"jane.doe\" /\u003e\n\t\u003cinput type=\"password\" name=\"password\" value=\"12345678\" /\u003e\n\t\u003cinput type=\"checkbox\" name=\"rememberMe\" checked /\u003e\n\t\u003cbutton type=\"submit\"\u003eSign in\u003c/button\u003e\n\u003c/form\u003e\n```\n\n```javascript\nexpect(getByTestId('login-form')).toHaveFormValues({\n\tusername: 'jane.doe',\n\trememberMe: true,\n});\n```\n\n### `toHaveStyle`\n\n```typescript\ntoHaveStyle(css: string | object)\n```\n\nThis allows you to check if a certain element has some specific css properties\nwith specific values applied. It matches only if the element has _all_ the\nexpected properties applied, not just some of them.\n\n#### Examples\n\n```html\n\u003cbutton data-testid=\"delete-button\" style=\"display: none; background-color: red\"\u003eDelete item\u003c/button\u003e\n```\n\n```javascript\nconst button = getByTestId('delete-button');\n\nexpect(button).toHaveStyle('display: none');\nexpect(button).toHaveStyle({ display: 'none' });\nexpect(button).toHaveStyle(`\n  background-color: red;\n  display: none;\n`);\nexpect(button).toHaveStyle({\n\tbackgroundColor: 'red',\n\tdisplay: 'none',\n});\nexpect(button).not.toHaveStyle(`\n  background-color: blue;\n  display: none;\n`);\nexpect(button).not.toHaveStyle({\n\tbackgroundColor: 'blue',\n\tdisplay: 'none',\n});\n```\n\nThis also works with rules that are applied to the element via a class name for\nwhich some rules are defined in a stylesheet currently active in the document.\nThe usual rules of css precedence apply.\n\n\u003chr /\u003e\n\n### `toHaveTextContent`\n\n```typescript\ntoHaveTextContent(text: string | RegExp, options?: {normalizeWhitespace: boolean})\n```\n\nThis allows you to check whether the given element has a text content or not.\n\nWhen a `string` argument is passed through, it will perform a partial\ncase-sensitive match to the element content.\n\nTo perform a case-insensitive match, you can use a `RegExp` with the `/i`\nmodifier.\n\nIf you want to match the whole content, you can use a `RegExp` to do it.\n\n#### Examples\n\n```html\n\u003cspan data-testid=\"text-content\"\u003eText Content\u003c/span\u003e\n```\n\n```javascript\nconst element = getByTestId('text-content');\n\nexpect(element).toHaveTextContent('Content');\nexpect(element).toHaveTextContent(/^Text Content$/); // to match the whole content\nexpect(element).toHaveTextContent(/content$/i); // to use case-insensitive match\nexpect(element).not.toHaveTextContent('content');\n```\n\n\u003chr /\u003e\n\n### `toHaveValue`\n\n```typescript\ntoHaveValue(value: string | string[] | number)\n```\n\nThis allows you to check whether the given form element has the specified value.\nIt accepts `\u003cinput\u003e`, `\u003cselect\u003e` and `\u003ctextarea\u003e` elements with the exception of\n`\u003cinput type=\"checkbox\"\u003e` and `\u003cinput type=\"radio\"\u003e`, which can be meaningfully\nmatched only using [`toBeChecked`](#tobechecked) or\n[`toHaveFormValues`](#tohaveformvalues).\n\nFor all other form elements, the value is matched using the same algorithm as in\n[`toHaveFormValues`](#tohaveformvalues) does.\n\n#### Examples\n\n```html\n\u003cinput type=\"text\" value=\"text\" data-testid=\"input-text\" /\u003e\n\u003cinput type=\"number\" value=\"5\" data-testid=\"input-number\" /\u003e\n\u003cinput type=\"text\" data-testid=\"input-empty\" /\u003e\n\u003cselect data-testid=\"multiple\" multiple data-testid=\"select-number\"\u003e\n\t\u003coption value=\"first\"\u003eFirst Value\u003c/option\u003e\n\t\u003coption value=\"second\" selected\u003eSecond Value\u003c/option\u003e\n\t\u003coption value=\"third\" selected\u003eThird Value\u003c/option\u003e\n\u003c/select\u003e\n```\n\n##### Using DOM Testing Library\n\n```javascript\nconst textInput = screen.getByTestId('input-text');\nconst numberInput = screen.getByTestId('input-number');\nconst emptyInput = screen.getByTestId('input-empty');\nconst selectInput = screen.getByTestId('select-number');\n\nexpect(textInput).toHaveValue('text');\nexpect(numberInput).toHaveValue(5);\nexpect(emptyInput).not.toHaveValue();\nexpect(selectInput).not.toHaveValue(['second', 'third']);\n```\n\n\u003chr /\u003e\n\n### `toHaveDisplayValue`\n\n```typescript\ntoHaveDisplayValue(value: string | RegExp | (string|RegExp)[])\n```\n\nThis allows you to check whether the given form element has the specified\ndisplayed value (the one the end user will see). It accepts `\u003cinput\u003e`,\n`\u003cselect\u003e` and `\u003ctextarea\u003e` elements with the exception of\n`\u003cinput type=\"checkbox\"\u003e` and `\u003cinput type=\"radio\"\u003e`, which can be meaningfully\nmatched only using [`toBeChecked`](#tobechecked) or\n[`toHaveFormValues`](#tohaveformvalues).\n\n#### Examples\n\n```html\n\u003clabel for=\"input-example\"\u003eFirst name\u003c/label\u003e\n\u003cinput type=\"text\" id=\"input-example\" value=\"Luca\" /\u003e\n\n\u003clabel for=\"textarea-example\"\u003eDescription\u003c/label\u003e\n\u003ctextarea id=\"textarea-example\"\u003eAn example description here.\u003c/textarea\u003e\n\n\u003clabel for=\"single-select-example\"\u003eFruit\u003c/label\u003e\n\u003cselect id=\"single-select-example\"\u003e\n\t\u003coption value=\"\"\u003eSelect a fruit...\u003c/option\u003e\n\t\u003coption value=\"banana\"\u003eBanana\u003c/option\u003e\n\t\u003coption value=\"ananas\"\u003eAnanas\u003c/option\u003e\n\t\u003coption value=\"avocado\"\u003eAvocado\u003c/option\u003e\n\u003c/select\u003e\n\n\u003clabel for=\"mutiple-select-example\"\u003eFruits\u003c/label\u003e\n\u003cselect id=\"multiple-select-example\" multiple\u003e\n\t\u003coption value=\"\"\u003eSelect a fruit...\u003c/option\u003e\n\t\u003coption value=\"banana\" selected\u003eBanana\u003c/option\u003e\n\t\u003coption value=\"ananas\"\u003eAnanas\u003c/option\u003e\n\t\u003coption value=\"avocado\" selected\u003eAvocado\u003c/option\u003e\n\u003c/select\u003e\n```\n\n##### Using DOM Testing Library\n\n```javascript\nconst input = screen.getByLabelText('First name');\nconst textarea = screen.getByLabelText('Description');\nconst selectSingle = screen.getByLabelText('Fruit');\nconst selectMultiple = screen.getByLabelText('Fruits');\n\nexpect(input).toHaveDisplayValue('Luca');\nexpect(input).toHaveDisplayValue(/Luc/);\nexpect(textarea).toHaveDisplayValue('An example description here.');\nexpect(textarea).toHaveDisplayValue(/example/);\nexpect(selectSingle).toHaveDisplayValue('Select a fruit...');\nexpect(selectSingle).toHaveDisplayValue(/Select/);\nexpect(selectMultiple).toHaveDisplayValue([/Avocado/, 'Banana']);\n```\n\n\u003chr /\u003e\n\n### `toBeChecked`\n\n```typescript\ntoBeChecked();\n```\n\nThis allows you to check whether the given element is checked. It accepts an\n`input` of type `checkbox` or `radio` and elements with a `role` of `checkbox`,\n`radio` or `switch` with a valid `aria-checked` attribute of `\"true\"` or\n`\"false\"`.\n\n#### Examples\n\n```html\n\u003cinput type=\"checkbox\" checked data-testid=\"input-checkbox-checked\" /\u003e\n\u003cinput type=\"checkbox\" data-testid=\"input-checkbox-unchecked\" /\u003e\n\u003cdiv role=\"checkbox\" aria-checked=\"true\" data-testid=\"aria-checkbox-checked\" /\u003e\n\u003cdiv role=\"checkbox\" aria-checked=\"false\" data-testid=\"aria-checkbox-unchecked\" /\u003e\n\n\u003cinput type=\"radio\" checked value=\"foo\" data-testid=\"input-radio-checked\" /\u003e\n\u003cinput type=\"radio\" value=\"foo\" data-testid=\"input-radio-unchecked\" /\u003e\n\u003cdiv role=\"radio\" aria-checked=\"true\" data-testid=\"aria-radio-checked\" /\u003e\n\u003cdiv role=\"radio\" aria-checked=\"false\" data-testid=\"aria-radio-unchecked\" /\u003e\n\u003cdiv role=\"switch\" aria-checked=\"true\" data-testid=\"aria-switch-checked\" /\u003e\n\u003cdiv role=\"switch\" aria-checked=\"false\" data-testid=\"aria-switch-unchecked\" /\u003e\n```\n\n```javascript\nconst inputCheckboxChecked = getByTestId('input-checkbox-checked');\nconst inputCheckboxUnchecked = getByTestId('input-checkbox-unchecked');\nconst ariaCheckboxChecked = getByTestId('aria-checkbox-checked');\nconst ariaCheckboxUnchecked = getByTestId('aria-checkbox-unchecked');\nexpect(inputCheckboxChecked).toBeChecked();\nexpect(inputCheckboxUnchecked).not.toBeChecked();\nexpect(ariaCheckboxChecked).toBeChecked();\nexpect(ariaCheckboxUnchecked).not.toBeChecked();\n\nconst inputRadioChecked = getByTestId('input-radio-checked');\nconst inputRadioUnchecked = getByTestId('input-radio-unchecked');\nconst ariaRadioChecked = getByTestId('aria-radio-checked');\nconst ariaRadioUnchecked = getByTestId('aria-radio-unchecked');\nexpect(inputRadioChecked).toBeChecked();\nexpect(inputRadioUnchecked).not.toBeChecked();\nexpect(ariaRadioChecked).toBeChecked();\nexpect(ariaRadioUnchecked).not.toBeChecked();\n\nconst ariaSwitchChecked = getByTestId('aria-switch-checked');\nconst ariaSwitchUnchecked = getByTestId('aria-switch-unchecked');\nexpect(ariaSwitchChecked).toBeChecked();\nexpect(ariaSwitchUnchecked).not.toBeChecked();\n```\n\n\u003chr /\u003e\n\n### `toBePartiallyChecked`\n\n```typescript\ntoBePartiallyChecked();\n```\n\nThis allows you to check whether the given element is partially checked. It\naccepts an `input` of type `checkbox` and elements with a `role` of `checkbox`\nwith a `aria-checked=\"mixed\"`, or `input` of type `checkbox` with\n`indeterminate` set to `true`\n\n#### Examples\n\n```html\n\u003cinput type=\"checkbox\" aria-checked=\"mixed\" data-testid=\"aria-checkbox-mixed\" /\u003e\n\u003cinput type=\"checkbox\" checked data-testid=\"input-checkbox-checked\" /\u003e\n\u003cinput type=\"checkbox\" data-testid=\"input-checkbox-unchecked\" /\u003e\n\u003cdiv role=\"checkbox\" aria-checked=\"true\" data-testid=\"aria-checkbox-checked\" /\u003e\n\u003cdiv role=\"checkbox\" aria-checked=\"false\" data-testid=\"aria-checkbox-unchecked\" /\u003e\n\u003cinput type=\"checkbox\" data-testid=\"input-checkbox-indeterminate\" /\u003e\n```\n\n```javascript\nconst ariaCheckboxMixed = getByTestId('aria-checkbox-mixed');\nconst inputCheckboxChecked = getByTestId('input-checkbox-checked');\nconst inputCheckboxUnchecked = getByTestId('input-checkbox-unchecked');\nconst ariaCheckboxChecked = getByTestId('aria-checkbox-checked');\nconst ariaCheckboxUnchecked = getByTestId('aria-checkbox-unchecked');\nconst inputCheckboxIndeterminate = getByTestId('input-checkbox-indeterminate');\n\nexpect(ariaCheckboxMixed).toBePartiallyChecked();\nexpect(inputCheckboxChecked).not.toBePartiallyChecked();\nexpect(inputCheckboxUnchecked).not.toBePartiallyChecked();\nexpect(ariaCheckboxChecked).not.toBePartiallyChecked();\nexpect(ariaCheckboxUnchecked).not.toBePartiallyChecked();\n\ninputCheckboxIndeterminate.indeterminate = true;\nexpect(inputCheckboxIndeterminate).toBePartiallyChecked();\n```\n\n\u003chr /\u003e\n\n### `toHaveErrorMessage`\n\n```typescript\ntoHaveErrorMessage(text: string | RegExp)\n```\n\nThis allows you to check whether the given element has an\n[ARIA error message](https://www.w3.org/TR/wai-aria/#aria-errormessage) or not.\n\nUse the `aria-errormessage` attribute to reference another element that contains\ncustom error message text. Multiple ids is **NOT** allowed. Authors MUST use\n`aria-invalid` in conjunction with `aria-errormessage`. Learn more from\n[`aria-errormessage` spec](https://www.w3.org/TR/wai-aria/#aria-errormessage).\n\nWhitespace is normalized.\n\nWhen a `string` argument is passed through, it will perform a whole\ncase-sensitive match to the error message text.\n\nTo perform a case-insensitive match, you can use a `RegExp` with the `/i`\nmodifier.\n\nTo perform a partial match, you can pass a `RegExp` or use\n`jasmine.stringContaining(\"partial string\")`.\n\n#### Examples\n\n```html\n\u003clabel for=\"startTime\"\u003e Please enter a start time for the meeting: \u003c/label\u003e\n\u003cinput id=\"startTime\" type=\"text\" aria-errormessage=\"msgID\" aria-invalid=\"true\" value=\"11:30 PM\" /\u003e\n\u003cspan id=\"msgID\" aria-live=\"assertive\" style=\"visibility:visible\"\u003e\n\tInvalid time: the time must be between 9:00 AM and 5:00 PM\n\u003c/span\u003e\n```\n\n```javascript\nconst timeInput = getByLabel('startTime');\n\nexpect(timeInput).toHaveErrorMessage('Invalid time: the time must be between 9:00 AM and 5:00 PM');\nexpect(timeInput).toHaveErrorMessage(/invalid time/i); // to partially match\nexpect(timeInput).toHaveErrorMessage(jasmine.stringContaining('Invalid time')); // to partially match\nexpect(timeInput).not.toHaveErrorMessage('Pikachu!');\n```\n\n\u003chr /\u003e\n\n### `toHaveDescription`\n\n```typescript\ntoHaveDescription(text: string | RegExp)\n```\n\nThis allows you to check whether the given element has a description or not.\n\nAn element gets its description via the\n[`aria-describedby` attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-describedby_attribute).\nSet this to the `id` of one or more other elements. These elements may be nested\ninside, be outside, or a sibling of the passed in element.\n\nWhitespace is normalized. Using multiple ids will\n[join the referenced elements’ text content separated by a space](https://www.w3.org/TR/accname-1.1/#mapping_additional_nd_description).\n\nWhen a `string` argument is passed through, it will perform a whole\ncase-sensitive match to the description text.\n\nTo perform a case-insensitive match, you can use a `RegExp` with the `/i`\nmodifier.\n\nTo perform a partial match, you can pass a `RegExp`.\n\n#### Examples\n\n```html\n\u003cbutton aria-label=\"Close\" aria-describedby=\"description-close\"\u003eX\u003c/button\u003e\n\u003cdiv id=\"description-close\"\u003eClosing will discard any changes\u003c/div\u003e\n\n\u003cbutton\u003eDelete\u003c/button\u003e\n```\n\n```javascript\nconst closeButton = getByRole('button', { name: 'Close' });\n\nexpect(closeButton).toHaveDescription('Closing will discard any changes');\nexpect(closeButton).toHaveDescription(/will discard/); // to partially match\nexpect(closeButton).toHaveDescription(/^closing/i); // to use case-insensitive match\nexpect(closeButton).not.toHaveDescription('Other description');\n\nconst deleteButton = getByRole('button', { name: 'Delete' });\nexpect(deleteButton).not.toHaveDescription();\nexpect(deleteButton).toHaveDescription(''); // Missing or empty description always becomes a blank string\n```\n\n## Inspiration\n\nThis library was heavily inspired by [testing-library][testing-library] being [jest-dom][jest-dom] a part of its ecosystem, and [Kent C. Dodds'][kentcdodds] guiding principles.\n\nThe intention is to make these matchers available to developers using Jasmine instead of Jest.\n\n## Other Solutions\n\nI'm not aware of any, if you are please do make a PR and add it here!\n\nFor extending Jasmine's matchers outside the realm of DOM testing, [Jasmine-Matchers](https://github.com/JamieMason/Jasmine-Matchers) is an option.\n\n## Guiding Principles\n\n\u003e [The more your tests resemble the way your software is used, the more confidence they can give you][guiding-principle]\n\n## Contributors\n\nThanks goes to these people ([emoji key][emojis])\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://kentcdodds.com\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/1500684?v=3?s=100\" width=\"100px;\" alt=\"Kent C. Dodds\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eKent C. Dodds\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#infra-kentcdodds\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/brrianalexis\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/51463930?v=4?s=100\" width=\"100px;\" alt=\"Brian Alexis\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBrian Alexis\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#ideas-brrianalexis\" title=\"Ideas, Planning, \u0026 Feedback\"\u003e🤔\u003c/a\u003e \u003ca href=\"https://github.com/testing-library/jasmine-dom/commits?author=brrianalexis\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/testing-library/jasmine-dom/commits?author=brrianalexis\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"https://github.com/testing-library/jasmine-dom/commits?author=brrianalexis\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/IanGrainger\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/559336?v=4?s=100\" width=\"100px;\" alt=\"IanGrainger\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eIanGrainger\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/testing-library/jasmine-dom/commits?author=IanGrainger\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://michaeldeboey.be\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/6643991?v=4?s=100\" width=\"100px;\" alt=\"Michaël De Boey\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eMichaël De Boey\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#infra-MichaelDeBoey\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://nickmccurdy.com/\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/927220?v=4?s=100\" width=\"100px;\" alt=\"Nick McCurdy\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eNick McCurdy\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#infra-nickmccurdy\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"http://www.orilivni.com\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/2685242?v=4?s=100\" width=\"100px;\" alt=\"Ori Livni\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eOri Livni\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/testing-library/jasmine-dom/commits?author=oriSomething\" title=\"Code\"\u003e💻\u003c/a\u003e \u003ca href=\"https://github.com/testing-library/jasmine-dom/commits?author=oriSomething\" title=\"Tests\"\u003e⚠️\u003c/a\u003e\u003c/td\u003e\n      \u003ctd align=\"center\" valign=\"top\" width=\"14.28%\"\u003e\u003ca href=\"https://github.com/sebastian-altamirano\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/38230545?v=4?s=100\" width=\"100px;\" alt=\"Sebastián Altamirano\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eSebastián Altamirano\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/testing-library/jasmine-dom/commits?author=sebastian-altamirano\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors][all-contributors] specification.\nContributions of any kind are welcome!\n\n## LICENSE\n\nMIT\n\n[jasmine]: https://jasmine.github.io/\n[jest-dom]: https://testing-library.com/docs/ecosystem-jest-dom\n[kentcdodds]: https://kentcdodds.com/\n[npm]: https://www.npmjs.com/\n[node]: https://nodejs.org\n[testing-library]: https://testing-library.com/\n[yarn]: https://yarnpkg.com\n\n\u003c!-- BADGES --\u003e\n\n[build-badge]: https://img.shields.io/github/workflow/status/testing-library/jasmine-dom/validate?logo=github\u0026style=flat-square\n[build]: https://github.com/testing-library/jasmine-dom/actions?query=workflow%3Avalidate\n[coverage-badge]: https://codecov.io/gh/testing-library/jasmine-dom/branch/main/graph/badge.svg\n[coverage]: https://codecov.io/gh/testing-library/jasmine-dom\n[version-badge]: https://img.shields.io/npm/v/@testing-library/jasmine-dom?style=flat-square\n[semantic-release-badge]: https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg\n[semantic-release]: https://github.com/semantic-release/semantic-release\n[package]: https://www.npmjs.com/package/@testing-library/jasmine-dom\n[downloads-badge]: https://img.shields.io/npm/dm/@testing-library/jasmine-dom?style=flat-square\n[npmtrends]: http://www.npmtrends.com/@testing-library/jasmine-dom\n[license-badge]: https://img.shields.io/npm/l/@testing-library/jasmine-dom?style=flat-square\n[license]: https://github.com/testing-library/jasmine-dom/blob/main/LICENSE\n[prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square\n[prs]: http://makeapullrequest.com\n[coc-badge]: https://img.shields.io/badge/code%20of-conduct-ff69b4.svg?style=flat-square\n[coc]: https://github.com/testing-library/jasmine-dom/blob/main/other/CODE_OF_CONDUCT.md\n[github-watch-badge]: https://img.shields.io/github/watchers/testing-library/jasmine-dom?style=social\n[github-watch]: https://github.com/testing-library/jasmine-dom/watchers\n[github-star-badge]: https://img.shields.io/github/stars/testing-library/jasmine-dom?style=social\n[github-star]: https://github.com/testing-library/jasmine-dom/stargazers\n[twitter]: https://twitter.com/intent/tweet?text=Check%20out%20jasmine-dom%20by%20%40brrianalexis%20https%3A%2F%2Fgithub.com%2Ftesting-library%2Fjasmine-dom%20%F0%9F%91%8D\n[twitter-badge]: https://img.shields.io/twitter/url?style=social\u0026url=https%3A%2F%2Fgithub.com%2Ftesting-library%2Fjasmine-dom\n[emojis]: https://allcontributors.org/docs/en/emoji-key\n[all-contributors]: https://github.com/all-contributors/all-contributors\n[all-contributors-badge]: https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square\n[guiding-principle]: https://testing-library.com/docs/guiding-principles\n[discord-badge]: https://img.shields.io/discord/723559267868737556.svg?color=7389D8\u0026labelColor=6A7EC2\u0026logo=discord\u0026logoColor=ffffff\u0026style=flat-square\n[discord]: https://discord.gg/testing-library\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftesting-library%2Fjasmine-dom","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftesting-library%2Fjasmine-dom","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftesting-library%2Fjasmine-dom/lists"}