From a16a68859ed39c9f95e06e1a3b95b2194bbf42b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20S=C4=99dzik?= Date: Mon, 17 Jul 2023 20:29:50 +0200 Subject: [PATCH 1/2] feat: add `@tag` decorator --- README.md | 33 +++++++++++++++++++++++++++++++++ lib/index.ts | 2 ++ lib/tag.decorator.ts | 21 +++++++++++++++++++++ tests/tag.spec.ts | 41 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 97 insertions(+) create mode 100644 lib/tag.decorator.ts create mode 100644 tests/tag.spec.ts diff --git a/README.md b/README.md index bdb08af..2ee0f2a 100644 --- a/README.md +++ b/README.md @@ -195,3 +195,36 @@ class TestSuite { } } ``` + +### Run test(s) or suite(s) with certain tag(s): `@tag(tags: string[])` +Declares a @test or @suite with certain tag(s). +You can later run test(s) or suite(s) with specific tag, using `npx playwright test --grep "@nameOfTag"` command. +For example: to run tests/suites with `x` tag, please run `npx playwright test --grep "@x"` + +```ts +import { suite, test, tag } from 'playwright-decorators'; + +// Run only selected test suite(s) +@tag(['x-api-consumer']) // <-- Decorate suite with @tag() +@suite() +class ApiConsumerTestSuite { +} + +// Or run only selected test(s) +@suite() +class TestSuite { + @tag(['x-api-consumer']) // <-- Decorate test with @tag() + @test() + async apiConsumerTest({ page }) { + // ... + } +} +``` + +To run test(s) or suite(s) for `x-api-consumer` tag (example above), please type and run below command: +```shell +npx playwright test --grep "@x-api-consumer" +``` + +#### Options +- `tags` (required) - array of tags. (Tags should not be prefixed with `@` sign, as sign will be automatically added to every tag by `@tag` decorator). diff --git a/lib/index.ts b/lib/index.ts index 1219896..5196778 100644 --- a/lib/index.ts +++ b/lib/index.ts @@ -10,3 +10,5 @@ export { afterEach } from './afterEach.decorator'; export { skip } from './skip.decorator'; export { slow } from './slow.decorator'; export { only } from './only.decorator'; +// helpers +export { tag } from './tag.decorator'; diff --git a/lib/tag.decorator.ts b/lib/tag.decorator.ts new file mode 100644 index 0000000..44d2d90 --- /dev/null +++ b/lib/tag.decorator.ts @@ -0,0 +1,21 @@ +import {SuiteDecoratedMethod} from "./suite.decorator"; +import {TestDecoratedMethod} from "./test.decorator"; + +/** + * Declares a @test or @suite with certain tag(s). + * You can later run test(s) or suite(s) with specific tag, using `npx playwright test --grep "@nameOfTag"` command. + * For example: to run tests/suites with `x` tag, please run `npx playwright test --grep "@x"` + */ +export const tag = (tags: string[]) => function(originalMethod: any, context?: any) { + const tagsAsPlaywrightAnnotations = tags.map(tag => `@${tag}`).join(' '); + + if ((originalMethod as SuiteDecoratedMethod)?.suiteDecorator) { + originalMethod.suiteDecorator.name = `${originalMethod.suiteDecorator.name} ${tagsAsPlaywrightAnnotations}`; + return; + } + + if ((originalMethod as TestDecoratedMethod)?.testDecorator) { + originalMethod.testDecorator.name = `${originalMethod.testDecorator.name} ${tagsAsPlaywrightAnnotations}`; + return; + } +} diff --git a/tests/tag.spec.ts b/tests/tag.spec.ts new file mode 100644 index 0000000..453a4de --- /dev/null +++ b/tests/tag.spec.ts @@ -0,0 +1,41 @@ +import playwright, {expect} from "@playwright/test"; +import {mockFn} from "./__mocks__/mockFn"; +import {suite, tag, test} from "../lib"; + +playwright.describe('@tag decorator', () => { + playwright.describe('with @suite', () => { + const titlePath: string[] = []; + + @tag(['x']) + @suite() + class SuiteWithTag { + @test() + async test({}, testInfo) { + titlePath.push(...testInfo.titlePath); + } + } + + playwright('should add @x tag to suite name', () => { + expect(titlePath.join('->')).toContain('SuiteWithTag'); + expect(titlePath.join('->')).toContain('@x'); + }); + }) + + playwright.describe('with @test', () => { + const titlePath: string[] = []; + + @suite() + class TestSuite { + @tag(['x']) + @test() + async testWithTag({}, testInfo) { + titlePath.push(...testInfo.titlePath); + } + } + + playwright('should add @x tag to test name', () => { + expect(titlePath.join('->')).toContain('testWithTag'); + expect(titlePath.join('->')).toContain('@x'); + }); + }); +}); From 4466771a81885e438c9dd39dacb0c0b128e9a801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20S=C4=99dzik?= Date: Mon, 17 Jul 2023 20:34:42 +0200 Subject: [PATCH 2/2] docs: update `@tag` docs --- README.md | 12 ++++++------ lib/tag.decorator.ts | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 2ee0f2a..0334c1c 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ class MyTestSuite { ## 📝 Documentation ### Creating a test suite: `@suite(options?)` -Decorate a class with `@suite()` or `@suite(options)` to create a test suite. +Mark class as test suite. Under the hood, decorator creates a `describe` block and runs all methods decorated by `@test` inside it. ```ts @@ -41,7 +41,7 @@ class MyTestSuite { - `name` (optional) - name of the test suite. By default, name of the class. ### Creating a test: `@test(options?)` -Mark class method as test by decorating it with `@test()` or `@test(options)` decorator. +Mark class method as test. Under the hood, decorator creates a `test` block and runs the method inside it. ```ts @@ -120,7 +120,7 @@ class MyTestSuite { ``` ### Skip test or suite: `@skip(reason?: string)` -Skip single method or test suite. +Skip single `@test` or `@suite`. ```ts import { suite, test, skip } from 'playwright-decorators'; @@ -146,7 +146,7 @@ class MyTestSuite { - `reason` (optional) - reason of skipping. Will be displayed in the test report. ### Mark test or suite as "slow": `@slow(reason?: string)` -Mark single method or test suite as "slow". +Mark single `@test` or `@suite` as "slow". Slow test will be given triple the default timeout. ```ts @@ -173,7 +173,7 @@ class MyTestSuite { - `reason` (optional) - reason of marking as "slow". Will be displayed in the test report. ### Run only selected test(s) or suite(s): `@only()` -Declares a focused test or suite. +Declares a focused `@test` or `@suite`. If there are some focused tests or suites, all of them will be run but nothing else. ```ts @@ -197,7 +197,7 @@ class TestSuite { ``` ### Run test(s) or suite(s) with certain tag(s): `@tag(tags: string[])` -Declares a @test or @suite with certain tag(s). +Adds tags to `@test` or `@suite`. You can later run test(s) or suite(s) with specific tag, using `npx playwright test --grep "@nameOfTag"` command. For example: to run tests/suites with `x` tag, please run `npx playwright test --grep "@x"` diff --git a/lib/tag.decorator.ts b/lib/tag.decorator.ts index 44d2d90..2485fe6 100644 --- a/lib/tag.decorator.ts +++ b/lib/tag.decorator.ts @@ -2,7 +2,7 @@ import {SuiteDecoratedMethod} from "./suite.decorator"; import {TestDecoratedMethod} from "./test.decorator"; /** - * Declares a @test or @suite with certain tag(s). + * Adds tags to `@test` or `@suite`. * You can later run test(s) or suite(s) with specific tag, using `npx playwright test --grep "@nameOfTag"` command. * For example: to run tests/suites with `x` tag, please run `npx playwright test --grep "@x"` */