{"id":13727117,"url":"https://github.com/testing-library/playwright-testing-library","last_synced_at":"2025-04-09T13:10:18.325Z","repository":{"id":37067893,"uuid":"267168962","full_name":"testing-library/playwright-testing-library","owner":"testing-library","description":"🔍 Find elements in Playwright with queries from Testing Library","archived":false,"fork":false,"pushed_at":"2023-05-24T22:00:15.000Z","size":4210,"stargazers_count":248,"open_issues_count":22,"forks_count":9,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-10-29T17:41:09.984Z","etag":null,"topics":["dom-testing-library","integration-testing","jest","playwright","testing-library"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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}},"created_at":"2020-05-26T22:55:09.000Z","updated_at":"2024-10-06T09:44:27.000Z","dependencies_parsed_at":"2024-04-12T11:23:01.084Z","dependency_job_id":"7ffea9a4-1440-4a81-acdb-b8c6d639829c","html_url":"https://github.com/testing-library/playwright-testing-library","commit_stats":{"total_commits":360,"total_committers":13,"mean_commits":"27.692307692307693","dds":0.7083333333333333,"last_synced_commit":"5c11987a4e9df7abf6b6e6f1d7076404028ccbce"},"previous_names":["hoverinc/playwright-testing-library"],"tags_count":56,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testing-library%2Fplaywright-testing-library","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testing-library%2Fplaywright-testing-library/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testing-library%2Fplaywright-testing-library/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/testing-library%2Fplaywright-testing-library/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/testing-library","download_url":"https://codeload.github.com/testing-library/playwright-testing-library/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247685757,"owners_count":20979119,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["dom-testing-library","integration-testing","jest","playwright","testing-library"],"created_at":"2024-08-03T01:03:40.163Z","updated_at":"2025-04-09T13:10:18.302Z","avatar_url":"https://github.com/testing-library.png","language":"TypeScript","readme":"\u003e 😲 **Heads up** — Playwright introduced native Testing Library queries in version **[1.27](https://playwright.dev/docs/release-notes#locators)**.\n\u003e\n\u003e 💬 [**#558**](https://github.com/testing-library/playwright-testing-library/issues/558) ← We're discussing what this means for Playwright Testing Library in [this issue](https://github.com/testing-library/playwright-testing-library/issues/558). You can find a more detailed comparison of the new Playwright API and this library [here](https://github.com/testing-library/playwright-testing-library/issues/558#issuecomment-1273969028). Please ask any questions you may have or share thoughts and suggestions!\n\n\u003cbr\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003cbr\u003e\n  \u003cheader\u003e\n    \u003cimg src=\"https://user-images.githubusercontent.com/288160/126050717-dd76eb80-ef06-40e0-97e8-72c20c9f8f20.png\" height=\"64\" /\u003e\n  \u003c/header\u003e\n  \u003cbr\u003e\n  \u003ch1\u003eplaywright-testing-library\u003c/h1\u003e\n  \u003cp\u003e🔍 Find elements in \u003cstrong\u003eplaywright\u003c/strong\u003e like your users  with queries from \u003cstrong\u003e@testing-library/dom\u003c/strong\u003e\u003c/p\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![Build Status][build-badge]][build-link]\n[![Test Coverage][codecov-badge]][codecov-link]\n[![Code Style][prettier-badge]][prettier-link]\n[![Package Version][npm-badge]][npm-link] \u003cbr\u003e\n[![MIT License][license-badge]][license-link]\n[![Conventional Commits][conventional-commits-badge]][conventional-commits-link]\n[![Maintenance][maintenance-badge]][maintenance-link]\n\n\u003c/div\u003e\n\n\u003cbr\u003e\n\n## 🎛 Features\n\nAll of your favorite user-centric querying functions from **@testing-library/react** and **@testing-library/dom** available from within Playwright!\n\n- Test [fixture](https://playwright.dev/docs/test-fixtures) for **@playwright/test** via **@playwright-testing-library/test**\n  - ✨ **New** — `Locator` queries fixture (`locatorFixtures`) [↓](#playwright-test-fixture)\n  - `ElementHandle` queries fixture (`fixtures`) [↓](#legacy-playwright-test-fixture)\n- Standalone queries for **playwright** via **playwright-testing-library**\n  - `ElementHandle` queries (`getDocument` + `queries`) [↓](#standalone-playwright-queries)\n  - Asynchronous `waitFor` assertion helper (via **[wait-for-expect](https://github.com/TheBrainFamily/wait-for-expect)**)\n\n## 🌱 Installation\n\n```bash\n# For use with Playwright Test (@playwright/test)\nnpm install --save-dev @playwright-testing-library/test\n\n# For use with Playwright (playwright)\nnpm install --save-dev playwright-testing-library\n```\n\n## 📝 Usage\n\nThere are currently a few different ways to use Playwright Testing Library, depending on how you use Playwright. However, the recommended approach is to use the `Locator` [queries fixture](#playwright-test-fixture) with Playwright Test (**@playwright/test**).\n\n\u003e ⚠️ The `ElementHandle` query APIs were created before Playwright introduced its `Locator` API and will be replaced in the next major version of Playwright Testing Library. If you can't use **@playwright/test** at the moment, you'll need to use the `ElementHandle` query API, but a migration path will be provided when we switch to the new `Locator` APIs.\n\n### Playwright Test Fixture\n\n\u003e 🔖 Added in [**4.4.0**](https://github.com/testing-library/playwright-testing-library/releases/tag/v4.4.0)\n\nUsing the `Locator` Playwright Test (**@playwright/test**) fixture with **@playwright-testing-library/test**.\n\n#### Setup\n\n```ts\nimport {test as base} from '@playwright/test'\nimport {\n  locatorFixtures as fixtures,\n  LocatorFixtures as TestingLibraryFixtures,\n} from '@playwright-testing-library/test/fixture'\n\nconst test = base.extend\u003cTestingLibraryFixtures\u003e(fixtures)\n\nconst {expect} = test\n\ntest('my form', async ({screen, within}) =\u003e {\n  // Screen provides `Locator` queries scoped to current Playwright `Page`\n  const formLocator = screen.getByTestId('my-form')\n\n  // Scope queries to `Locator` with `within`\n  // (note that this is a fixture from `test`, not the `within` import)\n  const emailInputLocator = within(formLocator).getByLabelText('Email')\n\n  // Interact via `Locator` API 🥳\n  await emailInputLocator.fill('email@playwright.dev')\n  await emailInputLocator.press('Enter')\n\n  // Screen also provides Playwright's `Page` API\n  screen.goto('/account')\n\n  const emailLocator = screen.getByRole('heading', {level: 2})\n\n  // Assert via `Locator` APIs 🎉\n  await expect(emailLocator).toHaveText('email@playwright.dev')\n})\n```\n\n#### Async Methods\n\nThe `findBy` queries work the same way as they do in [Testing Library](https://testing-library.com/docs/dom-testing-library/api-async) core in that they return `Promise\u003cLocator\u003e` and are intended to be used to defer test execution until an element appears on the page.\n\n```ts\ntest('my modal', async ({screen, within}) =\u003e {\n  // Here we wait for a modal to appear asynchronously before continuing\n  // Note: the timeout for `findBy` queries is configured with `asyncUtilTimeout`\n  const modalLocator = await screen.findByRole('dialog')\n\n  // Once the modal is visible, we can interact with its contents and assert\n  await expect(modalLocator).toHaveText(/My Modal/)\n  await within(modalLocator).getByRole('button', {name: 'Okay'}).click()\n\n  // We can also use `queryBy` methods to take advantage of Playwright's `Locator` auto-waiting\n  // See: https://playwright.dev/docs/actionability\n  // Note: this will use Playwright's timeout, not `asyncUtilTimeout`\n  await expect(screen.queryByRole('dialog')).toBeHidden()\n})\n```\n\n#### Chaining\n\n\u003e 🔖 Added in [**4.5.0**](https://github.com/testing-library/playwright-testing-library/releases/tag/v4.5.0)\n\nAs an alternative to the `within(locator: Locator)` function you're familiar with from Testing Library, Playwright Testing Library also supports chaining queries together.\n\nAll synchronous queries (`get*` + `query*`) return `Locator` instances augmented with a `.within()` method (`TestingLibraryLocator`). All asynchronous queries (`find*`) return a special `LocatorPromise` that also supports `.within()`. This makes it possible to chain queries, including chaining `get*`, `query*` and `find*` interchangeably.\n\n\u003e ⚠️ Note that including any `find*` query in the chain will make the entire chain asynchronous\n\n##### Synchronous\n\n```ts\ntest('chaining synchronous queries', async ({screen}) =\u003e {\n  const locator = screen.getByRole('figure').within().findByRole('img')\n\n  expect(await locator.getAttribute('alt')).toEqual('Some image')\n})\n```\n\n##### Synchronous + Asynchronous\n\n```ts\ntest('chaining synchronous queries + asynchronous queries', ({screen}) =\u003e {\n  //              ↓↓↓↓↓ including any `find*` queries makes the whole chain asynchronous\n  const locator = await screen\n    .getByTestId('modal-container') // Get \"modal container\" or throw (sync)\n    .within()\n    .findByRole('dialog') // Wait for modal to appear (async, until `asyncUtilTimeout`)\n    .within()\n    .getByRole('button', {name: 'Close'}) // Get close button within modal (sync)\n\n  expect(await locator.textContent()).toEqual('Close')\n})\n```\n\n#### Configuration\n\nThe `Locator` query API is configured using Playwright's `use` API. See Playwright's documentation for [global](https://playwright.dev/docs/api/class-testconfig#test-config-use), [project](https://playwright.dev/docs/api/class-testproject#test-project-use), and [test](https://playwright.dev/docs/api/class-test#test-use).\n\n##### Global\n\nConfiguring Testing Library globally in `playwright.config.ts`\n\n```ts\nimport type {PlaywrightTestConfig} from '@playwright/test'\n\nconst config: PlaywrightTestConfig = {\n  use: {\n    // These are the defaults\n    testIdAttribute: 'data-testid',\n    asyncUtilTimeout: 1000,\n    asyncUtilExpectedState: 'visible',\n  },\n}\n\nexport default config\n```\n\n##### Local\n\nScoping Testing Library configuration to test suites or `describe` blocks\n\n```ts\nimport {test as base} from '@playwright/test'\nimport {\n  locatorFixtures as fixtures,\n  LocatorFixtures as TestingLibraryFixtures,\n} from '@playwright-testing-library/test/fixture'\n\nconst test = base.extend\u003cTestingLibraryFixtures\u003e(fixtures)\n\nconst {describe, expect, use} = test\n\n// Entire test suite\nuse({testIdAttribute: 'data-custom-test-id'})\n\ndescribe(() =\u003e {\n  // Specific block\n  use({\n    testIdAttribute: 'some-other-test-id',\n    asyncUtilsTimeout: 5000,\n    asyncUtilExpectedState: 'attached',\n  })\n\n  test('my form', async ({screen}) =\u003e {\n    // ...\n  })\n})\n```\n\n### Legacy Playwright Test Fixture\n\nUsing the `ElementHandle` Playwright Test (**@playwright/test**) fixture with **@playwright-testing-library/test**.\n\n\u003e ⚠️ See note in [Usage](#-usage) as you should be using the `Locator` fixture if possible\n\n#### Setup\n\n```ts\nimport {test as base} from '@playwright/test'\nimport {fixtures, within, TestingLibraryFixtures} from '@playwright-testing-library/test/fixture'\n\nconst test = base.extend\u003cTestingLibraryFixtures\u003e(fixtures)\n\nconst {expect} = test\n\ntest('my form', async ({page, queries}) =\u003e {\n  // Query methods are available in `test` blocks\n  const formHandle = await queries.getByTestId('my-form')\n\n  // Scope queries to an `ElementHandle` with `within`\n  const emailInputHandle = await within(formHandle).getByLabelText('Email')\n\n  // Interact via `ElementHandle` API\n  await emailInputHandle.fill('email@playwright.dev')\n  await emailInputHandle.press('Enter')\n\n  page.goto('/account')\n\n  const emailHandle = queries.getByRole('heading', {level: 2})\n\n  // Assert via `ElementHandle` APIs\n  expect(await emailHandle.textContent()).toEqual('email@playwright.dev')\n})\n```\n\n#### Configuration\n\n```ts\nimport {test as base} from '@playwright/test'\nimport {\n  configure,\n  fixtures,\n  within,\n  TestingLibraryFixtures,\n} from '@playwright-testing-library/test/fixture'\n\nconst test = base.extend\u003cTestingLibraryFixtures\u003e(fixtures)\n\nconst {beforeEach, describe, expect} = test\n\n// Global (these are the defaults)\nconfigure({asyncUtilTimeout: 1000, testIdAttribute: 'data-testid'})\n\n// Specific block\ndescribe('my page', () =\u003e {\n  beforeEach(() =\u003e configure({asyncUtilTimeout: 5000, testIdAttribute: 'data-custom-test-id'}))\n\n  afterEach(() =\u003e configure({}))\n\n  test('my form', async ({page, queries}) =\u003e {\n    // ...\n  })\n})\n```\n\n### Standalone Playwright Queries\n\nUsing the `ElementHandle` queries with Playwright (**playwright**) and **playwright-testing-library**.\n\n\u003e ⚠️ See note in [Usage](#-usage) as you should be using **@playwright/test** with the `Locator` fixture if possible. The `Locator` queries will be made available for standalone **playwright** in the next major release.\n\n```ts\nimport {beforeAll, expect, jest, test} from '@jest/globals'\nimport {webkit} from 'playwright' // or 'firefox' or 'chromium'\nimport {getDocument, queries, within} from 'playwright-testing-library'\n\nlet browser: playwright.Browser\nlet page: playwright.Page\n\nbeforeAll(() =\u003e {\n  const browser = await webkit.launch()\n  const page = await browser.newPage()\n})\n\ntest('my form', () =\u003e {\n  // Get `ElementHandle` for document from `Page`\n  const documentHandle = await getDocument(page)\n\n  // Global query methods take document handle as the first parameter\n  const formHandle = await queries.getByTestId(documentHandle, 'my-form')\n\n  // Scope queries to an `ElementHandle` with `within`\n  const emailInputHandle = await within(formHandle).getByLabelText('Email')\n\n  // Interact via `ElementHandle` API\n  await emailInputHandle.fill('email@playwright.dev')\n  await emailInputHandle.press('Enter')\n\n  page.goto('/account')\n\n  const accountHandle = getDocument(page)\n  const emailHandle = queries.getByRole(accountHandle, 'heading', {level: 2})\n\n  // Assert via `ElementHandle` APIs\n  expect(await emailHandle.textContent()).toEqual('email@playwright.dev')\n})\n```\n\n#### Configuration\n\n```ts\nimport {beforeEach, afterEach, expect, jest, test} from '@jest/globals'\nimport {configure, getDocument, queries, within} from 'playwright-testing-library'\n\n// Global (these are the defaults)\nconfigure({asyncUtilTimeout: 1000, testIdAttribute: 'data-testid'})\n\n// Specific block\ndescribe('my page', () =\u003e {\n  beforeEach(() =\u003e configure({asyncUtilTimeout: 5000, testIdAttribute: 'data-custom-test-id'}))\n\n  afterEach(() =\u003e configure({}))\n\n  test('my form', async ({page, queries}) =\u003e {\n    // ...\n  })\n})\n```\n\n## 🔌 API\n\n### Testing Library\n\nAll queries from **[@testing-library/dom](https://github.com/testing-library/dom-testing-library#usage)** are supported.\n\n\u003e 📝 The **`find*`** queries for the `Locator` queries return `Promise\u003cLocator\u003e` which resolves when the element is found before the timeout specified via `asyncUtilTimeout`\n\n### Additional\n\nUnique methods, not part of **@testing-library/dom**\n\n\u003e ⚠️ These only apply to the `ElementHandle` queries\n\n- Get an `ElementHandle` for the document\n\n  ```ts\n  getDocument(page: playwright.Page): ElementHandle\n  ```\n\n- Wait for an assertion (wrapper around [wait-for-expect](https://github.com/TheBrainFamily/wait-for-expect))\n\n  ```ts\n  waitFor(\n    expectation: () =\u003e void | Promise\u003cvoid\u003e,\n    timeout?: number,\n    interval?: number\n  ): Promise\u003c{}\u003e\n  ```\n\n## Known Limitations\n\n- Only `testIdAttribute` and `asyncUtilTimeout` are supported as configuration options\n- Async utilities `waitForElement`, `waitForElementToBeRemoved` and `waitForDomChange` are not exposed. Consider using a `find*` query or a Playwright built-in like [`Locator.waitFor()`](https://playwright.dev/docs/api/class-locator#locator-wait-for).\n- The `fireEvent` method is not exposed, use Playwright's built-ins instead.\n- Assertion extensions from [**jest-dom**](https://testing-library.com/docs/ecosystem-jest-dom/) are not compatible, use Playwright Test if possible.\n\n### Locator Queries\n\n- The [`getNodeText()`](https://testing-library.com/docs/dom-testing-library/api-custom-queries/#getnodetext) function is currently unsupported.\n- When using a function for [`TextMatch`](https://testing-library.com/docs/queries/about/#textmatch), the function cannot reference its closure scope\n\n  ```ts\n  // ✅ This is supported\n  screen.getByText(content =\u003e content.startsWith('Foo'))\n\n  // ❌ This is not supported\n  const startsWithFoo = (content: string) =\u003e content.startsWith('Foo')\n\n  screen.getByText(content =\u003e startsWithFoo(content))\n  ```\n\n## Special Thanks\n\n- [pptr-testing-library](https://github.com/testing-library/pptr-testing-library)\n- [@testing-library/dom](https://github.com/testing-library/dom-testing-library)\n\n## Related Playwright Test Utilities\n\n- [jest-playwright](https://github.com/playwright-community/jest-playwright)\n- [expect-playwright](https://github.com/playwright-community/expect-playwright)\n\n## LICENSE\n\nMIT\n\n## Maintenance\n\nThis project is actively maintained by engineers at\n[@hoverinc](https://github.com/hoverinc/) 😀.\n\n[codecov-badge]: https://codecov.io/gh/testing-library/playwright-testing-library/branch/main/graph/badge.svg\n[codecov-link]: https://codecov.io/gh/testing-library/playwright-testing-library\n[conventional-commits-badge]: https://img.shields.io/badge/Conventional%20Commits-1.0.0-yellow.svg\n[conventional-commits-link]: https://conventionalcommits.org\n[david-badge]: https://david-dm.org/testing-library/playwright-testing-library.svg\n[david-link]: https://david-dm.org/testing-library/playwright-testing-library\n[license-badge]: https://img.shields.io/npm/l/@hover/javascript.svg\n[license-link]: https://github.com/hoverinc/hover-javascript/blob/master/LICENSE\n[maintenance-badge]: https://img.shields.io/badge/maintenance-active-247ddc?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAcCAYAAACUJBTQAAAB1ElEQVRIibWWPUtdQRCGH0VNF/wCCVjYCxr/gZWdhYVgLQYbm/wACTYxxA8SSBDtbKwUbfQWkiJFAgkkmHBBY6U2CXaCGlDDG1buxePOnt17bsgD28zOzjtnZvbuRVKR1SFpVdKepEe1njOGnOWCz0q60B1lSa05/oVE2iTNSfqdCZ7lSyWB0NmkSJekeUmXJqzlayWZUJxckUUTJs23mFAjlhNjSdMHfAQ6g54hZUnDdXyN44ek7iKNH4w0PMaeX7pQ8Ox6HQkWww3Dw1hPWoAJ4BxoB4aNR5oB4APQ5vekUdITSceZDLcreyORrGPcfpEL0CBpVNJRwLmUSWLS7NbGpju8FXEteT2qR+jQ9aS3QK2XgUljjXPpRC6iLpYV4KmxRghNVy28Aqb+t4jjLbBhrAH+RcRxZSwBUiINxlIHKZE/xlIHTTlHBDwHjoDPwHtgF/gEnBnvFJVfzSrXkpYyfxKGvIu14F3ONXP1LOWmzEPjpuWl92j55XyQyDnEjRN5AbwD9gMOPkV7tAPMOJE3ZuuOFmOpjS3gGfCdQDl8fgGnGVtzwt8F7wdGqgKOvOmq4iarB3gMjAFlb78qug5MAwehIO4tKViJe4wDP4FSrgfwF/ntR8JxRSf3AAAAAElFTkSuQmCC\n[maintenance-link]: https://github.com/testing-library/playwright-testing-library#maintenance\n[npm-badge]: https://img.shields.io/npm/v/playwright-testing-library\n[npm-link]: https://www.npmjs.com/package/playwright-testing-library\n[prettier-badge]: https://img.shields.io/badge/code_style-prettier-ff69b4.svg?logo=prettier\n[prettier-link]: https://prettierjs.org/en/download/\n[build-badge]: https://github.com/testing-library/playwright-testing-library/actions/workflows/build.yml/badge.svg\n[build-link]: https://github.com/testing-library/playwright-testing-library/actions/workflows/build.yml\n","funding_links":[],"categories":["TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftesting-library%2Fplaywright-testing-library","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftesting-library%2Fplaywright-testing-library","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftesting-library%2Fplaywright-testing-library/lists"}