# class: TestInfo
* langs: js

`TestInfo` contains information about currently running test. It is available to any test function, [`method: Test.beforeEach`] and [`method: Test.afterEach`] hooks and test-scoped fixtures. `TestInfo` provides utilities to control test execution: attach files, update test timeout, determine which test is currently running and whether it was retried, etc.

```js js-flavor=js
const { test, expect } = require('@playwright/test');

test('basic test', async ({ page }, testInfo) => {
  expect(testInfo.title).toBe('basic test');
  await page.screenshot(testInfo.outputPath('screenshot.png'));
});
```

```js js-flavor=ts
import { test, expect } from '@playwright/test';

test('basic test', async ({ page }, testInfo) => {
  expect(testInfo.title).toBe('basic test');
  await page.screenshot(testInfo.outputPath('screenshot.png'));
});
```


## property: TestInfo.annotations
- type: <[Array]<[Object]>>
  - `type` <[string]> Annotation type, for example `'skip'` or `'fail'`.
  - `description` <[void]|[string]> Optional description.

The list of annotations applicable to the current test. Includes annotations from the test, annotations from all [`method: Test.describe`] groups the test belongs to and file-level annotations for the test file.

Learn more about [test annotations](./test-annotations.md).

## property: TestInfo.attachments
- type: <[Array]<[Object]>>
  - `name` <[string]> Attachment name.
  - `contentType` <[string]> Content type of this attachment to properly present in the report, for example `'application/json'` or `'image/png'`.
  - `path` <[void]|[string]> Optional path on the filesystem to the attached file.
  - `body` <[void]|[Buffer]> Optional attachment body used instead of a file.

The list of files or buffers attached to the current test. Some reporters show test attachments. For example, you can attach a screenshot to the test.

```js js-flavor=js
const { test, expect } = require('@playwright/test');

test('basic test', async ({ page }, testInfo) => {
  await page.goto('https://playwright.dev');

  // Capture a screenshot and attach it.
  const path = testInfo.outputPath('screenshot.png');
  await page.screenshot({ path });
  testInfo.attachments.push({ name: 'screenshot', path, contentType: 'image/png' });
});
```

```js js-flavor=ts
import { test, expect } from '@playwright/test';

test('basic test', async ({ page }, testInfo) => {
  await page.goto('https://playwright.dev');

  // Capture a screenshot and attach it.
  const path = testInfo.outputPath('screenshot.png');
  await page.screenshot({ path });
  testInfo.attachments.push({ name: 'screenshot', path, contentType: 'image/png' });
});
```

## property: TestInfo.column
- type: <[int]>

Column number where the currently running test is declared.


## property: TestInfo.config
- type: <[TestConfig]>

Processed configuration from the [configuration file](./test-configuration.md).


## property: TestInfo.duration
- type: <[int]>

The number of milliseconds the test took to finish. Always zero before the test finishes, either successfully or not.


## property: TestInfo.error
- type: <[Object]>
  - `message` <[void]|[string]> Error message. Set when `Error` (or its subclass) has been thrown.
  - `stack` <[void]|[string]> Error stack. Set when `Error` (or its subclass) has been thrown.
  - `value` <[void]|[string]> The thrown value. Set when anything except the `Error` (or its subclass) has been thrown.

An error thrown during test execution, if any.


## property: TestInfo.expectedStatus
- type: <[TestStatus]<"passed"|"failed"|"timedOut"|"skipped">>

Expected status for the currently running test. This is usually `'passed'`, except for a few cases:
* `'skipped'` for skipped tests, e.g. with [`method: Test.skip`];
* `'failed'` for tests marked as failed with [`method: Test.fail`].

Expected status is usually compared with the actual [`property: TestInfo.status`]:

```js js-flavor=js
const { test, expect } = require('@playwright/test');

test.afterEach(async ({}, testInfo) => {
  if (testInfo.status !== testInfo.expectedStatus)
    console.log(`${testInfo.title} did not run as expected!`);
});
```

