Skip to content

Commit

Permalink
feat(test runner): tags/annotations (#29248)
Browse files Browse the repository at this point in the history
API changes:
- `test(title, details, body)` where details contain `tag` and
`annotation`.
- similar `details` property added to `test.skip`, `test.fail`,
`test.fixme`, `test.only`, `test.describe` and other `test.describe.*`
variations.
- `TestProject.tagFilter`/`TestConfig.tagFilter` that supports logical
tag expressions with `(`, `)`, `and`, `or` and `not`.
- `--tag` CLI option to filter by tags.
- New annotations are available in `TestInfo.annotations` and
`TestCase.annotations`.
- New tags are available in `TestCase.tags`.
    
Reporter changes:
- `json` reporter includes new tags in addition to old `@smoke`-style
tags. **Breaking**: tags are now listed with the leading `@` symbol.
- `html` reporter filters by old and new tags with the same `@smoke`
token.

Fixes #29229, fixes #23180.
  • Loading branch information
dgozman authored Feb 8, 2024
1 parent 58f580d commit 3331a40
Show file tree
Hide file tree
Showing 33 changed files with 1,849 additions and 220 deletions.
121 changes: 94 additions & 27 deletions docs/src/test-annotations-js.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ title: "Annotations"

## Introduction

Playwright Test supports test annotations to deal with failures, flakiness, skip, focus and tag tests:
- [`method: Test.skip`] marks the test as irrelevant. Playwright Test does not run such a test. Use this annotation when the test is not applicable in some configuration.
- [`method: Test.fail`] marks the test as failing. Playwright Test will run this test and ensure it does indeed fail. If the test does not fail, Playwright Test will complain.
- [`method: Test.fixme`] marks the test as failing. Playwright Test will not run this test, as opposed to the `fail` annotation. Use `fixme` when running the test is slow or crashes.
Playwright supports tags and annotations that are displayed in the test report.

You can add your own tags and annotations at any moment, but Playwright comes with a few built-in ones:
- [`method: Test.skip`] marks the test as irrelevant. Playwright does not run such a test. Use this annotation when the test is not applicable in some configuration.
- [`method: Test.fail`] marks the test as failing. Playwright will run this test and ensure it does indeed fail. If the test does not fail, Playwright will complain.
- [`method: Test.fixme`] marks the test as failing. Playwright will not run this test, as opposed to the `fail` annotation. Use `fixme` when running the test is slow or crashes.
- [`method: Test.slow`] marks the test as slow and triples the test timeout.

Annotations can be used on a single test or a group of tests. Annotations can be conditional, in which case they apply when the condition is truthy. Annotations may depend on test fixtures. There could be multiple annotations on the same test, possibly in different configurations.
Annotations can be used on a single test or a group of tests.

Built-in annotations can be conditional, in which case they apply when the condition is truthy, and may depend on test fixtures. There could be multiple annotations on the same test, possibly in different configurations.

## Focus a test

Expand Down Expand Up @@ -63,66 +67,129 @@ test.describe('two tests', () => {

## Tag tests

Sometimes you want to tag your tests as `@fast` or `@slow` and only run the tests that have the certain tag. We recommend that you use the `--grep` and `--grep-invert` command line flags for that:
Sometimes you want to tag your tests as `@fast` or `@slow`, and then filter by tag in the test report. Or you might want to only run tests that have a certain tag. To do this, provide additional details when declaring a test.

```js
import { test, expect } from '@playwright/test';

test('Test login page @fast', async ({ page }) => {
test('test login page', {
tag: '@fast',
}, async ({ page }) => {
// ...
});

test('Test full report @slow', async ({ page }) => {
test('test full report', {
tag: '@slow',
}, async ({ page }) => {
// ...
});
```

You will then be able to run only that test:
You can also tag all tests in a group or provide multiple tags:

```js
import { test, expect } from '@playwright/test';

test.describe('group', {
tag: '@report',
}, () => {
test('test report header', async ({ page }) => {
// ...
});

test('test full report', {
tag: ['@slow', '@vrt'],
}, async ({ page }) => {
// ...
});
});
```

You can now run tests that have a particular tag.

```bash tab=bash-bash
npx playwright test --grep @fast
npx playwright test --tag @fast
```

```powershell tab=bash-powershell
npx playwright test --grep "@fast"
npx playwright test --tag "@fast"
```

```batch tab=bash-batch
npx playwright test --grep @fast
npx playwright test --tag @fast
```

Or if you want the opposite, you can skip the tests with a certain tag:

```bash tab=bash-bash
npx playwright test --grep-invert @fast
npx playwright test --tag "not @fast"
```

```powershell tab=bash-powershell
npx playwright test --grep-invert "@fast"
npx playwright test --tag "not @fast"
```

```batch tab=bash-batch
npx playwright test --grep-invert @fast
npx playwright test --tag "not @fast"
```

To run tests containing either tag (logical `OR` operator):
The `--tag` option supports logical tag expressions. You can use `and`, `or` and `not` operators, as well as group with parenthesis. For example, to run `@smoke` tests that are either `@slow` or `@very-slow`:

```bash tab=bash-bash
npx playwright test --grep "@fast|@slow"
npx playwright test --tag "@smoke and (@slow or @very-slow)"
```

```powershell tab=bash-powershell
npx playwright test --grep --% "@fast^|@slow"
npx playwright test --tag "@smoke and (@slow or @very-slow)"
```

```batch tab=bash-batch
npx playwright test --grep "@fast^|@slow"
npx playwright test --tag "@smoke and (@slow or @very-slow)"
```

You can also filter tests in the configuration file via [`property: TestConfig.tagFilter`] and [`property: TestProject.tagFilter`].


## Annotate tests

If you would like to annotate your tests with something more substantial than a tag, you can do that when declaring a test. Annotations have a `type` and a `description` for more context, and will be visible in the test report.

For example, to annotate a test with an issue url:

```js
import { test, expect } from '@playwright/test';

test('test login page', {
annotation: {
type: 'issue',
description: 'https://github.com/microsoft/playwright/issues/23180',
},
}, async ({ page }) => {
// ...
});
```

Or run tests containing both tags (logical `AND` operator) using regex lookaheads:
You can also annotate all tests in a group or provide multiple annotations:

```bash
npx playwright test --grep "(?=.*@fast)(?=.*@slow)"
```js
import { test, expect } from '@playwright/test';

test.describe('report tests', {
annotation: { type: 'category', description: 'report' },
}, () => {
test('test report header', async ({ page }) => {
// ...
});

test('test full report', {
annotation: [

This comment has been minimized.

Copy link
@IPRIT

IPRIT Feb 8, 2024

Would be cool to see projects property to run only specific platforms for test to remove skips from the the report like:

test('my test', {
  projects: ['chrome-desktop']
}, ({ page }) => {
  // ...
})
{ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/23180' },
{ type: 'performance', description: 'very slow test!' },
],
}, async ({ page }) => {
// ...
});
});
```

## Conditionally skip a group of tests
Expand Down Expand Up @@ -166,17 +233,17 @@ test('user profile', async ({ page }) => {
});
```

## Custom annotations
## Dynamic annotations

It's also possible to add custom metadata in the form of annotations to your tests. Annotations are key/value pairs accessible via [`test.info().annotations`](./api/class-testinfo#test-info-annotations). Many reporters show annotations, for example `'html'`.
While the test is running, you can add dynamic annotations to [`test.info().annotations`](./api/class-testinfo#test-info-annotations).


```js title="example.spec.ts"

test('user profile', async ({ page }) => {
test('example test', async ({ page, browser }) => {
test.info().annotations.push({
type: 'issue',
description: 'https://github.com/microsoft/playwright/issues/<some-issue>',
type: 'browser version',
description: browser.version(),
});
// ...
});
Expand Down
Loading

0 comments on commit 3331a40

Please sign in to comment.