{"id":15380852,"url":"https://github.com/sebastiansedzik/playwright-decorators","last_synced_at":"2025-08-26T11:33:35.493Z","repository":{"id":180487692,"uuid":"664371030","full_name":"SebastianSedzik/playwright-decorators","owner":"SebastianSedzik","description":"TypeScript's decorators for writing Playwright based tests.","archived":false,"fork":false,"pushed_at":"2025-04-14T13:45:49.000Z","size":666,"stargazers_count":16,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-15T18:50:34.557Z","etag":null,"topics":["playwright","playwright-tests","playwright-typescript","typescript","typescript-decorators"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SebastianSedzik.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"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,"zenodo":null}},"created_at":"2023-07-09T19:15:06.000Z","updated_at":"2025-03-14T08:11:49.000Z","dependencies_parsed_at":null,"dependency_job_id":"fe41e6fe-7835-4cdf-a5c4-bd7937e0596a","html_url":"https://github.com/SebastianSedzik/playwright-decorators","commit_stats":{"total_commits":94,"total_committers":4,"mean_commits":23.5,"dds":0.5319148936170213,"last_synced_commit":"51d7a790daf1f905c4c3200138200a5d1164ccfc"},"previous_names":["sebastiansedzik/playwright-decorators"],"tags_count":27,"template":false,"template_full_name":null,"purl":"pkg:github/SebastianSedzik/playwright-decorators","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SebastianSedzik%2Fplaywright-decorators","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SebastianSedzik%2Fplaywright-decorators/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SebastianSedzik%2Fplaywright-decorators/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SebastianSedzik%2Fplaywright-decorators/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SebastianSedzik","download_url":"https://codeload.github.com/SebastianSedzik/playwright-decorators/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SebastianSedzik%2Fplaywright-decorators/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272214419,"owners_count":24893201,"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","status":"online","status_checked_at":"2025-08-26T02:00:07.904Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["playwright","playwright-tests","playwright-typescript","typescript","typescript-decorators"],"created_at":"2024-10-01T14:24:48.259Z","updated_at":"2025-08-26T11:33:35.475Z","avatar_url":"https://github.com/SebastianSedzik.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# playwright-decorators\n\nTypeScript's decorators for writing Playwright based tests.\n\n[![npm version](https://badge.fury.io/js/playwright-decorators.svg)](https://www.npmjs.com/package/playwright-decorators)\n[![package tests](https://github.com/SebastianSedzik/playwright-decorators/actions/workflows/master.yml/badge.svg?branch=master)](https://github.com/SebastianSedzik/playwright-decorators/actions/workflows/master.yml)\n\n## 🌱 Installation\n```sh\nnpm i playwright-decorators\n```\n\n## 👀 Examples\nDeclare tests using `@suite` and `@test` decorators\n```ts\nimport { suite, test, slow, tag, TestArgs, TestInfo } from 'playwright-decorators';\n\n@suite()  // \u003c-- Decorate class with @suite\nclass MyTestSuite {\n  @test() // \u003c-- Decorate test method with @test\n  async myTest({ page }: TestArgs, testInfo: TestInfo) {\n    // ...\n  }\n\n  @tag(['team-x'])\n  @slow('Response from reset password service needs more time')\n  @test() \n  async userShouldBeAbleToResetPassword({ page }: TestArgs) {\n    // ...\n  }\n\n  @withUser({ features: ['payment'] }) // \u003c- Use your own custom decorators\n  @test()\n  async userShouldBeAbleToCancelSubscription({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n1. To view all the available decorators, check the [docs](#-docs) section.\n2. For guidance on creating custom decorators, refer to the [custom decorators](#custom-decorators) section.\n3. Explore additional examples in the [examples](./examples/tests) directory.\n\n## 📖 Docs\n- [Creating a test suite: `@suite`](#creating-a-test-suite-suiteoptions)\n- [Creating a test: `@test`](#creating-a-test-testoptions)\n- [Run method before all tests in the suite: `@beforeAll`](#run-method-before-all-tests-in-the-suite-beforeall)\n- [Run method before each test in the suite: `@beforeEach`](#run-method-before-each-test-in-the-suite-beforeeach)\n- [Run method after all tests in the suite: `@afterAll`](#run-method-after-all-tests-in-the-suite-afterall)\n- [Run method after each test in the suite: `@afterEach`](#run-method-after-each-test-in-the-suite-aftereach)\n- [Skip test or suite: `@skip`](#skip-test-or-suite-skipreason-string)\n- [Mark test or suite as \"should fail\": `@fail`](#mark-test-or-suite-as-should-fail-failreason-string)\n- [Mark test or suite as \"fixme\", with the intention to fix it: `@fixme`](#mark-test-or-suite-as-fixme-with-the-intention-to-fix-it-fixmereason-string)\n- [Mark test or suite as \"slow\": `@slow`](#mark-test-or-suite-as-slow-slowreason-string)\n- [Run only selected test(s) or suite(s): `@only`](#run-only-selected-tests-or-suites-only)\n- [Run test(s) or suite(s) with certain tag(s): `@tag`](#run-tests-or-suites-with-certain-tags-tagtags-string)\n- [Add custom annotation to test(s): `@annotate`](#add-custom-annotation-to-tests-annotatetype-string-description-string)\n- [Change or set retries for test(s): `@retries`](#change-or-set-retries-for-tests-retriesretries-number)\n- [Run test(s) or suite(s) in debug mode: `@debug`](#run-tests-or-suites-in-debug-mode-debug)\n- [Run test(s) or suite(s) in preview mode: `@preview`](#run-tests-or-suites-in-preview-mode-preview)\n- [Create custom decorator: `createSuiteDecorator`, `createTestDecorator`, `createSuiteAndTestDecorator`](#custom-decorators)\n- [Using custom fixtures: `extend`](#fixtures)\n\n### Creating a test suite: `@suite(options?)`\nMark class as test suite.\nUnder the hood, decorator creates a `describe` block and runs all methods decorated by `@test` inside it.\n\n```ts\nimport { suite } from 'playwright-decorators';\n\n@suite() // \u003c-- Decorate class with @suite() or @suite(options)\nclass MyTestSuite {\n  // ...\n}\n```\n\n#### Options\n- `name` (optional) - name of the test suite. By default, name of the class.\n- `only` (optional) - declares focused test suite. If there are some focused @test(s) or @suite(s), all of them will be run but nothing else.\n\n\n### Creating a test: `@test(options?)`\nMark class method as test.\nUnder the hood, decorator creates a `test` block and runs the method inside it.\n\n```ts\nimport { suite, test, TestArgs } from 'playwright-decorators';\n\n@suite()\nclass MyTestSuite {\n  @test() // \u003c-- Decorate test method with @test() or @test(options)\n  async myTest({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n\n#### Options\n- `name` (optional) - name of the test. By default, name of the method.\n- `only` (optional) - declares focused test. If there are some focused @test(s) or @suite(s), all of them will be run but nothing else.\n- `playwright` (optional) - Custom playwright instance to use instead of standard one. For example, provide result of `playwright.extend\u003cT\u003e(customFixture)` to ensure availability of custom fixture in the `test` method.\n\n### Run method before all tests in the suite: `@beforeAll(options?)`\nMark the method as `beforeAll` book.\n\n```ts\nimport { suite, test, beforeAll, TestArgs } from 'playwright-decorators';\n\n@suite()\nclass MyTestSuite {\n  @beforeAll() // \u003c-- Decorate method with @beforeAll()\n  async beforeAll({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n\n#### Options\n- `playwright` (optional) - Custom playwright instance to use instead of standard one. For example, provide result of `playwright.extend\u003cT\u003e(customFixture)` to ensure availability of custom fixture in the `beforeAll` hook.\n\n\n### Run method before each test in the suite: `@beforeEach(options?)`\nMark the method as `beforeEach` book.\n\n```ts\nimport { suite, test, beforeEach, TestArgs } from 'playwright-decorators';\n\n@suite()\nclass MyTestSuite {\n  @beforeEach() // \u003c-- Decorate method with @beforeEach()\n  async beforeEach({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n\n#### Options\n- `playwright` (optional) - Custom playwright instance to use instead of standard one. For example, provide result of `playwright.extend\u003cT\u003e(customFixture)` to ensure availability of custom fixture in the `beforeEach` hook.\n\n\n### Run method after all tests in the suite: `@afterAll(options?)`\nMark the method as `afterAll` book.\n\n```ts\nimport { suite, test, afterAll, TestArgs } from 'playwright-decorators';\n\n@suite()\nclass MyTestSuite {\n  @afterAll() // \u003c-- Decorate method with @afterAll()\n  async afterAll({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n\n#### Options\n- `playwright` (optional) - Custom playwright instance to use instead of standard one. For example, provide result of `playwright.extend\u003cT\u003e(customFixture)` to ensure availability of custom fixture in the `afterAll` hook.\n\n\n### Run method after each test in the suite: `@afterEach(options?)`\nMark the method as `afterEach` book.\n\n```ts\nimport { suite, test, afterEach, TestArgs } from 'playwright-decorators';\n\n@suite()\nclass MyTestSuite {\n  @afterEach() // \u003c-- Decorate method with @afterEach()\n  async afterEach({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n\n#### Options\n- `playwright` (optional) - Custom playwright instance to use instead of standard one. For example, provide result of `playwright.extend\u003cT\u003e(customFixture)` to ensure availability of custom fixture in the `afterEach` hook.\n\n\n### Skip test or suite: `@skip(reason?: string)`\nSkip single `@test` or `@suite`.\n\n```ts\nimport { suite, test, skip, TestArgs } from 'playwright-decorators';\n\n// Skip test suite\n@skip() // \u003c-- Decorate suite with @skip()\n@suite()\nclass SkippedTestSuite {\n}\n\n// Or skip selected test\n@suite()\nclass MyTestSuite {\n  @skip() // \u003c-- Decorate test with @skip()\n  @test()\n  async skippedTest({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n\n#### Options\n- `reason` (optional) - the reason for skipping. Will be displayed in the test report.\n\n\n### Mark test or suite as \"should fail\": `@fail(reason?: string)`\nMark single `@test` or `@suite` as \"should fail\".\nPlaywright Test runs this test and ensures that it is actually failing.\nThis is useful for documentation purposes to acknowledge that some functionality is broken until it is fixed.\n\n```ts\nimport { suite, test, fail, TestArgs } from 'playwright-decorators';\n\n// Mark suite as \"fail\", and ensure that all tests from suite fail\n@fail() // \u003c-- Decorate suite with @fail()\n@suite()\nclass FailTestSuite {\n}\n\n// Or mark selected test as \"fail\"\n@suite()\nclass MyTestSuite {\n  @fail() // \u003c-- Decorate test with @fail()\n  @test()\n  async failingTest({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n\n#### Options\n- `reason` (optional) - the reason for marking as \"should fail\". Will be displayed in the test report.\n\n\n### Mark test or suite as \"fixme\", with the intention to fix it: `@fixme(reason?: string)`\nMarks a `@test` or `@suite` as \"fixme\", with the intention to fix (with optional reason).\nDecorated tests or suites will not be run.\n\n```ts\nimport { suite, test, fixme, TestArgs } from 'playwright-decorators';\n\n// Mark test suite as \"fixme\"\n@fixme() // \u003c-- Decorate suite with @fixme()\n@suite()\nclass FixmeTestSuite {\n}\n\n// Or mark selected test as \"fixme\"\n@suite()\nclass MyTestSuite {\n  @fixme() // \u003c-- Decorate test with @fixme()\n  @test()\n  async fixmeTest({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n\n#### Options\n- `reason` (optional) - the reason for marking as \"fixme\". Will be displayed in the test report.\n\n\n### Mark test or suite as \"slow\": `@slow(reason?: string)`\nMark single `@test` or `@suite` as \"slow\".\nSlow test will be given triple the default timeout.\n\n```ts\nimport { suite, test, skip, TestArgs } from 'playwright-decorators';\n\n// Mark test suite as \"slow\"\n@slow() // \u003c-- Decorate suite with @slow()\n@suite()\nclass SlowTestSuite {\n}\n\n// Or mark selected test as \"slow\"\n@suite()\nclass MyTestSuite {\n  @slow() // \u003c-- Decorate test with @slow()\n  @test()\n  async slowTest({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n\n#### Options\n- `reason` (optional) - the reason for marking as \"slow\". Will be displayed in the test report.\n\n\n### Run only selected test(s) or suite(s): `@only()`\nDeclares a focused `@test` or `@suite`.\nIf there are some focused tests or suites, all of them will be run but nothing else.\n\n```ts\nimport { suite, test, only, TestArgs } from 'playwright-decorators';\n\n// Run only selected test suite(s)\n@only() // \u003c-- Decorate suite with @only()\n@suite()\nclass FocusedTestSuite {\n}\n\n// Or run only selected test(s)\n@suite()\nclass TestSuite {\n    @only() // \u003c-- Decorate test with @only()\n    @test()\n    async focusedTest({ page }: TestArgs) {\n        // ...\n    }\n}\n```\n\n\n### Run test(s) or suite(s) with certain tag(s): `@tag(tags: string[])`\nAdds tags to `@test` or `@suite`.\nYou can later run test(s) or suite(s) with specific tag, using `npx playwright test --grep \"@nameOfTag\"` command.\nFor example: to run tests/suites with `x` tag, please run `npx playwright test --grep \"@x\"`\n\n```ts\nimport { suite, test, tag, TestArgs } from 'playwright-decorators';\n\n// Run only selected test suite(s)\n@tag(['x-api-consumer']) // \u003c-- Decorate suite with @tag()\n@suite()\nclass ApiConsumerTestSuite {\n}\n\n// Or run only selected test(s)\n@suite()\nclass TestSuite {\n    @tag(['x-api-consumer']) // \u003c-- Decorate test with @tag()\n    @test()\n    async apiConsumerTest({ page }: TestArgs) {\n        // ...\n    }\n}\n```\n\nTo run test(s) or suite(s) for `x-api-consumer` tag (example above), please type and run the below command:\n```shell\nnpx playwright test --grep \"@x-api-consumer\"\n``` \n\n#### Options\n- `tags` (required) - array of tags. (Tags should not be prefixed with `@` sign, as sign will be automatically added to every tag by `@tag` decorator).\n\n\n### Add custom annotation to test(s): `@annotate({type: string, description?: string})`\nAdd custom annotation to a test.\nAnnotations are accessible via `test.info().annotations`. Many reporters show annotations, for example 'html'.\n\n```ts\nimport { suite, test, annotation, TestArgs } from 'playwright-decorators';\n\n@suite()\nclass MyTestSuite {\n  @annotation({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/\u003csome-issue\u003e' }) // \u003c-- Decorate test with @annotate()\n  @test()\n  async testWithCustomAnnotation({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n\n#### Options\n- `type` (required) - type of annotation, for example 'skip' or 'fail'.\n- `description` (optional) - description of annotation.\n\n### Change or set retries for test(s): `@retries(retries: number)`\nSet the maximum number of retry attempts given to failed `@tests` in the `@suite`\n\n```ts\nimport { suite, test, retries } from 'playwright-decorators';\n\n@retries(3) // \u003c-- Decorate suite with @retries()\n@suite()\nclass MyTestSuite {\n    @test()\n    async test() { // \u003c- This test may be retried up to 3 times if it fails\n        // ...\n    }\n}\n```\n\n#### Options\n- `retries` (required) - the max number of retries for each test.\n\n\n### Run test(s) or suite(s) in debug mode: `@debug()`\nRuns a `@test`(s) or `@suite`(s) in debug mode.\nTests or suites without the `@debug` decorator will not be excluded.\nLearn more about debug mode: https://playwright.dev/docs/debug\n\n```ts\nimport { suite, test, debug, TestArgs } from 'playwright-decorators';\n\n// Debug selected test suite(s)\n@debug() // \u003c-- Decorate suite with @debug()\n@suite()\nclass DebugTestSuite {\n}\n\n// Or debug selected test(s)\n@suite()\nclass TestSuite {\n    @debug() // \u003c-- Decorate test with @debug()\n    @test()\n    async test({ page }: TestArgs) {\n        // ...\n    }\n}\n```\n\nThen run playwright tests as usual, i.e. `npx playwright test`.\n\u003e For debugging purposes, running tests only on local machine for one project/browser is recommended.\n\n\n### Run test(s) or suite(s) in preview mode: `@preview()`\nRuns a `@test`(s) or `@suite`(s) in preview (headed browser) mode, simulating user interaction (slowing down each operation by 1000ms).\nTests or suites without the `@preview` decorator will not be excluded.\n\n```ts\nimport { suite, test, preview, TestArgs } from 'playwright-decorators';\n\n// Preview selected test suite(s)\n@preview() // \u003c-- Decorate suite with @preview()\n@suite()\nclass PreviewTestSuite {\n}\n\n// Or preview selected test(s)\n@suite()\nclass TestSuite {\n    @preview() // \u003c-- Decorate test with @preview()\n    @test()\n    async test({ page }: TestArgs) {\n        // ...\n    }\n}\n```\n\nThen run playwright tests as usual, i.e. `npx playwright test`.\n\u003e For preview purposes, running tests only for one project/browser is recommended.\n\n\n### Custom decorators\nCustom decorators can be created using `createTestDecorator` and `createSuiteDecorator` functions.\nSimple usage examples are provided below. For more advanced examples, please take a look at [example decorators](./examples/tests/decorators) directory.\n\n#### Test decorator\nThe `createTestDecorator` function enables the generation of custom test decorators.\nAttempting to utilize a custom test decorator on a method that lacks the `@test` decoration will result in an error.\n\n```ts\nimport { suite, createTestDecorator } from 'playwright-decorators';\nimport playwright from '@playwright/test';\n\nconst customTestDecorator = createTestDecorator('customTestDecorator', ({ test }) =\u003e {\n  // create code using hooks provided by test decorator...\n  test.beforeTest(() =\u003e { /* ... */ })\n  test.afterTest(() =\u003e { /* ... */ })\n\n  // ...or Playwright hooks\n  playwright.beforeEach(() =\u003e {\n    // ...\n  })\n});\n```\n\nThen use it on `@test` decorator:\n```ts\n@suite()\nclass MyTestSuite {\n  @customTestDecorator() // \u003c-- Decorate test with custom decorator\n  @test()\n  async myTest({ page }: TestArgs) {\n    // ...\n  }\n}\n```\n\n#### Suite decorator\nThe `createSuiteDecorator` function allows the creation of custom suite decorators.\nAttempting to apply a custom suite decorator to a class that lacks the `@suite` decoration will result in an error.\n\n```ts\nimport { suite, createSuiteDecorator } from 'playwright-decorators';\n\nconst customSuiteDecorator = createSuiteDecorator('customSuiteDecorator', ({ suite }) =\u003e {\n  // run your custom code immediately\n  suite.name = 'Custom name';\n\n  // or attach to specific hooks...\n  suite.initialized(() =\u003e { /* ... */ })\n});\n```\n\nThen use it on `@suite` decorator:\n```ts\n@customSuiteDecorator() // \u003c-- Decorate suite with custom decorator\n@suite()\nclass MyTestSuite {\n  // ...\n}\n```\n\n### Suite and test decorator\nThe `createSuiteAndTestDecorator` function allows the creation of custom decorators that can be applied to both suites and tests.\n\n```ts\nimport {createSuiteAndTestDecorator} from 'playwright-decorators';\n\nconst customSuiteAndTestDecorator = createSuiteAndTestDecorator(\n  'customSuiteAndTestDecorator',\n  ({ suite }) =\u003e {\n    // custom suite decorator code\n  },\n  ({ test }) =\u003e {\n    // custom test decorator code\n  }\n)\n```\n\n\n### Fixtures\n\u003e If you are not familiar with concept of fixtures in Playwright, please read [this](https://playwright.dev/docs/test-fixtures) article first.\n\nThe `extend\u003cT\u003e(customFixture)` method generates decorators with access to custom fixture.\n\nThe following example illustrates how to create decorators with access to `user` fixture:\n\n```ts\nimport { test as base } from 'playwright';\nimport { suite, test, extend } from 'playwright-decorators';\n\n// #1 Create fixture type\ntype UserFixture = {\n    user: {\n      firstName: string;\n      lastName: string;\n    }\n}\n\n// #2 Create user fixture\nconst withUser = base.extend\u003cUserFixture\u003e({\n    user: async ({}, use) =\u003e {\n        await use({\n            firstName: 'John',\n            lastName: 'Doe'\n        })\n    }\n})\n\n// #3 Generate afterAll, afterEach, test, beforeAll, beforeEach decorators with access to the user fixture\nconst {\n    afterAll,\n    afterEach,\n    test,\n    beforeAll,\n    beforeEach,\n} = extend\u003cUserFixture\u003e(withUser);\n\n// #4 Use decorators\n@suite()\nclass MyTestSuite {\n    @beforeAll()\n    async beforeAll({ user }: TestArgs\u003cUserFixture\u003e) { // have access to user fixture\n        // ...\n    }\n\n    @test()\n    async test({ user }: TestArgs\u003cUserFixture\u003e) { // have access to user fixture\n        // ...\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsebastiansedzik%2Fplaywright-decorators","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsebastiansedzik%2Fplaywright-decorators","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsebastiansedzik%2Fplaywright-decorators/lists"}