```js js-flavor=ts
import { test, expect } from '@playwright/test';

test.afterEach(async ({}, testInfo) => {
  if (testInfo.status !== testInfo.expectedStatus)
    console.log(`${testInfo.title} did not run as expected!`);
});
```

## method: TestInfo.fail

Marks the currently running test as "should fail". Playwright Test ensures that this test is actually failing. This is similar to [`method: Test.fail`].

### param: TestInfo.fail.condition
- `condition` <[void]|[boolean]>

Optional condition - the test is marked as "should fail" when the condition is `true`.

### param: TestInfo.fail.description
- `description` <[void]|[string]>

Optional description that will be reflected in a test report.

## property: TestInfo.file
- type: <[string]>

Absolute path to a file where the currently running test is declared.

## method: TestInfo.fixme

Marks the currently running test as "fixme". The test will be skipped, but the intention is to fix it. This is similar to [`method: Test.fixme`].

### param: TestInfo.fixme.condition
- `condition` <[void]|[boolean]>

Optional condition - the test is marked as "fixme" when the condition is `true`.

### param: TestInfo.fixme.description
- `description` <[void]|[string]>

Optional description that will be reflected in a test report.

## property: TestInfo.fn
- type: <[function]\([TestArgs], [TestInfo]\)>

Test function as passed to `test(title, testFunction)`.

## property: TestInfo.line
- type: <[int]>

Line number where the currently running test is declared.

## property: TestInfo.outputDir
- type: <[string]>

Absolute path to the output directory for this specific test run. Each test run gets its own directory so they cannot conflict.

## method: TestInfo.outputPath
- returns: <[string]>

Returns a path inside the [`property: TestInfo.outputDir`] where the test can safely put a temporary file. Guarantees that tests running in parallel will not interfere with each other.

```js js-flavor=js
const { test, expect } = require('@playwright/test');
const fs = require('fs');

test('example test', async ({}, testInfo) => {
  const file = testInfo.outputPath('dir', 'temporary-file.txt');
  await fs.promises.writeFile(file, 'Put some data to the dir/temporary-file.txt', 'utf8');
});
```

```js js-flavor=ts
import { test, expect } from '@playwright/test';
import fs from 'fs';

test('example test', async ({}, testInfo) => {
  const file = testInfo.outputPath('dir', 'temporary-file.txt');
  await fs.promises.writeFile(file, 'Put some data to the dir/temporary-file.txt', 'utf8');
});
```

### param: TestInfo.outputPath.pathSegments
- `pathSegments` <[string...]>

Path segments to append at the end of the resulting path.


## property: TestInfo.project
- type: <[TestProject]>

Processed project configuration from the [configuration file](./test-configuration.md).


## property: TestInfo.repeatEachIndex
- type: <[int]>

Specifies a unique repeat index when running in "repeat each" mode. This mode is enabled by passing `--repeat-each` to the [command line](./test-cli.md).

## property: TestInfo.retry
- type: <[int]>

Specifies the retry number when the test is retried after a failure. The first test run has [`property: TestInfo.retry`] equal to zero, the first retry has it equal to one, and so on. Learn more about [retries](./test-retries.md).

## method: TestInfo.setTimeout

Changes the timeout for the currently running test. Zero means no timeout.

Timeout is usually specified in the [configuration file](./test-configuration.md), but it could be useful to change the timeout in certain scenarios:

```js js-flavor=js
const { test, expect } = require('@playwright/test');

test.beforeEach(async ({ page }, testInfo) => {
  // Extend timeout for all tests running this hook by 30 seconds.
  testInfo.setTimeout(testInfo.timeout + 30000);
});
```

```js js-flavor=ts
import { test, expect } from '@playwright/test';

test.beforeEach(async ({ page }, testInfo) => {
  // Extend timeout for all tests running this hook by 30 seconds.
  testInfo.setTimeout(testInfo.timeout + 30000);
});
```

