# Cypress Documentation
# Source: https://raw.githubusercontent.com/cypress-io/cypress-documentation/main/docs/api/node-events/after-spec-api.mdx
# Path: docs/api/node-events/after-spec-api.mdx

---
title: 'After Spec Event | Cypress Node Events'
description: 'The after:spec event fires after a spec file is run in Cypress.'
sidebar_label: 'after:spec'
---

<ProductHeading product="app" />

# After Spec Event

The `after:spec` event fires after a spec file is run. When running cypress via
`cypress open`, the event will fire when the browser closes.

## Syntax

<WarningSetupNodeEvents />

:::caution

⚠️ When running via `cypress open`, the `after:spec` event only fires if the
[experimentalInteractiveRunEvents flag](/app/references/configuration#Experiments)
is enabled.

:::

:::cypress-config-plugin-example

```js
on('after:spec', (spec, results) => {
  /* ... */
})
```

:::

<Icon name="angle-right" /> **spec _(Object)_**

Details of the spec file, including the following properties:

| Property   | Description                                                                                |
| ---------- | ------------------------------------------------------------------------------------------ |
| `name`     | The base name of the spec file (e.g. `login.cy.js`)                                        |
| `relative` | The path to the spec file, relative to the project root (e.g. `cypress/e2e/login.cy.js`)   |
| `absolute` | The absolute path to the spec file (e.g. `/Users/janelane/my-app/cypress/e2e/login.cy.js`) |

<Icon name="angle-right" /> **results _(Object)_**

Details of the spec file's results, including numbers of passes/failures/etc and
details on the tests themselves.

Results are only provided when running via `cypress run`. When running via
`cypress open`, the results will be undefined.

## Usage

You can return a promise from the `after:spec` event handler and it will be
awaited before Cypress proceeds with processing the spec's video or moving on to
further specs if there are any.

### Log the relative spec path to stdout after the spec is run

:::cypress-config-plugin-example

```javascript
on('after:spec', (spec, results) => {
  // spec will look something like this:
  // {
  //   name: 'login.cy.js',
  //   relative: 'cypress/e2e/login.cy.js',
  //   absolute: '/Users/janelane/my-app/cypress/e2e/login.cy.js',
  // }
  // results will look something like this:
  // {
  //   stats: {
  //     suites: 0,
  //     tests: 1,
  //     passes: 1,
  //     pending: 0,
  //     skipped: 0,
  //     failures: 0,
  //     // ...more properties
  //   }
  //   reporter: 'spec',
  //   tests: [
  //     {
  //       title: ['login', 'logs user in'],
  //       state: 'passed',
  //       // ...more properties...
  //     }
  //   ],
  //   error: null,
  //   video: '/Users/janelane/my-app/cypress/videos/login.cy.js.mp4',
  //   screenshots: [],
  //   // ...more properties...
  // }
  console.log('Finished running', spec.relative)
})
```

:::

## Examples

### Delete the recorded video if the spec passed

You can delete the recorded video for a spec when certain conditions are met.
This will skip the compression and uploading of the video when recording to
Cypress Cloud.

The example below shows how to delete the recorded video for specs with no
failing tests.

:::cypress-config-plugin-example

```ts
import fs from 'fs'
```

```ts
on(
  'after:spec',
  (spec: Cypress.Spec, results: CypressCommandLine.RunResult) => {
    // Do we have failures?
    if (results && results.video && results.stats.failures === 0) {
      // delete the video if the spec passed
      fs.unlinkSync(results.video)
    }
  }
)
```

:::

### Delete the recorded video if no tests retried

You can delete the recorded video for a spec when certain conditions are met.
This will skip the compression and uploading of the video when recording to
Cypress Cloud.

The example below shows how to delete the recorded video for specs that had no
retry attempts when using Cypress [test retries](/app/guides/test-retries).

:::cypress-config-plugin-example

```ts
import fs from 'fs'
```

```ts
on(
  'after:spec',
  (spec: Cypress.Spec, results: CypressCommandLine.RunResult) => {
    if (results && results.video) {
      // Do we have failures for any retry attempts?
      const failures = results.tests.some((test) =>
        test.attempts.some((attempt) => attempt.state === 'failed')
      )
      if (!failures) {
        // delete the video if the spec passed and no tests retried
        fs.unlinkSync(results.video)
      }
    }
  }
)
```

:::

## See also

- [Before Spec API](/api/node-events/before-spec-api)
- [Before Run API](/api/node-events/before-run-api)
- [After Run API](/api/node-events/after-run-api)
- [How to use Plugins](/app/plugins/plugins-guide)
- [Node Events Overview](/api/node-events/overview)