### param: TestInfo.setTimeout.timeout
- `timeout` <[int]>

Timeout in milliseconds.

## method: TestInfo.skip

Skips the currently running test. This is similar to [`method: Test.skip`].

### param: TestInfo.skip.condition
- `condition` <[void]|[boolean]>

Optional condition - the test is skipped when the condition is `true`.

### param: TestInfo.skip.description
- `description` <[void]|[string]>

Optional description that will be reflected in a test report.

## method: TestInfo.slow

Marks the currently running test as "slow", giving it triple the default timeout. This is similar to [`method: Test.slow`].

### param: TestInfo.slow.condition
- `condition` <[void]|[boolean]>

Optional condition - the test is marked as "slow" when the condition is `true`.

### param: TestInfo.slow.description
- `description` <[void]|[string]>

Optional description that will be reflected in a test report.

## method: TestInfo.snapshotPath
- returns: <[string]>

Returns a path to a snapshot file with the given `snapshotName`. Learn more about [snapshots](./test-snapshots.md).

### param: TestInfo.snapshotPath.snapshotName
- `snapshotName` <[string]> The name of the snapshot. Note that snapshots with the same name in the same test file are expected to be the same.

## property: TestInfo.snapshotSuffix
- type: <[string]>

Suffix used to differentiate snapshots between multiple test configurations. For example, if snapshots depend on the platform, you can set `testInfo.snapshotSuffix` equal to `process.platform`. In this case `expect(value).toMatchSnapshot(snapshotName)` will use different snapshots depending on the platform. Learn more about [snapshots](./test-snapshots.md).

## property: TestInfo.status
- type: <[void]|[TestStatus]<"passed"|"failed"|"timedOut"|"skipped">>

Actual status for the currently running test. Available after the test has finished in [`method: Test.afterEach`] hook and fixtures.

Status is usually compared with the [`property: TestInfo.expectedStatus`]:

```js js-flavor=js
const { test, expect } = require('@playwright/test');

test.afterEach(async ({}, testInfo) => {
  if (testInfo.status !== testInfo.expectedStatus)
    console.log(`${testInfo.title} did not run as expected!`);
});
```

```js js-flavor=ts
import { test, expect } from '@playwright/test';

test.afterEach(async ({}, testInfo) => {
  if (testInfo.status !== testInfo.expectedStatus)
    console.log(`${testInfo.title} did not run as expected!`);
});
```

## property: TestInfo.stderr
- type: <[Array]<[string]|[Buffer]>>

Output written to `process.stderr` or `console.error` during the test execution.

## property: TestInfo.stdout
- type: <[Array]<[string]|[Buffer]>>

Output written to `process.stdout` or `console.log` during the test execution.

## property: TestInfo.timeout
- type: <[int]>

Timeout in milliseconds for the currently running test. Zero means no timeout. Timeout is usually specified in the [configuration file](./test-configuration.md)

```js js-flavor=js
const { test, expect } = require('@playwright/test');

test.beforeEach(async ({ page }, testInfo) => {
  // Extend timeout for all tests running this hook by 30 seconds.
  testInfo.setTimeout(testInfo.timeout + 30000);
});
```

```js js-flavor=ts
import { test, expect } from '@playwright/test';

test.beforeEach(async ({ page }, testInfo) => {
  // Extend timeout for all tests running this hook by 30 seconds.
  testInfo.setTimeout(testInfo.timeout + 30000);
});
```

## property: TestInfo.title
- type: <[string]>

The title of the currently running test as passed to `test(title, testFunction)`.

## property: TestInfo.workerIndex
- type: <[int]>

The unique index of the worker process that is running the test. Also available as `process.env.TEST_WORKER_INDEX`. Learn more about [parallelism and sharding](./test-parallel.md) with Playwright Test.
