# Overview

Currents is a cloud platform, dashboard and test orchestrator aimed to help SDET and Software Teams to manage the complexity of running automated tests in CI.

**Currents goes beyond test reports** to help teams understand test health, reduce CI runtime, and keep large test suites reliable.

SDETs, QA engineers, and engineering leaders—from startups to large enterprises—use Currents to fix CI failures faster, control flakiness, and scale testing across teams and repositories.

## Get started

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="files"></th></tr></thead><tbody><tr><td><ol><li>Connect Playwright to Currents</li></ol></td><td><a href="/pages/V1X2cpKlIVCEEvB1tq9s">/pages/V1X2cpKlIVCEEvB1tq9s</a></td><td><a href="/files/nCj2WwmbcHFtHkIHvuYg">/files/nCj2WwmbcHFtHkIHvuYg</a></td></tr><tr><td><ol start="2"><li>Setup your CI provider</li></ol></td><td><a href="/pages/xHzwM6ZSoRz2XHnYqgTt">/pages/xHzwM6ZSoRz2XHnYqgTt</a></td><td><a href="/files/xcd92La9X8E9vgW7v6Ev">/files/xcd92La9X8E9vgW7v6Ev</a></td></tr></tbody></table>

## Why Currents

Playwright reports explain a single run.\
Currents explains your test suite over time, and more.

As teams scale testing in CI, they need visibility into debugging traces, flakiness, regressions, and performance trends — and ways to act on them. Currents aggregates test data across runs and repositories, optimizes CI execution, integrates across your delivery stack, and brings test intelligence directly into daily engineering workflows.

{% content-ref url="/pages/qb47rb1B2Vi3OGRuRS1M" %}
[Alternatives to Currents](/resources/reporters/alternatives-to-currents)
{% endcontent-ref %}

## Use Currents with AI

Currents turns test failures into structured context that AI agents can act on - full errors, traces, historical results, and flakiness data - so an agent fixes a failing test from real evidence instead of a pasted error message. Debug interactively in your editor, hand failures to an agent from the dashboard, or build pipelines that auto-heal failing tests.

<table><thead><tr><th width="280" data-type="content-ref">AI</th><th></th></tr></thead><tbody><tr><td><a href="/pages/uubuNPjaIusH34p3bSoW">/pages/uubuNPjaIusH34p3bSoW</a></td><td>All the ways to connect AI agents to your test results.</td></tr><tr><td><a href="/pages/jnH6vDdIz1O24wm1EN98">/pages/jnH6vDdIz1O24wm1EN98</a></td><td>Fix CI failures with AI without leaving your editor.</td></tr><tr><td><a href="/pages/cFzyaGzZrNCprtF67Ahm">/pages/cFzyaGzZrNCprtF67Ahm</a></td><td>Let agents query runs, tests, and analytics on demand.</td></tr><tr><td><a href="/pages/4YTkJA0l1JgOaS8Y8AQ0">/pages/4YTkJA0l1JgOaS8Y8AQ0</a></td><td>Expert Playwright knowledge for your AI agents.</td></tr></tbody></table>

## Explore

Currents is much more than a reporter. Discover the full range of features and capabilities.

<table><thead><tr><th width="280" data-type="content-ref">Debugging &#x26; Analytics</th><th></th></tr></thead><tbody><tr><td><a href="/pages/UvwZp8DPo2rrwDaqJn0q">/pages/UvwZp8DPo2rrwDaqJn0q</a></td><td>Debug failures with full execution history.</td></tr><tr><td><a href="/pages/jgAL5eze5Z5unSKjg6Jh">/pages/jgAL5eze5Z5unSKjg6Jh</a></td><td>See flakiness, regressions, and trends over time.</td></tr><tr><td><a href="/pages/ukx82DfDbE2Qjb13nHb8">/pages/ukx82DfDbE2Qjb13nHb8</a></td><td>Discover problematic tests.</td></tr><tr><td><a href="/pages/Pcg9IQJNeauR9a7LslII">/pages/Pcg9IQJNeauR9a7LslII</a></td><td>Track test coverage over time.</td></tr></tbody></table>

<table><thead><tr><th width="280" data-type="content-ref">Speeding up CI</th><th></th></tr></thead><tbody><tr><td><a href="/pages/7alshCVlb0CGsMIyLUv5">/pages/7alshCVlb0CGsMIyLUv5</a></td><td>Shorten pipelines without sacrificing coverage.</td></tr><tr><td><a href="/pages/ndMMdUB3QLG0z561KRF8">/pages/ndMMdUB3QLG0z561KRF8</a></td><td>Distribute tests across CI jobs. Faster than Sharding.</td></tr></tbody></table>

<table><thead><tr><th width="280" data-type="content-ref">Automation</th><th></th></tr></thead><tbody><tr><td><a href="/pages/0AwLLZphUa1wLpuVDCYv">/pages/0AwLLZphUa1wLpuVDCYv</a></td><td>Automatically alert, skip or quarantine tests.</td></tr><tr><td><a href="/pages/IURKAIOw5vjRsHRuBHNn">/pages/IURKAIOw5vjRsHRuBHNn</a></td><td>Proactively identify regressions.</td></tr><tr><td><a href="/pages/d44bzRXv64zE5vf3hjLZ">/pages/d44bzRXv64zE5vf3hjLZ</a></td><td>Integrate with issue tracking and collaboration tools.</td></tr></tbody></table>


# Quick Start

Running Playwright tests with Currents Dashboard

Connect Playwright to Currents in a few minutes and start seeing runs, screenshots, videos, and traces in one place. This guide keeps the setup minimal so you can go from "tests run locally" to "results show up in Currents" without extra ceremony.

## Prerequisites <a href="#prerequisites" id="prerequisites"></a>

* An account — [sign up](https://app.currents.dev/signup) for a free trial.
* NodeJS v14.0.0+
* Playwright v1.22.2+

{% hint style="info" %}
Want to hand this off to AI? Copy the prompt below into Cursor, Claude, ChatGPT, or your editor assistant and let it wire up the basics for you.
{% endhint %}

<details>

<summary>🤖 Expand to see the prompt</summary>

```
Your task is to update Playwright setup to report test results to Currents.dev

1. Install "@currents/playwright" package:

- as a development dependency
- using the project's package manager (npm, pnpm, yarn, etc...)

2. Update the Playwright configuration file (playwright.config.ts|js|mjs):

  - enable traces, videos and screenshots by updating the "use" property, e.g.:

  use: {
      trace: "retain-on-failure-and-retries",
      video: "retain-on-failure",
      screenshot: "on",
  }

  - add Currents test reporter, keep any existing reporters. Example:

  // playwright.config.ts
  import { defineConfig, devices, PlaywrightTestConfig } from "@playwright/test";
  import { currentsReporter } from "@currents/playwright";

  export default defineConfig({
    // ...
    reporter: [currentsReporter()], // add Currents reporter
  });

3. Create a new "currents.config.ts" file next to the existing playwright.config.ts|js|mjs file.

- use the same extension
- add the content below

import { CurrentsConfig } from "@currents/playwright";

const config: CurrentsConfig = {
  recordKey: process.env.CURRENTS_RECORD_KEY!,
  projectId: process.env.CURRENTS_PROJECT_ID!,
};

export default config;
```

</details>

## Setup Currents

{% stepper %}
{% step %}

#### Create a Project

When you first sign in, create an organization and a project. You can rename both later, so keep moving.

Next, Currents shows your `Project ID` and `Record Key`. Keep that page open for the next steps.

<figure><img src="/files/a1cWg4YylND1MQeQCKxi" alt=""><figcaption></figcaption></figure>
{% endstep %}

{% step %}

#### Install @currents/playwright

Install the native Playwright reporter with your project's package manager.

```bash
npm i -D @currents/playwright
```

If you use `pnpm`, `yarn`, or `bun`, run the equivalent dev dependency install command instead.
{% endstep %}

{% step %}

#### Create currents.config.ts

Create `currents.config.ts` next to `playwright.config.ts`, usually in the project root. If your Playwright config uses `.js` or `.mjs`, use that same extension for `currents.config`.

{% code title="currents.config.ts" %}

```typescript
import { CurrentsConfig } from "@currents/playwright";

const config: CurrentsConfig = {
  recordKey: process.env.CURRENTS_RECORD_KEY!,
  projectId: "you project id goes here",
};

export default config;
```

{% endcode %}

Use your real project ID from Currents. Keeping `recordKey` in an environment variable is the safest default.
{% endstep %}

{% step %}

#### Enable artifacts

Update `playwright.config.ts` so every recorded run includes traces, videos, and screenshots.

```json
use: {
    // ...
    trace: "retain-on-failure-and-retries",
    video: "retain-on-failure",
    screenshot: "on",
}
```

These artifacts are what make the dashboard feel useful on the first run, so it is worth enabling all three up front.
{% endstep %}

{% step %}

#### Setup Currents Reporter

You have two ways to finish the integration. Most teams should start with the reporter because it keeps the existing Playwright command unchanged.

<details>

<summary>Option 1: Add Currents Reporter (recommended)</summary>

Add the Currents reporter to `playwright.config.ts` and keep using `playwright test`.

```typescript
// playwright.config.ts
import { defineConfig, devices, PlaywrightTestConfig } from "@playwright/test";
import { currentsReporter } from "@currents/playwright";

export default defineConfig({
  // ...
  reporter: [currentsReporter()], // 👈🏻 add Currents reporter
})
```

If you already have reporters configured, keep them and append `currentsReporter()` to the list.

* Run `npx playwright test` or your usual test command to start sending results to Currents.
* The reporter reads settings from `currents.config.ts`. See [@currents/playwright](/resources/reporters/currents-playwright) for more configuration options.

</details>

<details>

<summary>Option 2: Run tests with the pwc command</summary>

`pwc` is a lightweight command-line executable included in `@currents/playwright`. It runs Playwright with Currents wired in for you.

Setup

* Run `npx pwc`.
* Or update `package.json` to execute `pwc` instead of `playwright test`.

```json
"scripts": {
  ...
  "test": "npx pwc",
},
```

How it works

* `pwc` reads the configuration from `currents.config.ts` file. See additional configuration options [Configuration](/resources/reporters/currents-playwright/configuration).
* `pwc` injects Currents reporter into Playwright configuration.
* You can also provide CLI configuration parameters, e.g. `npx pwc --key RECORD_KEY --project-id PROJECT_ID`

</details>
{% endstep %}
{% endstepper %}

## Create your first run

After setup, run Playwright and watch results get [streamed in real-time](/guides/parallelization-guide/step-level-reporting) to Currents.

A link to the recorded run will be available at the start of the execution:

```
> npx pwc --key XXX --project-id YYY

📦 Currents reporter: 1.12.0 recording to project WlKqJ0
🎭 Playwright: 1.52.0 5 tests in 1 project [chromium]
🔨 CI Build ID: auto:tzwgltasm
🌐 Run URL: https://app.currents.dev/run/cfc7ab8fcaaz10157

================================================================
```

Open the link to see the run in the dashboard.

{% embed url="<https://player.mux.com/qpKec7RVobezySxuxI52G9bCt4vr2ffi4rNGqbm9Ab4?thumbnail-time=35>" %}

{% hint style="warning" %}
Ran into any errors? Check out our [Troubleshooting](/guides/troubleshooting-playwright) guide.
{% endhint %}

## Next Step

Once your Playwright project is set up and reporting locally, configure your CI pipeline.

Running tests in CI is where you get consistent, repeatable feedback on every pull request and deployment, not just on your local machine.

{% content-ref url="/pages/xHzwM6ZSoRz2XHnYqgTt" %}
[CI Setup](/getting-started/ci-setup)
{% endcontent-ref %}


# CI Setup

Learn how to integrate Currents with your CI provider.

## Get started

Integrating Currents with your CI Provider is the next logical step after creating your first run. Currents supports all major CI providers and provides examples for the most popular ones.

{% hint style="warning" %}
Got stuck configuring CI? Reach out to our [Support](/resources/support), we'll be happy to help!
{% endhint %}

## CI Providers

Below are articles guiding how to integrate with major CI Providers, with code examples included.

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-card-cover-dark data-type="image">Cover image (dark)</th></tr></thead><tbody><tr><td><strong>GitHub Actions</strong></td><td></td><td><a href="/pages/WCDEPTNeHvJ3wtHVbAqa">/pages/WCDEPTNeHvJ3wtHVbAqa</a></td><td data-object-fit="contain"><a href="/files/hy4ak1W2RCMNRdV0SHRZ">/files/hy4ak1W2RCMNRdV0SHRZ</a></td><td data-object-fit="contain"><a href="/files/iymLJcP8PjWTjG627SE7">/files/iymLJcP8PjWTjG627SE7</a></td></tr><tr><td><strong>GitLab</strong></td><td></td><td><a href="/pages/8kAp72H1ZAXg7J0ODFs4">/pages/8kAp72H1ZAXg7J0ODFs4</a></td><td data-object-fit="contain"><a href="/files/qkLOxpA2Nu8hK3M7QWQh">/files/qkLOxpA2Nu8hK3M7QWQh</a></td><td></td></tr><tr><td><strong>CircleCI</strong></td><td></td><td><a href="/pages/zLZclfIhlMLrYuMlUoj0">/pages/zLZclfIhlMLrYuMlUoj0</a></td><td data-object-fit="contain"><a href="/files/pXYSZpLIfI7U4aGyanS6">/files/pXYSZpLIfI7U4aGyanS6</a></td><td data-object-fit="contain"><a href="/files/YluI9bVjokahMLheoZil">/files/YluI9bVjokahMLheoZil</a></td></tr><tr><td><strong>Buildkite</strong></td><td></td><td><a href="/pages/WIV4TakX68XNsaRflRIV">/pages/WIV4TakX68XNsaRflRIV</a></td><td data-object-fit="contain"><a href="/files/dtlDPWXUgxHWdd4V2J78">/files/dtlDPWXUgxHWdd4V2J78</a></td><td></td></tr><tr><td><strong>Jenkins</strong></td><td></td><td><a href="/pages/hUi6WFMbJbtpX52PXBuL">/pages/hUi6WFMbJbtpX52PXBuL</a></td><td data-object-fit="contain"><a href="/files/pzrrfGQbhOZihVmmGxgI">/files/pzrrfGQbhOZihVmmGxgI</a></td><td></td></tr><tr><td><strong>Azure DevOps</strong></td><td></td><td><a href="/pages/2MW1rfB9DMQfiBwgj7qq">/pages/2MW1rfB9DMQfiBwgj7qq</a></td><td data-object-fit="contain"><a href="/files/5d72afm2dCsbAwBf3FNd">/files/5d72afm2dCsbAwBf3FNd</a></td><td></td></tr><tr><td><strong>AWS Code Build</strong></td><td></td><td><a href="/pages/bVecbLj0aFV2tmZhaCkk">/pages/bVecbLj0aFV2tmZhaCkk</a></td><td data-object-fit="contain"><a href="/files/LC3W7UV8gHN0MeA78qR8">/files/LC3W7UV8gHN0MeA78qR8</a></td><td></td></tr><tr><td><strong>Harness</strong></td><td></td><td><a href="/pages/fw4FpHXu3X9yEsoKOYQb">/pages/fw4FpHXu3X9yEsoKOYQb</a></td><td data-object-fit="contain"><a href="/files/XIXtKSQu6OndKpGQpaPb">/files/XIXtKSQu6OndKpGQpaPb</a></td><td data-object-fit="contain"><a href="/files/XIXtKSQu6OndKpGQpaPb">/files/XIXtKSQu6OndKpGQpaPb</a></td></tr><tr><td><strong>NX</strong></td><td></td><td><a href="/pages/EvoFOKv9JNKXeU9AflAo">/pages/EvoFOKv9JNKXeU9AflAo</a></td><td data-object-fit="contain"><a href="/files/uxDafsQxfynkytSpF1Iu">/files/uxDafsQxfynkytSpF1Iu</a></td><td data-object-fit="contain"><a href="/files/gG3P7y8arGeEbiUjeHw4">/files/gG3P7y8arGeEbiUjeHw4</a></td></tr></tbody></table>


# GitHub Actions

Running tests with Currents in GitHub Actions

Start with [Quick Start](/getting-started/ci-setup/github-actions/playwright-github-actions) for a workflow that records to Currents, then add what your setup needs from the articles below.

## Setup

* [Quick Start](/getting-started/ci-setup/github-actions/playwright-github-actions) — a workflow that records tests to Currents, and how to parallelize it.
* [Commit data for GitHub Actions](/getting-started/ci-setup/github-actions/commit-data-for-github-actions) — get the correct commit, branch and pull request on a run.
* [Custom Docker runners](/getting-started/ci-setup/github-actions/custom-docker-runners) — the environment variables to pass when the job runs in your own container.
* [Named Runners](/getting-started/ci-setup/github-actions/named-runners) — show which runner executed each spec file.

## Reruns

* [Re-run Only Failed Tests](/getting-started/ci-setup/github-actions/re-run-failed-only-tests) — re-run only the tests that failed, for [sharded](/getting-started/ci-setup/github-actions/re-run-failed-only-tests/re-run-failed-only-tests-sharded) and [orchestrated](/getting-started/ci-setup/github-actions/re-run-failed-only-tests/re-run-failed-only-tests-orchestrated-v2) runs.
* [Custom CI Build ID for Reruns](/getting-started/ci-setup/github-actions/re-run-failed-only-tests/custom-ci-build-id-for-reruns) — when your workflow sets its own CI build ID.

## Cancellation

* [Cancel Runs on Workflow Cancellation](/getting-started/ci-setup/github-actions/cancel-runs) — cancel the Currents run when the workflow is cancelled, so it does not sit in progress until the run timeout.

## Examples

The [currents-examples](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/github-actions) repository has complete workflows for sharding, orchestration, reruns and visual testing.


# Quick Start

Running Playwright tests in Parallel in GitHub Actions using Matrix Workflow

{% hint style="info" %}
Check out the example repository [https://github.com/currents-dev/currents-examples](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/github-actions)
{% endhint %}

### Quick Start

The example workflow file below shows how to run Playwright tests in GitHub actions.

<pre class="language-yaml"><code class="lang-yaml">name: Run Playwright Tests
on:
  pull_request:
    branches: [main]
jobs:
  run-tests:
    name: "Playwright Tests"
    timeout-minutes: 60
    runs-on: ubuntu-22.04
    container: <code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>

    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.event.pull_request.head.sha }}

      # https://github.com/actions/runner-images/issues/6775
      - run: |
          echo "$GITHUB_WORKSPACE"
          git config --global --add safe.directory "$GITHUB_WORKSPACE"

      - uses: actions/setup-node@v4
        with:
          node-version: "24.x"

      - name: Install dependencies
        run: npm ci

      - name: Playwright Tests
        continue-on-error: false
        env:
          CURRENTS_PROJECT_ID: ${{ vars.CURRENTS_PROJECT_ID }}
          CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
        run: npx playwright test
</code></pre>

The workflow above is the simplest way to get started. As the test suite grows, parallelization helps keep execution time fast.

### Parallelization

The [GitHub Actions matrix execution strategy](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix) can create multiple containers that run Playwright tests in parallel.

Each container receives a unique set of tests. This makes the browser test suite finish faster and gives feedback sooner.

<figure><img src="/files/8ZAetkXmthHKtz1KIulH" alt="Tests Parallelization with Github Actions"><figcaption><p>Tests Parallelization with Github Actions</p></figcaption></figure>

This can be done with [Playwright Sharding](https://playwright.dev/docs/test-sharding). Playwright can split tests between multiple CI machines using the `--shard` CLI flag. The examples below show how to set up sharding and orchestration.

{% hint style="info" %}
Looking for more ways to speed up CI? Read our [CI Optimization](/guides/ci-optimization) page.
{% endhint %}

### Examples

The [example repository](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/github-actions) showcases running Playwright tests in GitHub Actions. We've included several config files to exemplify the workflows:

* [test-basic-pwc.yml](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/github-actions/.github/workflows/test-basic-pwc.yml) - run Playwright tests in parallel using 3 shards of GitHub Actions Matrix and `pwc` command.
* [test-basic-reporter.yml](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/github-actions/.github/workflows/test-basic-reporter.yml) - run Playwright tests in parallel run using 3 shards of GitHub Actions Matrix and configuring Currents Reporter in `playwright.config.ts`.
* [test-or8n.yml](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/github-actions/.github/workflows/test-or8n.yml) - run Playwright tests in parallel Playwright using [Orchestration Setup](/guides/ci-optimization/playwright-orchestration) and GitHub Actions Matrix. Currents Orchestration speeds up CI runs by up to 40% (compared to native sharding) by optimally balancing tests between the available machines.
* [reruns-or8n.yml](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/github-actions/.github/workflows/reruns-or8n.yml) - Orchestration failed-only reruns.
* [argos-example.yml](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/github-actions/.github/workflows/argos-example.yml) - run Playwright tests in parallel using Currents Orchestration, use Argos CI for visual testing.


# Re-run Only Failed Tests

How to set up failed test reruns on GitHub Actions

When a workflow fails in GitHub Actions, the failed jobs can be re-run. However, Playwright needs extra setup to rerun only the failed tests.

For GitHub Actions, Currents provides the [Last Failed GitHub Action](https://github.com/currents-dev/playwright-last-failed) to simplify reruns with Playwright sharding or Currents Orchestration.

{% hint style="info" %}
The `playwright-last-failed` action uses `@currents/cmd` as a dependency. To control which version of `@currents/cmd` is used, install it as a dev dependency in `package.json` and use `npm ci` (or your package manager's equivalent frozen lockfile install) in GitHub Actions. Without this, the action installs `@currents/cmd` globally from npm, which may pull a different version than what's pinned in your lockfile.
{% endhint %}

Select the guide that matches your setup:

* [Sharded runs](/getting-started/ci-setup/github-actions/re-run-failed-only-tests/re-run-failed-only-tests-sharded) — fixed shard count and native Playwright `--shard` parallelism
* [Orchestrated runs](/getting-started/ci-setup/github-actions/re-run-failed-only-tests/re-run-failed-only-tests-orchestrated-v2) — `pwc-p discover` and `pwc-p run`
* [Custom CI Build ID for Reruns](/getting-started/ci-setup/github-actions/re-run-failed-only-tests/custom-ci-build-id-for-reruns) — for sharded or orchestrated runs with a non-default CI build ID


# Sharded runs

How to set up failed test reruns for sharded Playwright runs on GitHub Actions

When using native Playwright `--shard` parallelism, the [Last Failed GitHub Action](https://github.com/currents-dev/playwright-last-failed) can fetch and rerun failed tests from the last workflow run.

Step-by-step guide:

<details>

<summary>Add the currents-dev/playwright-last-failed step</summary>

Add a step to the workflow before the test step runs.

<pre class="language-yaml"><code class="lang-yaml">- name: Playwright Last Failed action
<strong>  id: last-failed-action
</strong><strong>  uses: currents-dev/playwright-last-failed@v2
</strong>  with:
    pw-output-dir: basic/test-results
    matrix-index: ${{ matrix.shard }}
    matrix-total: ${{ strategy.job-total }}
</code></pre>

See the [action configuration for details](https://github.com/currents-dev/playwright-last-failed/blob/main/action.yml).

</details>

<details>

<summary>A full example</summary>

<pre class="language-yaml"><code class="lang-yaml">name: failed-only-reruns

on:
  push:

jobs:
  test-reporter:
    strategy:
      fail-fast: false
      matrix:
        shard: [1, 2, 3]
    timeout-minutes: 60
    runs-on: ubuntu-latest
    container: <code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>
    env:
      CURRENTS_PROJECT_ID: ${{ vars.CURRENTS_PROJECT_ID }}
      CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
      CURRENTS_CI_BUILD_ID: ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.ref }}
      - run: |
          echo "$GITHUB_WORKSPACE"
          git config --global --add safe.directory "$GITHUB_WORKSPACE"
      - uses: actions/setup-node@v4
        with:
          node-version: "24.x"
      - name: Install dependencies
        run: |
          npm ci
          npx playwright install chrome
      - name: Playwright Last Failed action
        id: last-failed-action
        uses: currents-dev/playwright-last-failed@v2
        with:
          pw-output-dir: basic/test-results
          matrix-index: ${{ matrix.shard }}
          matrix-total: ${{ strategy.job-total }}
      - name: Playwright Tests
        working-directory: ./basic
        run: |
          COMMAND="npx playwright test --config playwright.config.reporter.ts ${{ steps.last-failed-action.outputs.extra-pw-flags }}"
          echo "Running command: $COMMAND"
          $COMMAND
</code></pre>

</details>

{% hint style="info" %}
For a workflow with a custom CI build ID, see [Custom CI Build ID for Reruns](/getting-started/ci-setup/github-actions/re-run-failed-only-tests/custom-ci-build-id-for-reruns).
{% endhint %}

Full examples:

* [rerun-shards-pwc.yml](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/github-actions/.github/workflows/rerun-shards-pwc.yml) - rerun only the tests that failed in the previous run, using the `pwc` helper command from `@currents/playwright`.
* [rerun-shards-reporter.yml](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/github-actions/.github/workflows/rerun-shards-reporter.yml) - rerun only the tests that failed in the previous run, using reporter setup in `playwright.config.ts`.


# Orchestrated runs

How to set up failed test reruns for Orchestration on GitHub Actions

{% hint style="info" %}
Currents Orchestration assigns tests to all available CI runners, so **Re-run all jobs** should be used instead of re-running only failed jobs. Read more at [Orchestrated runs](/guides/ci-optimization/re-run-only-failed-tests/re-run-only-failed-tests-orchestrated-v2).
{% endhint %}

### Prerequisites

* [Orchestration Setup](/guides/ci-optimization/playwright-orchestration) — `@currents/playwright` on its latest version.
* `CURRENTS_RECORD_KEY`, `CURRENTS_PROJECT_ID`, and `CURRENTS_API_KEY` configured in GitHub Actions secrets
* [playwright-last-failed@v2](https://github.com/currents-dev/playwright-last-failed) — exposes `extra-discovery-flags` for the discover step

### Step-by-step

#### Install `@currents/cmd`

The `playwright-last-failed` action depends on `@currents/cmd`. Pin it in the repository for reproducible installs:

```bash
npm i -D @currents/cmd
```

#### Set `CURRENTS_API_KEY`

Create an API key in the Currents Dashboard (see [Authentication](/api/get-started/authentication)) in addition to the Record Key. Add it as a [GitHub Actions secret](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions).

```yaml
env:
  CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
  CURRENTS_API_KEY: ${{ secrets.CURRENTS_API_KEY }}
```

#### Add the Playwright Last Failed step

```yaml
- name: Playwright Last Failed action
  id: last-failed-action
  uses: currents-dev/playwright-last-failed@v2
  with:
    or8n: true
    pw-output-dir: basic/test-results
```

When `or8n: true`, the action sets `extra-discovery-flags` for `pwc-p discover` (for example `--last-failed` on reruns).

#### Discover, then run

Run discovery once per job (or in a dedicated setup job that shares the test list artifact), then orchestrate with `pwc-p run`:

```yaml
- name: Discover tests to run
  working-directory: ./basic
  run: |
    npx pwc-p discover \
      --pwc-discovery-file tests.txt \
      ${{ steps.last-failed-action.outputs.extra-discovery-flags }}

- name: Playwright Tests
  working-directory: ./basic
  run: |
    npx pwc-p run \
      --pwc-discovery-file tests.txt
```

On the first run, `extra-discovery-flags` is empty and discovery records the full suite. On a workflow rerun, it includes `--last-failed` so only previously failed tests are orchestrated.

### Full example

{% code lineNumbers="true" %}

```yaml
name: failed-only-or8n-v2

on:
  push:

jobs:
  test-or8n:
    strategy:
      fail-fast: false
      matrix:
        shard: [1, 2, 3]
    timeout-minutes: 60
    runs-on: ubuntu-latest
    container: mcr.microsoft.com/playwright:v1.60.0-noble
    env:
      CURRENTS_PROJECT_ID: ${{ vars.CURRENTS_PROJECT_ID }}
      CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
      CURRENTS_CI_BUILD_ID: ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}
      CURRENTS_API_KEY: ${{ secrets.CURRENTS_API_KEY }}
    steps:
      - uses: actions/checkout@v4
        with:
          ref: ${{ github.ref }}
      - run: |
          echo "$GITHUB_WORKSPACE"
          git config --global --add safe.directory "$GITHUB_WORKSPACE"
      - uses: actions/setup-node@v4
        with:
          node-version: "24.x"
      - name: Install dependencies
        run: |
          npm ci
          npx playwright install chrome
      - name: Playwright Last Failed action
        id: last-failed-action
        uses: currents-dev/playwright-last-failed@v2
        with:
          or8n: true
          pw-output-dir: basic/test-results
      - name: Discover tests to run
        working-directory: ./basic
        run: |
          npx pwc-p discover \
            --pwc-discovery-file tests.txt \
            ${{ steps.last-failed-action.outputs.extra-discovery-flags }}
      - name: Playwright Tests
        working-directory: ./basic
        run: |
          npx pwc-p run --pwc-discovery-file tests.txt
```

{% endcode %}

{% hint style="info" %}
For a workflow with a custom CI build ID, see [Custom CI Build ID for Reruns](/getting-started/ci-setup/github-actions/re-run-failed-only-tests/custom-ci-build-id-for-reruns).
{% endhint %}

The full workflow is included above. For V1, see [reruns-or8n.yml](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/github-actions/.github/workflows/reruns-or8n.yml).


# Custom CI Build ID for Reruns

How to configure custom CI build IDs for failed test reruns on GitHub Actions

The [Last Failed GitHub Action](https://github.com/currents-dev/playwright-last-failed) uses the default CI build ID pattern to fetch the previous run information:

`${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}`

When you use a custom [CI Build ID](/guides/parallelization-guide/ci-build-id) for your test runs, set `previous-ci-build-id` to match that custom pattern.

<figure><img src="/files/GZ5RqYzyEG63BwroviNI" alt=""><figcaption><p>Using custom CI build ID for reruns</p></figcaption></figure>

## For Sharded Runs (with matrix strategy)

Use the matrix index and total to ensure each shard reruns its own failed tests:

{% code overflow="wrap" %}

```yaml

# an example for custom value like:
# currents-${{ github.run_id }}-${{ github.run_attempt }}
- name: Compute previous run attempt
  id: previous-attempt
  run: echo "previous=$(( ${{ github.run_attempt }} - 1 ))" >> "$GITHUB_OUTPUT"
- name: Playwright Last Failed action
  uses: currents-dev/playwright-last-failed@v2
  with:
    # if a custom CI build id is used, set "previous-ci-build-id" accordingly
    previous-ci-build-id: currents-${{ github.run_id }}-${{ steps.previous-attempt.outputs.previous }}
    pw-output-dir: basic/test-results
    matrix-index: ${{ matrix.shard }}
    matrix-total: ${{ strategy.job-total }}
```

{% endcode %}

## For Orchestrated Runs (Currents assigns tests across machines)

Omit the matrix parameters and use `or8n: true` so Currents handles test distribution:

{% code overflow="wrap" %}

```yaml
- name: Compute previous run attempt
  id: previous-attempt
  run: echo "previous=$(( ${{ github.run_attempt }} - 1 ))" >> "$GITHUB_OUTPUT"
- name: Playwright Last Failed action
  uses: currents-dev/playwright-last-failed@v2
  with:
    or8n: true
    previous-ci-build-id: currents-${{ github.run_id }}-${{ steps.previous-attempt.outputs.previous }}
    pw-output-dir: basic/test-results
```

{% endcode %}


# Cancel Runs on Workflow Cancellation

Cancel the Currents run when a GitHub Actions workflow is cancelled

A cancelled workflow stops reporting mid-run. Currents has no way to tell that apart from a job that is still working, so the run stays in progress until it hits the project's [Run Timeouts](/dashboard/runs/run-timeouts). That leaves a run sitting in the feed as if it were live, for up to an hour.

Add a step that cancels the run when the job is cancelled:

```yaml
- name: Cancel the Currents run
  if: ${{ cancelled() }}
  run: npx currents cancel
```

`if: cancelled()` runs the step only when the workflow was cancelled, so it costs nothing on a normal run.

## Which credential to use

[`currents cancel`](/resources/reporters/currents-cmd/currents-cancel) authenticates with the [Record Key](/guides/record-key) the job already uses to report results, so no additional secret is needed. It identifies the run by its [CI Build ID](/guides/parallelization-guide/ci-build-id) or its run ID, which means the same step works on any CI provider.

{% hint style="warning" %}
Set `CURRENTS_CI_BUILD_ID` on the job, as the example below does. Without it Currents generates a CI Build ID that includes the test framework. The cancelling step cannot reconstruct that value from the environment, so it reports that there is no run to cancel.
{% endhint %}

The [cancel-run-gh-action](https://github.com/currents-dev/cancel-run-gh-action) does the same as a GitHub action and accepts either a record key or an [API Keys](/dashboard/administration/api-keys):

```yaml
- name: Cancel the Currents run
  if: ${{ cancelled() }}
  uses: currents-dev/cancel-run-gh-action@v1
```

With no inputs, the action reads `CURRENTS_RECORD_KEY`, `CURRENTS_PROJECT_ID` and `CURRENTS_CI_BUILD_ID` from the environment. Declare them on the job, the way the full example below does — a step's `env` is visible only to that step, so variables set on the reporting step reach the cancelling step empty.

Like the command, the action can also identify the run by its run ID, through the `run-id` input or `CURRENTS_RUN_ID`. The [action's README](https://github.com/currents-dev/cancel-run-gh-action#inputs) lists every input.

## Full example

```yaml
name: Run Playwright Tests
on:
  pull_request:
    branches: [main]

# Cancel the previous run when a new commit is pushed to the same branch.
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  run-tests:
    runs-on: ubuntu-latest
    env:
      CURRENTS_PROJECT_ID: ${{ vars.CURRENTS_PROJECT_ID }}
      CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
      CURRENTS_CI_BUILD_ID: ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: "24.x"
      - run: npm ci

      - name: Playwright Tests
        run: npx playwright test

      - name: Cancel the Currents run
        if: ${{ cancelled() }}
        run: npx currents cancel
```

`concurrency` with `cancel-in-progress: true` is what makes this worth setting up: every push to a branch cancels the workflow still running for the previous commit, and each of those leaves a run behind.

## Notes

* **Parallel jobs.** Every job of a parallelized run records into the same run, and every one of them can run the cancellation step. Cancelling a run that is already cancelled succeeds.
* **Nothing recorded yet.** A workflow cancelled before the first results reached Currents has no run to cancel. The step reports that and succeeds, so it does not add a failed step to an already cancelled workflow.
* **Hard cancellations.** A job killed without running its remaining steps never reaches the step. That covers a cancelled job that does not honour `if: cancelled()`, and a runner that disappears. Those runs still end at the inactivity timeout.

See [Cancelling Runs](/dashboard/runs/cancel-run) for what cancelling a run affects: test statuses, plan usage, analytics and integrations.


# Commit data for GitHub Actions

How to get correct git commit information when using GitHub Actions

### GitHub Pull Request Title, Issue Link and Branch Name

{% hint style="info" %}
**Update Jan 30, 2024**

`@currents/playwright@0.12.0` and `cypress-cloud@1.10.0` automatically detect Pull Request information when running in GitHub Actions.
{% endhint %}

The recent (Jan 30, 2024) releases of `@currents/playwright@0.12.0` and `cypress-cloud@1.10.0` better handle git information when running in GitHub Actions triggered by `` `pull_request` `` trigger.

* PR title becomes Run Title (instead of a generic message PR #XX)
* Effective Branch becomes the PR HEAD branch name - allowing more meaningful usage in analytics and notification filters
* UI will display a direct link to GitHub Pull Request issue

<figure><img src="/files/XfVLhXPPPNoaohq1MwLK" alt=""><figcaption><p>Capturing GitHub PR data</p></figcaption></figure>

### Temporary commit in GitHub Pull Requests

Running tests using GitHub Actions can generate confusing git information. For example, instead of the last commit message (or pull request title), one can see something like:

```
Merge de7282540ac30ee4e32a0b1fede4f6391b4cc321 into fa58941d8a807b83ec5a3e5bfb83418ce12173c7
```

Also, the branch name becomes `refs/pull/12/merge` instead of the expected branch name. Why is that happening?

That happens when your GitHub Actions workflow is triggered by [`pull_request`](https://docs.github.com/en/github-ae@latest/actions/using-workflows/events-that-trigger-workflows#pull_request).

It changes the behaviour of `@actions/checkout` - it creates a **new merge commit,** which is created from merging the base to the head.

Specifically:

* it performs `git checkout` to `github.ref` environment variable
* it sets the git `ref` to `refs/remotes/pull/##/merge`
* it sets the commit SHA to an arbitrary value that is different from the commit that triggered the workflow

For example, a developer creates a pull request from the `feat/login` branch to be merged into the `main` branch with the title "*Add new login feature*". When the GitHub Actions workflow is triggered, instead of checking out the `feat/login` branch, the action creates a merge commit. In the GitHub Actions log, the commit message appears as "*Merge de7282540ac30ee4e32a0b1fede4f6391b4cc321 into fa58941d8a807b83ec5a3e5bfb83418ce12173c7*", which is a merge of the `feat/login` branch into the `main` branch. Consequently, the branch name in the CI environment shows as `refs/pull/12/merge`, not the expected `feat/login`.

To change the default behaviour and checkout the triggering commit, use the following `@actions/checkout` configuration

```yaml
- uses: actions/checkout@v2
  with:
    ref: ${{ github.event.pull_request.head.sha }}
```

The workflow will check out the last commit from the **head** branch of the pull request that triggered the workflow. Beware, that this approach might not detect issues that could arise when the pull request is eventually merged into the base branch. If the base branch has been updated since the pull request was created, there might be merge conflicts or integration issues that won't be detected with this configuration.

Read more about [GitHub Actions and `pull_request`](https://frontside.com/blog/2020-05-26-github-actions-pull_request/) (by frontside.com).


# Custom Docker runners

Self hosted/managed docker runners

Github Actions gives you the option to use your custom docker containers to execute your tests instead of directly using their built-in runners.

This usually leads to the loss of git information and environment variables not be available, so in this case for Currents to be able to gather all the information needed you need to setup the needed environment variables accordingly.

The best way to access this variables is through the context objects, specifically in this case the `github` one.

```
GITHUB_WORKFLOW=${{github.workflow}}
GITHUB_ACTION=true
GITHUB_EVENT_NAME=${{github.event_name}}
GITHUB_RUN_ID=${{github.run_id}}
GITHUB_RUN_ATTEMPT=${{github.run_attempt}}
GITHUB_REPOSITORY=${{github.repository}}

COMMIT_INFO_BRANCH=${{github.ref_name}}
COMMIT_INFO_MESSAGE=${{github.event.head_commit.message}}
COMMIT_INFO_EMAIL=${{github.event.head_commit.author.email}}
COMMIT_INFO_AUTHOR=${{github.event.head_commit.author.name}}
COMMIT_INFO_SHA=${{github.sha}}
COMMIT_INFO_TIMESTAMP=${{github.event.head_commit.timestamp}}
COMMIT_INFO_REMOTE=${{github.repository}}
```

Adding these environment variables to your `.yml` file will allow your custom docker runner to report the correct information to Currents and have all the available information in the dashboard to use it as a usual Github Action tests execution.


# Named Runners

Github Actions provides the ability to use human-readable runner names, and Currents displays these in the dashboard, allowing you to see which runner executed each spec file.

The typical method for creating a matrix strategy for runners in Github Actions is as follows:

```yaml
matrix:
    shard: [1/3, 2/3, 3/3]
```

However, there are several ways to achieve this, such as naming the machines with human-readable names like this:

```yaml
matrix:
    include:
        - runner_name: "Runner 1"
	    shard: 1/2
	- runner_name: "Runner 2"
      	    shard: 2/2
```

This creates jobs that looks like this in Github Actions:

<figure><img src="/files/wGRGWaz5Us2F8FXh0kAm" alt="" width="310"><figcaption><p>Named Runners</p></figcaption></figure>

The final step is to visualize this in the Currents dashboard, which can be done by passing the runner name into the CURRENTS\_MACHINE\_ID environment variable:

```yaml
- name: Run Playwright tests
    env:
        CURRENTS_MACHINE_ID: ${{ matrix.runner_name }}
    run: npx pwc --key ${{secrets.CURRENTS_RECORD_KEY}} --project-id ${{secrets.CURRENTS_PROJECT_ID}} --ci-build-id ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt}} --shard ${{ matrix.shard }}
```

The `machineId` will now be visible in the Currents dashboard for each spec file, making it possible to identify which machine or job executed a specific spec file.

<figure><img src="/files/DFgpxRyUL4KnIkgNsgdg" alt="" width="326"><figcaption><p>Spec file details view</p></figcaption></figure>

Here is a complete example of a Github Action yaml file with this setup:

<details>

<summary><code>workflow.yaml</code></summary>

```yaml
name: Playwright Tests
on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]
jobs:
  playwright-tests:
    timeout-minutes: 60
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        include:
          - runner_name: "Runner 1"
            shard: 1/2
          - runner_name: "Runner 2"
            shard: 2/2
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: "24.x"

      - name: Install Playwright browsers
        run: npx playwright install --with-deps

      - name: Install dependencies
        run: npm install

      - name: Run Playwright tests
        env:
          CURRENTS_MACHINE_ID: ${{ matrix.runner_name }}
        run: npx pwc --key ${{secrets.CURRENTS_RECORD_KEY}} --project-id ${{secrets.CURRENTS_PROJECT_ID}} --ci-build-id ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt}} --shard ${{ matrix.shard }}
```

</details>

It is also possible to add a dynamic number of named runners by including an extra job in the workflow:

```yaml
generate-matrix:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - name: Set number of shards
        id: set-shards
        run: echo "SHARDS=5" >> $GITHUB_ENV

      - name: Generate matrix
        id: set-matrix
        run: |
          SHARDS=${SHARDS:-2}  # Default to 2 if not set
          MATRIX="{\"include\":["
          for i in $(seq 1 $SHARDS); do
            if [ $i -gt 1 ]; then MATRIX="$MATRIX,"; fi
            MATRIX="$MATRIX{\"runner_name\":\"MyRunner $i\",\"shard\":\"$i/$SHARDS\"}"
          done
          MATRIX="$MATRIX]}"
          echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"
```

It is only needed to update `run: echo "SHARDS=5" >> $GITHUB_ENV` into the shards number is required.

A complete example can be found here:

<details>

<summary><code>dynamic-runners-workflow.yaml</code></summary>

```yaml
name: Playwright Tests
on:
  push:
    branches: [main, master]
  pull_request:
    branches: [main, master]
jobs:
  generate-matrix:
    runs-on: ubuntu-latest
    outputs:
      matrix: ${{ steps.set-matrix.outputs.matrix }}
    steps:
      - name: Set number of shards
        id: set-shards
        run: echo "SHARDS=5" >> $GITHUB_ENV

      - name: Generate matrix
        id: set-matrix
        run: |
          SHARDS=${SHARDS:-2}  # Default to 2 if not set
          MATRIX="{\"include\":["
          for i in $(seq 1 $SHARDS); do
            if [ $i -gt 1 ]; then MATRIX="$MATRIX,"; fi
            MATRIX="$MATRIX{\"runner_name\":\"MyRunner $i\",\"shard\":\"$i/$SHARDS\"}"
          done
          MATRIX="$MATRIX]}"
          echo "matrix=$MATRIX" >> "$GITHUB_OUTPUT"

  playwright-tests:
    needs: generate-matrix 
    timeout-minutes: 60
    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix: ${{ fromJson(needs.generate-matrix.outputs.matrix) }}
    steps:
      - name: Log matrix
        run: |
          echo "Running on ${{ matrix.runner_name }} with shard ${{ matrix.shard }}"
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: "24.x"

      - name: Install Playwright browsers
        run: npx playwright install --with-deps

      - name: Install dependencies
        run: npm install

      - name: Run Playwright tests
        env:
          CURRENTS_MACHINE_ID: ${{ matrix.runner_name }}
        run: npx pwc --key ${{secrets.CURRENTS_RECORD_KEY}} --project-id ${{secrets.CURRENTS_PROJECT_ID}} --ci-build-id ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt}} --shard ${{ matrix.shard }}
```

</details>


# GitLab


# Quick Start

Running Playwright test in parallel using GitLab CI/CD

{% hint style="info" %}
TL;DR take a look at the example repository:

<https://gitlab.com/currents.dev/gitlab-playwright-currents>
{% endhint %}

The example [`.gitlab-ci.yml`](https://gitlab.com/currents.dev/gitlab-playwright-currents/-/blob/main/.gitlab-ci.yml) file creates a GitLab CI pipeline with 3 workers using 3 [Playwright Shards](https://playwright.dev/docs/test-sharding):

<pre class="language-yaml"><code class="lang-yaml"># .gitlab-ci.yml
default:
  image: <code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>

stages:
  - test

test:
  image: <code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>
  stage: test
  parallel: 3

  script:
    - npm ci
    - npx playwright install
    - cd ./basic
    - npx pwc --key $CURRENTS_RECORD_KEY --project-id bnsqNa --shard=$CI_NODE_INDEX/$CI_NODE_TOTAL
</code></pre>

<figure><img src="/files/xKblXIO6vimlU1BffKGC" alt=""><figcaption><p>Running 3 parallel jobs Playwright jobs in GitLab CI</p></figcaption></figure>

### Setup <a href="#user-content-setup" id="user-content-setup"></a>

* Create an account at <https://app.currents.dev> and grab the **Project ID** and **Record Key**.
* Add `CURRENTS_RECORD_KEY` as [GitLab CI/CD Secrets](https://docs.gitlab.com/ee/ci/variables/) (make sure it's not protected)

Additional resources:

* Playwright Features on Currents: <https://currents.dev/playwright>
* Integration Documentation: <https://currents.dev/readme/integration-with-playwright/currents-playwright>
* CI Build ID Guide: <https://currents.dev/readme/guides/cypress-ci-build-id>

### GitLab CI Playwright Results <a href="#user-content-gitlab-ci-playwright-results" id="user-content-gitlab-ci-playwright-results"></a>

The results are being reported to Currents for more efficient troubleshooting, and monitoring test suite flakiness and performance.

Currents will collect the following information:

* console output
* screenshots
* videos
* trace files
* timing
* outcomes
* flaky tests
* error details
* tags for more convenient management of the tests

#### GitLab Merge Request Notes <a href="#user-content-gitlab-merge-request-notes" id="user-content-gitlab-merge-request-notes"></a>

Take a look at the example merge request: <https://gitlab.com/currents.dev/gitlab-playwright-currents/-/merge_requests/3>

When [GitLab integration](https://currents.dev/readme/integrations/gitlab) is enabled, Currents will post a Merge Commit note with run results:

<figure><img src="/files/E2HPn1tIwQQH5jvINgMo" alt=""><figcaption><p>Currents Merge Request Notes</p></figcaption></figure>

In addition, Currents will post an [External Status check](https://docs.gitlab.com/ee/user/project/merge_requests/status_checks.html) for every Playwright project configured. For example:

<figure><img src="/files/4LialYUNFSBUXsXQitDS" alt=""><figcaption><p>Example of GitLab CI External Status Check</p></figcaption></figure>


# Re-run Only Failed Tests

How to setup failed tests re-run on GitLab

When a workflow fails in GitLab CI/CD you have the option to re-run the failed jobs. However, an additional setup is required for properly configuring Playwright for rerunning only the failed tests. See [Re-run Only Failed Tests](https://docs.currents.dev/guides/re-run-only-failed-tests) guide for details.

<figure><img src="/files/AStaeXiLT5u1zbewLWCh" alt=""><figcaption><p>Rerunning only the failed jobs on GitLab CI/CD</p></figcaption></figure>

#### Playwright Sharding

If you're using [Playwright Sharding](https://docs.currents.dev/guides/parallelization-guide/pw-parallelization/playwright-sharding) for running your tests in parallel, use [currents cache](https://docs.currents.dev/resources/reporters/currents-cmd/currents-cache) command to store the last run results and simplify re-run workflows.

Example workflows are available in our GitLab repositories:

* [reruns-pwc.yml](https://gitlab.com/currents.dev/gitlab-playwright-currents/-/blob/main/.gitlab/ci/with-reruns-pwc.yml?ref_type=heads) - re-run only failed tests on GitLab CI using 3 parallel runners and Playwright Shards + Currents `pwc` command
* [reruns-reporter.yml](https://gitlab.com/currents.dev/gitlab-playwright-currents/-/blob/main/.gitlab/ci/with-reruns-reporter.yml?ref_type=heads) - re-run only failed tests on GitLab CI using 3 parallel runners and Playwright Shards + Currents reporter in `playwright.config.ts`

**Install the @currents/cmd package**

```bash
npm i -D @currents/cmd
```

**Add an after\_script to upload the cache**

Add an `after_script` to the end of your job that uploads run information to the cache

```yaml
after_script:
    # Save the last-run.json to cache after the run
    - npx currents cache set --pw-output-dir basic/test-results --preset last-run
```

See the [configuration for details](/resources/reporters/currents-cmd#cache-test-artifacts) on the flags.

**Add a download cache step to your script**

Update your job script to download the cache prior to running tests

```yaml
script:
    - npm ci
    # Grab the last run from cache. CacheId is automatically calculated for GitLab, and a .currents_env file is created with extra env variables
    # $EXTRA_PW_FLAGS will contain the correct --shard flag, as well as --last-failed if this was a retried job
    # $RUN_ATTEMPT will be populated with a value 1+ based on how many times this job has been retried
    - npx currents cache get --preset last-run --continue
    - cat .currents_env >> $GITLAB_ENV && source .currents_env
    - npx playwright install
    # Run playwright, provide a build id with the run-attempt included and also pass $EXTRA_PW_FLAGS 
    - export CURRENTS_CI_BUILD_ID="reporter-$CI_PIPELINE_ID-$RUN_ATTEMPT"
    - npx playwright test -c playwright.config.reporter.ts $EXTRA_PW_FLAGS

```

See the [configuration for details](/resources/reporters/currents-cmd#cache-test-artifacts) on the flags.

**Full example**

<pre class="language-yaml"><code class="lang-yaml">test-rerun-reporter:
  image: <code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>
  stage: test
  parallel: 3
  variables:
    CURRENTS_PROJECT_ID: ${{ vars.CURRENTS_PROJECT_ID }}
    # CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
  script:
    - npm ci
    # Grab the last run from cache. CacheId is automatically calculated for GitLab, and a .currents_env file is created with extra env variables
    # $EXTRA_PW_FLAGS will contain the correct --shard flag, as well as --last-failed if this was a retried job
    # $RUN_ATTEMPT will be populated with a value 1+ based on how many times this job has been retried
    - npx currents cache get --preset last-run --continue
    - cat .currents_env >> $GITLAB_ENV &#x26;&#x26; source .currents_env
    - npx playwright install
    - cd ./basic
    # Run playwright, provide a build id with the run-attempt included and also pass $EXTRA_PW_FLAGS 
    - export CURRENTS_CI_BUILD_ID="reporter-$CI_PIPELINE_ID-$RUN_ATTEMPT"
    - npx playwright test -c playwright.config.reporter.ts $EXTRA_PW_FLAGS
  after_script:
    # Save the last-run.json to cache after the run
    - npx currents cache set --pw-output-dir basic/test-results --preset last-run
</code></pre>

#### Currents Orchestration

In case you're using Currents Orchestration for running Playwright tests in parallel, use [currents api](/resources/reporters/currents-cmd/currents-api) to fetch the results of the last run from the [API](https://docs.currents.dev/api/).

* [Orchestration Setup](/guides/ci-optimization/playwright-orchestration)
* [Orchestration (v1)](/guides/ci-optimization/playwright-orchestration/playwright-orchestration-v1)

\
An example workflow is available in our GitLab demo repository

* [rerun-or8n.yml](https://gitlab.com/currents.dev/gitlab-playwright-currents/-/blob/main/.gitlab/ci/with-reruns-pwcp.yml?ref_type=heads) - rerun only failed tests on GitLab CI/CD with Currents Orchestration

**Install the @currents/cmd package**

```bash
npm i -D @currents/cmd
```

**Set `CURRENTS_API_KEY` environment variable**

Obtain an API key (see [Authentication](/api/get-started/authentication)) and [Record Key](/guides/record-key) from Currents Dashboard and set [GitLab CI/CD variable](https://docs.gitlab.com/ee/ci/variables/) accordingly

```yaml
variables:
    CURRENTS_PROJECT_ID: ${{ vars.CURRENTS_PROJECT_ID }}
    CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
    CURRENTS_API_KEY: ${{ secrets.CURRENTS_API_KEY }}
```

**Add an after\_script to upload the cache**

Add an `after_script` to the end of your job that uploads GitLab retry information to the cache

```yaml
after_script:
    # Save the last-run.json to cache after the run
    - npx currents cache set --pw-output-dir basic/test-results --preset last-run
```

See [currents cache](/resources/reporters/currents-cmd/currents-cache) documentation for all the available options

**Add an API get-run step to your script**

Update your job script to download the cache prior to running tests, and then also grab the previous run.

{% code overflow="wrap" %}

```yaml
script:
    - npm ci
    # Grab the last run from cache. CacheId is automatically calculated for GitLab, and a .currents_env file is created with extra env variables
    # $EXTRA_PWCP_FLAGS will contain --last-failed if this was a retried job (pass to discover, not run)
    # $RUN_ATTEMPT will be populated with a value 1+ based on how many times this job has been retried
    - npx currents cache get --preset last-run --continue
    - cat .currents_env >> $GITLAB_ENV && source .currents_env
    # Grab the complete last run from the API so orchestration can find all the failures
    - npx currents api get-run --branch=$CI_COMMIT_REF_NAME --pw-last-run --output=basic/test-results/.last-run.json || true
    - npx playwright install
    # Discover tests to run; $EXTRA_PWCP_FLAGS includes --last-failed on retried jobs
    - npx pwc-p discover --pwc-discovery-file tests.txt $EXTRA_PWCP_FLAGS
    # Run pwc-p with the discovery file and a build id that includes the run attempt
    - npx pwc-p run --ci-build-id=or8n-$CI_PIPELINE_ID-$RUN_ATTEMPT --pwc-discovery-file tests.txt

```

{% endcode %}

See [currents api](/resources/reporters/currents-cmd/currents-api) documentation to explore all the available options

**Full example**

<pre class="language-yaml"><code class="lang-yaml">test-rerun-pwcp:
  image: <code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>
  stage: test
  parallel: 3
  variables:
    CURRENTS_PROJECT_ID: ${{ vars.CURRENTS_PROJECT_ID }}
    # CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
    # CURRENTS_API_KEY: ${{ secrets.CURRENTS_API_KEY }}
  script:
    - npm ci
    # Grab the last run from cache. CacheId is automatically calculated for GitLab, and a .currents_env file is created with extra env variables
    # $EXTRA_PWCP_FLAGS will contain --last-failed if this was a retried job (pass to discover, not run)
    # $RUN_ATTEMPT will be populated with a value 1+ based on how many times this job has been retried
    - npx currents cache get --preset last-run --continue
    - cat .currents_env >> $GITLAB_ENV &#x26;&#x26; source .currents_env
    # Grab the complete last run from the API so orchestration can find all the failures
    - npx currents api get-run --branch=$CI_COMMIT_REF_NAME --pw-last-run --output=basic/test-results/.last-run.json || true
    - npx playwright install
    # Discover tests to run; $EXTRA_PWCP_FLAGS includes --last-failed on retried jobs
    - npx pwc-p discover --pwc-discovery-file tests.txt $EXTRA_PWCP_FLAGS
    # Run pwc-p with the discovery file and a build id that includes the run attempt
    - npx pwc-p run --ci-build-id=or8n-$CI_PIPELINE_ID-$RUN_ATTEMPT --pwc-discovery-file tests.txt
  after_script:
    # Save the last-run to cache in order to track the run attempts
    - npx currents cache set --preset last-run --pw-output-dir basic/test-results
</code></pre>


# Custom Docker runners

Self hosted/managed docker runners

Gitlab CI/CD gives you the option to use your custom docker containers to execute your tests instead of directly using their built-in runners.

This usually leads to the loss of git information and environment variables not be directly available, so in this case for Currents to be able to gather all the information needed you need to setup the needed environment variables accordingly.

```
GITLAB_CI=true
CI_PIPELINE_ID=$CI_PIPELINE_ID
CI_PIPELINE_URL=$CI_PIPELINE_URL
CI_BUILD_ID=$CI_BUILD_ID
CI_JOB_ID=$CI_JOB_ID
CI_JOB_URL=$CI_JOB_URL
CI_JOB_NAME=$CI_JOB_NAME
GITLAB_HOST=$GITLAB_HOST
CI_PROJECT_ID=$CI_PROJECT_ID
CI_PROJECT_URL=$CI_PROJECT_URL
CI_REPOSITORY_URL=$CI_REPOSITORY_URL
CI_ENVIRONMENT_URL=$CI_ENVIRONMENT_URL
CI_DEFAULT_BRANCH=$CI_DEFAULT_BRANCH

COMMIT_INFO_BRANCH=$CI_COMMIT_BRANCH
COMMIT_INFO_MESSAGE=$CI_COMMIT_MESSAGE
COMMIT_INFO_SHA=$CI_COMMIT_SHA
COMMIT_INFO_REMOTE=$CI_REPOSITORY_URL
```

Adding these environment variables to your `.yml` file will allow your custom docker runner to report the correct information to Currents and have all the available information in the dashboard to use it as a usual Gitlab CI/CD tests execution.

## Fallback: Using CURRENTS\_CI\_URL

If your GitLab environment variables are not forwarded to the Docker container and auto-detection fails, you can explicitly provide the CI URL using the `CURRENTS_CI_URL` environment variable:

```
CURRENTS_CI_URL=$CI_JOB_URL
```

Or for GitLab pipelines:

```
CURRENTS_CI_URL=$CI_PIPELINE_URL
```

This ensures the run link in the Currents Dashboard points back to the correct GitLab job or pipeline. See [Configuration](/resources/reporters/currents-playwright/configuration) for more details on `CURRENTS_CI_URL`.


# Jenkins

Running Playwright tests in parallel with Jenkins and Currents Dashboard

Here's an example of Jenkins pipeline that is running Playwright tests in parallel on 2 workers.

The pipeline will be running 2 workers, based on <code class="expression">space.vars.PW\_IMAGE\_ROUTE + ":" + space.vars.LATEST\_PW\_IMAGE\_VERSION</code> Docker image. Those workers will run all the tests in parallel.

The steps are:

* Use <code class="expression">space.vars.PW\_IMAGE\_ROUTE + ":" + space.vars.LATEST\_PW\_IMAGE\_VERSION</code> as the base image
* Install the necessary dependencies: `playwright` and `@currents/playwright`
* Populate the environment variable `CURRENTS_RECORD_KEY` using [Jenkins Credentials Store](https://jenkins.io/doc/book/using/using-credentials/). Learn more about [Record Key](/guides/record-key)
* Populate the environment variable `CURRENTS_PROJECT_ID` using [Jenkins Credentials Store](https://jenkins.io/doc/book/using/using-credentials/).
* Run Playwright tests on 2 workers, using CI Build ID for "connecting" the workers to the same parallel run. See [CI Build ID](/guides/parallelization-guide/ci-build-id).

{% code overflow="wrap" %}

```
npx pwc --key CURRENTS_RECORD_KEY --project-id CURRENTS_PROJECT_ID --ci-build-id ${env.BRANCH_NAME}-${env.BUILD_ID}"
```

{% endcode %}

Here's the full Jenkins pipeline configuration file:

<pre class="language-groovy"><code class="lang-groovy">pipeline {
  agent {
    // this image provides everything needed to run Playwright
    docker {
      image '<code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>'
    }
  }

  stages {
    // installs node dependencies
    stage('build') {
      steps {
        echo "Running build ${env.BUILD_ID} on ${env.JENKINS_URL}"
        sh 'npm install playwright @currents/playwright'
      }
    }

    // this stage runs Playwright tests, and each agent uses the workspace
    // from the previous stage
    stage('Playwright parallel tests') {
      environment {
        // see https://jenkins.io/doc/book/using/using-credentials/
        CURRENTS_RECORD_KEY = credentials('currents-record-key')
        CURRENTS_PROJECT_ID = credentials('currents-project-id')
      }

      // Run parallel workers, see:
      // https://jenkins.io/doc/book/pipeline/syntax/#parallel
      parallel {
        // each worker is running the same command, 
        stage('tester A') {
          steps {
            echo "Running build ${env.BUILD_ID}"
            sh "npx pwc --key ${env.CURRENTS_RECORD_KEY} --project-id ${env.CURRENTS_RECORD_KEY} --ci-build-id ${env.BRANCH_NAME}-${env.BUILD_ID} --shard 1/2 --output test-results/shard-1"
          }
        }

        // second tester runs the same command
        stage('tester B') {
          steps {
            echo "Running build ${env.BUILD_ID}"
            sh "npx pwc --key ${env.CURRENTS_RECORD_KEY} --project-id ${env.CURRENTS_RECORD_KEY} --ci-build-id ${env.BRANCH_NAME}-${env.BUILD_ID} --shard 2/2 --output test-results/shard-2"
          }
        }
      }

    }
  }
}
</code></pre>

## Using `--last-failed` with shards and orchestration

We have made available a [public repository with an example](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/jenkins/jenkins-last-failed) of how to setup last failed functionality using shards and orchestration in different machines.

Here you will be able to find the following Jenkinsfile that accepts two parameters:

* A CI Build ID from a previous run that you can use to apply the `--last-failed` flag. If this parameter is set, then the pipeline will automatically apply this tag and only run the failed tests from that run if found.
* A checkbox for knowing if you want to run an orchestrated run. If so, the pipeline will use `pwc-p` command instead of `pwc`.

<figure><img src="/files/DejooSwfXHkkRq8vzkXs" alt="" width="375"><figcaption><p>Pipeline Params</p></figcaption></figure>

In order to use the `--last-failed` flag, in addition to the project ID and record key, a Currents API key is needed (You can find it in the API Keys section in your dashboard).

{% hint style="info" %}
This example uses the API Key and the [`@currents/cmd`](/resources/reporters/currents-cmd/currents-api) package to query for the run corresponding to the CI Build ID and generates the `.last-run.json` file with that information.
{% endhint %}

Also, within the Jenkinsfile you can set different values as env variables for the total amount of shards `TOTAL_SHARDS` or the number of parallel jobs for orchestration `PARALLEL_JOBS.`

<details>

<summary>Install the @currents/cmd package</summary>

```bash
npm install -D @currents/cmd
```

</details>

<details>

<summary><code>Jenkinsfile</code></summary>

```groovy
pipeline {
    agent any
    parameters {
        string(name: 'CI_BUILD_ID', defaultValue: 'none', description: 'Set this value if you want to execute only the failed tests from a specific run')
        booleanParam(name: 'IS_ORCHESTRATION', defaultValue: false, description: 'Set this value if you want to execute an orchestrated run')
    }
    environment {
        CURRENTS_PROJECT_ID = credentials('CURRENTS_PROJECT_ID')
        CURRENTS_RECORD_KEY = credentials('CURRENTS_RECORD_KEY')
        CURRENTS_CI_BUILD_ID = "reporter-${JOB_NAME}-${BUILD_ID}-${BUILD_NUMBER}"
        CURRENTS_API_KEY = credentials('CURRENTS_API_KEY')
        TOTAL_SHARDS = 3
        PARALLEL_JOBS = 4
    }
    options {
        timeout(time: 60, unit: 'MINUTES')
    }
    stages {
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        stage('Install Dependencies') {
            steps {
                sh 'npm ci'
                sh 'npx playwright install'
                sh 'rm -rf test-results'
                sh 'rm -rf .last-run.json'
            }
        }

        stage('Set params CI Build ID') {
            steps {
                script {
                    env.CI_BUILD_ID = "${params.CI_BUILD_ID}"
                    echo "CI_BUILD_ID is set to: ${params.CI_BUILD_ID}"
                }
                echo "Verify values: ${env.CI_BUILD_ID} ${params.IS_ORCHESTRATION}"
            }
        }

        stage('Run Tests decision') {
            steps {
                runTestsDecision(env.CI_BUILD_ID, params.IS_ORCHESTRATION)
            }
        }
    }
}

def runTestsDecision(ciBuildId, isOrchestration) {
    if (ciBuildId && ciBuildId != 'none') {
        stage('Run Tests with last failed') {
            script {
                echo "Running tests with last failed: ${ciBuildId} ${env.TOTAL_SHARDS}"
                script {
                    sh "npx currents api get-run --api-key ${env.CURRENTS_API_KEY} --project-id ${env.CURRENTS_PROJECT_ID} --ci-build-id ${env.CI_BUILD_ID} --pw-last-run --output .last-run.json"
                    sh 'cat .last-run.json'
                }
                if (isOrchestration && isOrchestration == true) {
                    runPlaywrightOrchestration(env.PARALLEL_JOBS.toInteger(), true)
                } else {
                    runPlaywrightSharded(env.TOTAL_SHARDS.toInteger(), true)
                }
            }
        }
    } else {
        stage('Run Tests') {
            script {
                echo 'Running tests'
                if (isOrchestration && isOrchestration == true) {
                    runPlaywrightOrchestration(env.PARALLEL_JOBS.toInteger(), false)
                } else {
                    runPlaywrightSharded(env.TOTAL_SHARDS.toInteger(), false)
                }
            }
        }
    }
}

def runPlaywrightSharded(shardTotal, lastFailed) {
    def parallelStages = [:]
    for (int i = 1; i <= shardTotal; i++) {
        def shardIndex = i
        parallelStages["shard${shardIndex}"] = {
            if (lastFailed) {
                sh "mkdir -p test-results/shard-${shardIndex}"
                sh "cp .last-run.json test-results/shard-${shardIndex}/.last-run.json"
                runPlaywrightTestsLastFailed(shardIndex, shardTotal)
            } else {
                runPlaywrightTests(shardIndex, shardTotal)
            }
        }
    }
    parallel parallelStages
}

def runPlaywrightTests(shardIndex, shardTotal) {
    stage("Run Playwright Tests - Shard ${shardIndex}") {
        script {
            def command = "npx pwc --shard=${shardIndex}/${shardTotal}"
            echo "Running command: ${command}"
            sh "${command}"
        }
    }
}

def runPlaywrightTestsLastFailed(shardIndex, shardTotal) {
    stage("Run Playwright Tests - Shard ${shardIndex}") {
        script {
            def command = "npx pwc --shard=${shardIndex}/${shardTotal} --last-failed --output test-results/shard-${shardIndex}"
            echo "Running command: ${command}"
            sh "${command}"
        }
    }
}

def runPlaywrightOrchestration(parallelTotal, lastFailed) {
    def parallelStages = [:]
    for (int i = 1; i <= parallelTotal; i++) {
        def parallelIndex = i
        parallelStages["parallel${parallelIndex}"] = {
            if (lastFailed) {
                sh "mkdir -p test-results/parallel-${parallelIndex}"
                sh "cp .last-run.json test-results/parallel-${parallelIndex}/.last-run.json"
                runPlaywrightTestsLastFailedOrchestration(parallelIndex)
            } else {
                runPlaywrightTestsOrchestration(parallelIndex)
            }
        }
    }
    parallel parallelStages
}

def runPlaywrightTestsOrchestration(parallelIndex) {
    stage("Run Playwright Tests - Orchestration ${parallelIndex}") {
        script {
            def command = 'npx pwc-p run'
            echo "Running command: ${command}"
            sh "${command}"
        }
    }
}

def runPlaywrightTestsLastFailedOrchestration(parallelIndex) {
    stage("Run Playwright Tests - Orchestration ${parallelIndex}") {
        script {
            def discoveryFile = "test-results/parallel-${parallelIndex}/tests.txt"
            def discoverCommand = "npx pwc-p discover --pwc-discovery-file ${discoveryFile} --last-failed --output test-results/parallel-${parallelIndex}"
            def runCommand = "npx pwc-p run --pwc-discovery-file ${discoveryFile}"
            echo "Running command: ${discoverCommand}"
            sh "${discoverCommand}"
            echo "Running command: ${runCommand}"
            sh "${runCommand}"
        }
    }
}

```

</details>


# CircleCI

Running Playwright Tests in Parallel on CircleCI and Currents

{% hint style="info" %}
TL;DR Check out the example repository:

[https://github.com/currents-dev/currents-examples](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/circleci)
{% endhint %}

Run Playwright tests in [parallel on CircleCI](https://circleci.com/docs/guides/optimize/parallelism-faster-jobs/) using the native [Playwright Sharding](https://playwright.dev/docs/test-sharding) to split the tests between multiple containers. Parallelizing the test will help in decreasing the overall run duration.

Currents collects the results of distributed parallel CircleCI builds for more efficient troubleshooting. Each container will receive a unique set of tests to run so that your tests will run faster and you can receive faster feedback from your browser test suite.

Create multiple containers that will run your tests in parallel by setting the desired amount of containers with the [`parallelism`](https://circleci.com/docs/reference/configuration-reference/#parallelism) key in the `.circleci/config.yml` file.

Please refer to the [example repository](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/circleci) demonstrating how to set up [CircleCI](https://circleci.com) for running Playwright tests in parallel using [Currents](https://currents.dev) service.

* Create an organization at <https://app.currents.dev>
* Create a new project
* Grab `CURRENTS_RECORD_KEY` [Record Key](/guides/record-key) and `CURRENTS_PROJECT_ID`
* Store `CURRENTS_RECORD_KEY`: <https://circleci.com/docs/guides/security/contexts/>

<pre class="language-yaml"><code class="lang-yaml"># .circleci/config.yml
version: 2.1
jobs:
  run-test:
    docker:
      - image: <code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>
    # Enable parallelism of 3
    parallelism: 3
    steps:
      - checkout
      - run: npm i -D @playwright/test
      - run: npx playwright install
      - run: npx playwright install chrome
      - run:
          name: Run tests
          # Enable Playwright Shards
          # - Add CURRENTS_RECORD_KEY and CURRENTS_PROJECT_ID to the "currents" CircleCI context
          command: SHARD="$((${CIRCLE_NODE_INDEX}+1))"; npx pwc --key "$CURRENTS_RECORD_KEY" --project-id "$CURRENTS_PROJECT_ID" --shard="${SHARD}/${CIRCLE_NODE_TOTAL}"

# Invoke jobs via workflows
workflows:
  run-test-workflow:
    jobs:
      - run-test:
          # Use "currents" CircleCI context to enable access to secrets
          context: currents
</code></pre>

The example [config file](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/circleci/.circleci/config.yml):

* runs 3 containers with Playwright tests in parallel
* Note: the `Run tests` step above is ready to run once the `currents` context defines `CURRENTS_RECORD_KEY` and `CURRENTS_PROJECT_ID` (from [app.currents.dev](https://app.currents.dev)); you can append other `pwc` flags as needed.


# Buildkite

Running Playwright tests in parallel on Buildkite with Currents

{% hint style="info" %}
TL;DR Check out the example repository and the public Buildkite pipeline:

* <https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/buildkite>
* <https://buildkite.com/andrew-goldis/currents-buildkite>
  {% endhint %}

Run Playwright tests in parallel on [Buildkite](https://buildkite.com) using the native [Playwright Sharding](https://playwright.dev/docs/test-sharding) to split tests between multiple containers. Parallelizing tests helps decrease overall run duration.

Currents collects results from distributed parallel Buildkite builds for efficient troubleshooting. Each container receives a unique set of tests to run, providing faster feedback from your test suite.

## Setup

* Create an organization at <https://app.currents.dev>
* Create a new project
* Obtain `CURRENTS_RECORD_KEY` [Record Key](/guides/record-key) and `CURRENTS_PROJECT_ID`
* Store `CURRENTS_RECORD_KEY` as a pipeline-level secret in your Buildkite dashboard or via the [Buildkite Secrets plugin](https://buildkite.com/docs/pipelines/security/secrets/managing)

## Sharding

Buildkite provides `BUILDKITE_PARALLEL_JOB` (0-indexed) and `BUILDKITE_PARALLEL_JOB_COUNT` environment variables for parallel jobs. Since Playwright shards are 1-indexed, compute the shard index as `BUILDKITE_PARALLEL_JOB + 1`:

{% code overflow="wrap" %}

```bash
npx playwright test --shard=$((BUILDKITE_PARALLEL_JOB + 1))/$BUILDKITE_PARALLEL_JOB_COUNT
```

{% endcode %}

## Configuration

Configure the Currents reporter in your `playwright.config.ts`:

{% code title="playwright.config.ts" overflow="wrap" %}

```typescript
import { currentsReporter } from "@currents/playwright";
import { defineConfig, devices } from "@playwright/test";

export default defineConfig({
  reporter: [currentsReporter()],
  // ... other config
});
```

{% endcode %}

Create a `currents.config.ts` file:

{% code title="currents.config.ts" %}

```typescript
import { CurrentsConfig } from "@currents/playwright";

const currentsConfig: CurrentsConfig = {
  projectId: process.env.CURRENTS_PROJECT_ID ?? "your-project-id",
  recordKey: process.env.CURRENTS_RECORD_KEY ?? "",
};

export default currentsConfig;
```

{% endcode %}

## Example Pipeline

<pre class="language-yaml"><code class="lang-yaml">steps:
  - label: ":playwright: Playwright Tests"
    command: |
      npm ci
      npx playwright install --with-deps
      npx playwright test --shard=$((BUILDKITE_PARALLEL_JOB + 1))/$BUILDKITE_PARALLEL_JOB_COUNT
    parallelism: 3
    plugins:
      - docker#v5.11.0:
          image: "<code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>"
    env:
      CURRENTS_PROJECT_ID: "bnsqNa"
      CURRENTS_RECORD_KEY: "${CURRENTS_RECORD_KEY}"
</code></pre>

This pipeline:

* Runs 3 parallel containers using Buildkite's `parallelism` feature
* Uses the official Microsoft Playwright Docker image
* Splits tests using Playwright's native sharding with Buildkite environment variables
* Reports results to Currents via the Playwright Reporter

## Environment Variables

| Variable                       | Description                                           |
| ------------------------------ | ----------------------------------------------------- |
| `CURRENTS_PROJECT_ID`          | Your Currents project ID                              |
| `CURRENTS_RECORD_KEY`          | Your Currents record key (store as secret)            |
| `BUILDKITE_PARALLEL_JOB`       | Current job index (0-indexed, provided by Buildkite)  |
| `BUILDKITE_PARALLEL_JOB_COUNT` | Total number of parallel jobs (provided by Buildkite) |

{% hint style="info" %}
Looking for more ways to speed up CI? Read our [CI Optimization](/guides/ci-optimization) guide.
{% endhint %}


# Azure DevOps

Running Playwright test in parallel on Azure DevOps and Currents Dashboard

{% hint style="info" %}
TL;DR Check out the example repository:

[https://github.com/currents-dev/currents-examples](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/azure-devops)
{% endhint %}

Currents can use the native [Playwright Sharding](https://playwright.dev/docs/test-sharding) to split the tests between multiple containers. The results from distributed runs will be collected together with the generated artifacts to provide insights into test suite performance.

The [example repository](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/azure-devops) uses 3 Azure DevOps containers to allow parallel execution of the test showcasing Currents as a reporting service.

* Connect a new/existing Azure Pipeline to a repository containing your Playwright tests.
* Create an organization, get your **Record Key** and **Project Id** at [https://app.currents.dev](https://app.currents.dev/)
* Create or modify an existing [Variable Group](https://learn.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops\&tabs=yaml), and add a new secret variable called `CURRENTS_RECORD_KEY` with your **Record Key**.
* Include your **Project Id** in an env variable called `CURRENTS_PROJECT_ID` in your pipeline configuration.
* Ensure the [@current/playwright](/resources/reporters/currents-playwright) package has been integrated into your tests.
* Modify your `azure-pipelines.yml` file to run the tests and use one of the [example pipeline files](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/azure-devops/azure-pipelines.yml) as a reference.

Here's an example pipeline file:

<pre class="language-yaml"><code class="lang-yaml">trigger:
- main

jobs:
- job: pwcTests
  displayName: Playwright Tests - pwc
  strategy:
    matrix:
      chromium-1:
        project: chromium
        shard: 1/3
      chromium-2:
        project: chromium
        shard: 2/3
      chromium-3:
        project: chromium
        shard: 3/3
  pool:
    vmImage: ubuntu-latest

  # If you choose to not use the playwright container, you will also need to npx install playwright in your steps
  container: <code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>
  variables:
  - name: npm_config_cache
    value: $(Pipeline.Workspace)/.npm

  # You can use a variable group to store the CURRENTS_RECORD_KEY secret
  - group: currents-settings
  steps:
  - task: NodeTool@0
    displayName: 'Install NodeJS'
    inputs:
      versionSpec: '24'

  # Speed up the execution by caching the dependencies
  # https://docs.microsoft.com/en-us/azure/devops/pipelines/caching/?view=azure-devops
  - task: Cache@2
    inputs:
      key: 'npm | "$(Agent.OS)" | package-lock.json'
      restoreKeys: |
         npm | "$(Agent.OS)"
      path: $(npm_config_cache)
    displayName: Cache npm

  # Install Node dependencies
  - script: npm ci
    displayName: 'Install Dependencies'

  # Use pwc as the currents wrapper for playwright test
  # Replace the CURRENTS_PROJECT_ID value with your own from https://app.currents.dev
  - script: npx pwc --shard=$(shard)
    workingDirectory: '$(build.sourcesdirectory)/basic'
    displayName: 'Run Basic Tests'
    env:
      CI: 'true'
      CURRENTS_PROJECT_ID: '3W3DU4'
      CURRENTS_RECORD_KEY: $(CURRENTS_RECORD_KEY)
</code></pre>

Pipeline executions will be recorded and available in the Currents Dashboard, and test results and artifacts will be automatically uploaded.

<figure><img src="/files/4aDEdXytqqohQfLu3s7K" alt=""><figcaption><p>Running Playwright Tests in Azure DevOps Pipeline</p></figcaption></figure>

<figure><img src="/files/ydPIuohy5o895vNQpqJa" alt=""><figcaption><p>Running Playwright Tests in Azure DevOps Pipeline</p></figcaption></figure>


# AWS Code Build

Running Playwright Tests in Parallel on AWS CodeBuild and Currents

{% hint style="info" %}
TL;DR Check out the example repository:

[https://github.com/currents-dev/currents-examples](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/aws-codebuild)
{% endhint %}

Executing Playwright tests in parallel on AWS CodeBuild can significantly reduce the overall run duration. AWS CodeBuild supports [Batched Build](https://docs.aws.amazon.com/codebuild/latest/userguide/batch-build.html) in [matrix mode](https://docs.aws.amazon.com/codebuild/latest/userguide/batch-build.html#batch_build_matrix) for launching several workers in parallel.

<figure><img src="/files/LMXrVlVbec4h4MN8QRhj" alt=""><figcaption><p>Use AWS CodeBulld Matrix mode to run Playwright tests in parallel with Currents. 1 batch job (1) triggering 3 parallel build jobs (2).</p></figcaption></figure>

### Prerequisites

To enable parallel runs, please make sure that you have privileged access to your AWS Account and that you can create/modify an AWS CodeBuild Project.

### Configuration

#### Obtain Currents Credentials <a href="#user-content-obtain-currents-credentials" id="user-content-obtain-currents-credentials"></a>

Create an organization, and get [Record Key](/guides/record-key) and **Project ID** at [https://app.currents.dev](https://app.currents.dev/).

#### Create `buildspec.yml`

Create a `buildspec.yml` file in the root directory of your application's source code repository. This file defines the build and test steps for your application.

Set the **Project ID** for `pwc` command, for example:

<pre data-overflow="wrap"><code>npx pwc --project-id <a data-footnote-ref href="#user-content-fn-1">&#x3C;project_id></a> --key $CURRENTS_RECORD_KEY --ci-build-id $CODEBUILD_INITIATOR --shard $WORKER/3
</code></pre>

{% hint style="info" %}
The example uses `pwc` CLI command to run the tests. You can use `npx playwright test` command and configure `@currents/playwright` as a reporter. Please refer to the [documentation](https://currents.dev/readme/integration-with-playwright/currents-playwright#currents-playwright-reporter).
{% endhint %}

The `buildspec.yml` file uses [matrix mode](https://docs.aws.amazon.com/codebuild/latest/userguide/batch-build) to start 3 containers for running the test in parallel. Each container will have the environment variable `WORKER` set to `1,2,3` correspondingly, we use it to configure [Playwright Sharding](https://playwright.dev/docs/test-parallel#shard-tests-between-multiple-machines) `--shard $WORKER/3`

```yaml
## buildspec.yml
version: 0.2

batch:
  fast-fail: false
  build-matrix:
    dynamic:
      buildspec:
        - buildspec.yml
      env:
        variables:
          WORKER:
            - 1
            - 2
            - 3

phases:
  install:
    runtime-versions:
      nodejs: 24
    commands:
      # install playwright and its dependencies
      - npm ci
      - npx playwright install
      - npx playwright install-deps

  build:
    commands:
      # Optionally, set COMMIT_INFO variables to override the default values. See https://currents.dev/readme/runs/run-details#playwright-cypress-git-information
      # - export COMMIT_INFO_BRANCH="$(git rev-parse HEAD | xargs git name-rev |
      #   cut -d' ' -f2 | sed 's/remotes\/origin\///g')"
      # - export COMMIT_INFO_MESSAGE="$(git log -1 --pretty=%B)"
      # - export COMMIT_INFO_EMAIL="$(git log -1 --pretty=%ae)"
      # - export COMMIT_INFO_AUTHOR="$(git log -1 --pretty=%an)"
      # - export COMMIT_INFO_SHA="$(git log -1 --pretty=%H)"
      # - export COMMIT_INFO_REMOTE="$(git config --get remote.origin.url)"

      # update shard details according to the overall # of containers
      - npx pwc --project-id <project_id> --key $CURRENTS_RECORD_KEY --ci-build-id $CODEBUILD_INITIATOR --shard $WORKER/3
```

**Configure `CURRENTS_RECORD_KEY`**

Save the [Record Key](/guides/record-key) as `CURRENTS_RECORD_KEY` [Environment variable](https://docs.aws.amazon.com/codebuild/latest/userguide/change-project-console.html#change-project-console-environment). It is strongly recommended to use your **Record Key** in a secure secrets storage. Please refer to the [detailed guide](https://www.learnaws.org/2022/11/18/aws-codebuild-secrets-manager/), here is an overview of the steps:

* Create a new entry in AWS Secrets Manager with the **Record Key**. Please note that the generated secret is a JSON document, you should note the `json_key` of the actual record key value and use it later.
* Get the secret ARN
* Update the Build Project environment variables as follows:
  * Variable name: `CURRENTS_RECORD_KEY`
  * Variable value: the ARN of previously created secret + json\_key, for example: `<secret-arn>:<json-key>`
* Update the IAM execution role to allow reading of previously created secret

#### Configure AWS Project

Configure AWS-specific project settings like IAM execution policy, resources class and so on. Please refer to [AWS CodeBuild documentation](https://docs.aws.amazon.com/codebuild/) for details to explore possible configuration settings.

**Configure Source Batch Mode**

* Set the **Project Setting > Edit Source**
* Configure the repository details, the events that should trigger new builds
* Configure **Primary source webhook events > Build Type** to **Batch build** to start 3 parallel workers in [matrix mode](https://docs.aws.amazon.com/codebuild/latest/userguide/batch-build)

### Example: Triggering Parallel Playwright AWS CodeBuild

This [example repository](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/aws-codebuild) showcases running Playwright tests on AWS CodeBuild in parallel while using [Currents](https://currents.dev/) as the reporting dashboard. It has an example [AWS CodeBuilld Project configuration](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/aws-codebuild/aws-project-config-output.json).

{% embed url="<https://www.loom.com/share/36d9130a292949668cc875599927e83c?hideEmbedTopBar=true&hide_share=true&sid=4f798cda-d45f-4d05-841b-40aa6eed6f94?hide_owner=true>" %}
Example of triggering an AWS CodeBuild Playwright Tests via a commit
{% endembed %}

[^1]: replace with real project id


# Harness

Running Playwright tests on Harness CI with Currents reporting and parallel sharding

This guide explains how to run Playwright tests on [Harness Continuous Integration](https://developer.harness.io/docs/continuous-integration/) and report results to [Currents](https://currents.dev). It follows Harness NextGen pipeline patterns ([Run steps](https://developer.harness.io/docs/continuous-integration/use-ci/run-step-settings), [stage parallelism](https://developer.harness.io/docs/continuous-integration/use-ci/run-tests/speed-up-ci-test-pipelines-using-parallelism), [secrets](https://developer.harness.io/docs/platform/secrets/add-use-text-secrets)).

{% hint style="warning" %}
**`CURRENTS_CI_BUILD_ID` is mandatory** for Harness. Harness is **not** in Currents’ [auto-detected CI providers](/guides/parallelization-guide/ci-build-id#build-id-for-popular-ci-providers). If you omit it, Currents may generate a **different** build ID per job or shard: parallel Playwright shards **will not merge into one run**, reporting and orchestration **break**, and **retries** can collide with or duplicate prior runs. Always set `CURRENTS_CI_BUILD_ID` in every Run step (see below).
{% endhint %}

## Prerequisites

**Currents**

* Organization and project at <https://app.currents.dev>
* **Project ID** and **Record Key** — see [Record Key](/guides/record-key)
* **`CURRENTS_CI_BUILD_ID`** set in CI for every Playwright step (mandatory on Harness — see [CI Build ID](#ci-build-id-mandatory-on-harness))
* `@currents/playwright` installed and configured — see [@currents/playwright](/resources/reporters/currents-playwright)

**Harness**

* A **CI pipeline** with a **Build** (`CI`) stage
* A [Docker registry connector](https://developer.harness.io/docs/platform/connectors/cloud-providers/ref-cloud-providers/docker-registry-connector-settings-reference/) that can pull your Playwright image (for example `mcr.microsoft.com/playwright`). Replace `YOUR_DOCKER_CONNECTOR` in the examples with your connector reference (for example `account.harnessImageRegistry` or your org’s Docker Hub connector).

## Store the Record Key as a Harness secret

1. In Harness, create an **encrypted text** secret at the appropriate [scope](https://developer.harness.io/docs/platform/role-based-access-control/rbac-in-harness/#permissions-hierarchy-scopes) (project, org, or account).
2. Use a stable **identifier** (Harness derives it from the name). Example identifier: `currents_record_key`.
3. Reference it only by **identifier** in expressions, not the display name. See [Add and reference text secrets](https://developer.harness.io/docs/platform/secrets/add-use-text-secrets).

{% hint style="warning" %}
Avoid `$` in secret values when possible; the shell may expand it. If unavoidable, follow Harness guidance (for example quoting or base64 encoding) in the [text secrets](https://developer.harness.io/docs/platform/secrets/add-use-text-secrets) documentation.
{% endhint %}

## Application configuration

Use the same Playwright + Currents setup as other CI providers.

**`playwright.config.ts`** (reporter):

{% code title="playwright.config.ts" overflow="wrap" %}

```typescript
import { currentsReporter } from "@currents/playwright";
import { defineConfig } from "@playwright/test";

export default defineConfig({
  reporter: [currentsReporter()],
  use: {
    trace: "retain-on-failure-and-retries",
    video: "retain-on-failure",
    screenshot: "on",
  },
  // ...projects, testDir, etc.
});
```

{% endcode %}

**`currents.config.ts`**:

{% code title="currents.config.ts" %}

```typescript
import { CurrentsConfig } from "@currents/playwright";

const config: CurrentsConfig = {
  projectId: process.env.CURRENTS_PROJECT_ID ?? "",
  recordKey: process.env.CURRENTS_RECORD_KEY ?? "",
};

export default config;
```

{% endcode %}

## CI Build ID (mandatory on Harness)

**You must provide `CURRENTS_CI_BUILD_ID`** (environment variable or reporter config). It is a **required** input for correct Currents behavior on Harness — not optional.

Without a stable, explicit value:

* Each parallel shard may get its own ID → **multiple runs** instead of one combined run
* Reruns may reuse or collide with IDs → **stale or rejected** uploads — see the [CI Build ID FAQ](/guides/parallelization-guide/ci-build-id#faq-retrying-builds-and-ci-build-id)

The value must be:

* **Unique per pipeline execution** (each execution gets its own Currents run)
* **Identical across all parallel Playwright shards** in the same execution (shards merge into one run)
* **Different when you retry the same logical build**, when you need a fresh run — see [CI Build ID](/guides/parallelization-guide/ci-build-id)

Harness resolves expressions before the step runs. Common choices:

| Approach             | Expression (example)                                                                         | Notes                                                                                                                                                             |
| -------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Execution only       | `<+pipeline.executionId>`                                                                    | Unique per execution; confirm behavior for **re-runs** in your Harness edition                                                                                    |
| Execution + sequence | Concatenate `<+pipeline.executionId>` with `<+pipeline.sequenceId>` using `+` or `.concat()` | See [Harness variables](https://developer.harness.io/docs/platform/variables-and-expressions/harness-variables); helps separate retries when `sequenceId` changes |

Compose multi-part IDs with the concatenation patterns documented under **Harness variables** (for example combining `<+pipeline.identifier>`, `<+pipeline.executionId>`, and `<+pipeline.sequenceId>`).

## Option A — Single Run step (no parallelism)

Add a **Run** step in your **CI** stage. Set **Container Registry** to your Docker connector and **Image** to a [Playwright image](https://playwright.dev/docs/docker) tag that matches your `@playwright/test` version.

<pre class="language-yaml"><code class="lang-yaml">execution:
  steps:
    - step:
        type: Run
        name: playwright_currents
        identifier: playwright_currents
        spec:
          connectorRef: YOUR_DOCKER_CONNECTOR
          image: <code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>
          shell: Bash
          command: |-
            npm ci
            npx playwright install chrome
            npx playwright test
          envVariables:
            CI: "true"
            CURRENTS_PROJECT_ID: YOUR_CURRENTS_PROJECT_ID
            CURRENTS_RECORD_KEY: &#x3C;+secrets.getValue("currents_record_key")>
            CURRENTS_CI_BUILD_ID: &#x3C;+pipeline.executionId>
</code></pre>

* Replace `YOUR_CURRENTS_PROJECT_ID` with your project ID, or use a [pipeline variable](https://developer.harness.io/docs/platform/variables-and-expressions/harness-variables) (for example `<+pipeline.variables.currents_project_id>`).
* Replace `currents_record_key` with your secret’s **identifier**.

## Option B — Parallel Playwright sharding (recommended)

Use **stage-level** [parallelism](https://developer.harness.io/docs/continuous-integration/use-ci/run-tests/speed-up-ci-test-pipelines-using-parallelism) so Harness runs multiple copies of the stage. Playwright’s [`--shard`](https://playwright.dev/docs/test-sharding) is **1-based**; Harness parallel indices are **0-based**, so use `HARNESS_NODE_INDEX + 1` for the shard index.

Do **not** rely on Harness `split_tests` for Playwright unless you intentionally drive a custom split; native sharding matches the rest of Currents’ CI docs and keeps setup simple.

<pre class="language-yaml"><code class="lang-yaml">- stage:
    name: playwright_tests
    identifier: playwright_tests
    type: CI
    strategy:
      parallelism: 3
      maxConcurrency: 3
    spec:
      cloneCodebase: true
      platform:
        os: Linux
        arch: Amd64
      runtime:
        type: Cloud
        spec: {}
      execution:
        steps:
          - step:
              type: Run
              name: playwright_currents_shard
              identifier: playwright_currents_shard
              spec:
                connectorRef: YOUR_DOCKER_CONNECTOR
                image: <code class="expression">space.vars.PW_IMAGE_ROUTE + ":" + space.vars.LATEST_PW_IMAGE_VERSION</code>
                shell: Bash
                command: |-
                  npm ci
                  npx playwright install chrome
                  SHARD_INDEX=$((HARNESS_NODE_INDEX + 1))
                  npx playwright test --shard=${SHARD_INDEX}/${HARNESS_NODE_TOTAL}
                envVariables:
                  CI: "true"
                  HARNESS_NODE_INDEX: &#x3C;+strategy.iteration>
                  HARNESS_NODE_TOTAL: &#x3C;+strategy.iterations>
                  CURRENTS_PROJECT_ID: YOUR_CURRENTS_PROJECT_ID
                  CURRENTS_RECORD_KEY: &#x3C;+secrets.getValue("currents_record_key")>
                  CURRENTS_CI_BUILD_ID: &#x3C;+pipeline.executionId>
</code></pre>

* Tune `parallelism` and `maxConcurrency` per [best practices for looping strategies](https://developer.harness.io/docs/platform/pipelines/looping-strategies/best-practices-for-looping-strategies).
* **`CURRENTS_CI_BUILD_ID` is mandatory** — the **same** value must reach every shard (the `<+pipeline.executionId>` expression above resolves identically for all parallel instances of the same execution).

## Environment variables reference

| Variable               | Required            | Description                                                                                                                                                                   |
| ---------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CURRENTS_PROJECT_ID`  | Yes                 | Currents project ID from the dashboard                                                                                                                                        |
| `CURRENTS_RECORD_KEY`  | Yes                 | Record key; inject via `<+secrets.getValue("SECRET_IDENTIFIER")>` (or org/account-scoped variant)                                                                             |
| `CURRENTS_CI_BUILD_ID` | **Yes (mandatory)** | **Required on Harness.** Stable ID shared by all shards in one execution; must change appropriately on retries — see [CI Build ID](/guides/parallelization-guide/ci-build-id) |
| `CI`                   | Optional            | Set to `true` so tools behave as in CI                                                                                                                                        |
| `HARNESS_NODE_INDEX`   | Parallel only       | `<+strategy.iteration>` — 0-based shard index                                                                                                                                 |
| `HARNESS_NODE_TOTAL`   | Parallel only       | `<+strategy.iterations>` — must match `parallelism`                                                                                                                           |

## Optional — Pipeline or stage variables

You can define **pipeline** or **stage** variables for non-secret settings (for example project ID) and reference them with expressions such as `<+pipeline.variables.currents_project_id>`. Precedence for environment variables in Harness is **step > stage > pipeline**. See [Variables](https://developer.harness.io/docs/open-source/pipelines/variables) (open-source YAML) and [Harness variables](https://developer.harness.io/docs/platform/variables-and-expressions/harness-variables) (expressions).

## Harness Open Source / GitOps pipeline YAML

If you use the **open-source pipeline** schema (`kind: pipeline`), environment variables are often declared under `spec.options.envs` (pipeline-wide) or `spec.envs` on a `ci` stage, and Run steps use `spec.container` and `spec.script`. The **Currents** requirements are the same: include **`CURRENTS_CI_BUILD_ID` (mandatory)**, other `CURRENTS_*` variables, and `npx playwright test` with optional `--shard`. Map them to your schema per [CI stage reference](https://developer.harness.io/docs/open-source/reference/pipelines/yaml/stage.type.ci).

## Further reading

* [Harness CI Run step settings](https://developer.harness.io/docs/continuous-integration/use-ci/run-step-settings)
* [Speed up CI with parallelism](https://developer.harness.io/docs/continuous-integration/use-ci/run-tests/speed-up-ci-test-pipelines-using-parallelism)
* Currents: [CI Optimization](/guides/ci-optimization), [Orchestration Setup](/guides/ci-optimization/playwright-orchestration)

{% hint style="info" %}
Got stuck configuring CI? Reach out to [Support](/resources/support).
{% endhint %}


# NX

Running Playwright tests with NX

## Running Playwright tests in an Nx project with Currents

[Nx](https://github.com/nrwl/nx) is a build system with monorepo support and powerful integrations. Playwright tests executions in Nx can be done by using [@nx/playwright](https://nx.dev/nx-api/playwright) plugin.

[This example repository](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/nx) showcases all the implementation described here.

To use the nx playwright plugin, Currents client must be set as reporter option in the `playwright.config` file.

Here a quick example:

```typescript
import { nxE2EPreset } from '@nx/playwright/preset';
import { defineConfig, devices } from '@playwright/test';
import { CurrentsConfig, currentsReporter } from '@currents/playwright';

const currentsConfig: CurrentsConfig = {
  recordKey: process.env.CURRENTS_RECORD_KEY,
  projectId: process.env.CURRENTS_PROJECT_ID,
};

const nxConf = nxE2EPreset(__filename);
export default defineConfig({
  ...nxConf,
  reporter: [currentsReporter(currentsConfig)],
  ...
  ...
});
```

{% hint style="info" %}
See a more scalable [example for multiple projects here](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/nx)
{% endhint %}

In order to execute the tests, our example `project.json` file includes the `e2e` target and Playwright plugin as `executor` property.

```json
{
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "name": "e2e-02",
  "projectType": "application",
  "sourceRoot": "apps/e2e-02/src",
  "targets": {
    "e2e": {
      "executor": "@nx/playwright:playwright",
      "options": {
        "skipInstall": true,
        "output": "{workspaceRoot}/playwright-report/{projectName}",
        "config": "{projectRoot}/playwright.config.ts"
      }
    }
  }
}
```

The command to execute the tests with Playwright is:

```bash
CURRENTS_RECORD_KEY=recordkey \
CURRENTS_PROJECT_ID=projectid \
CURRENTS_CI_BUILD_ID=`date +%s` \
nx run-many -t e2e  --parallel=2 --verbose
```

This will create a run execution in Currents reporting the tests results.

### Using `--last-failed` flag

For executing only the failed tests according to a previous run, add the `--last-failed` flag to the execution command.

```bash
CURRENTS_RECORD_KEY=recordkey \
CURRENTS_PROJECT_ID=projectid \
CURRENTS_CI_BUILD_ID=`date +%s` \
nx run-many -t e2e  --parallel=2 --verbose --last-failed
```

{% hint style="info" %}
For a more detailed explanation on last failed CI setup, [see here](/guides/ci-optimization/re-run-only-failed-tests)
{% endhint %}

### Orchestration in a single project

It is possible to orchestrate the Playwright tests in a single nx project by using the same `ci-build-id` across multiple machines.

This is showcased in the `e2e-03` nx project and the `project.json` file is slightly different than for the other projects.

```json
{
  "$schema": "../../node_modules/nx/schemas/project-schema.json",
  "name": "e2e-03",
  "projectType": "application",
  "sourceRoot": "apps/e2e-03/src",
  "targets": {
    "or8n-discover": {
      "executor": "nx:run-commands",
      "options": {
        "cwd": "apps/e2e-03",
        "commands": [
          {
            "command": "npx pwc-p discover --pwc-discovery-file tests.txt"
          }
        ]
      }
    },
    "or8n": {
      "executor": "nx:run-commands",
      "options": {
        "cwd": "apps/e2e-03",
        "commands": [
          {
            "command": "npx pwc-p run"
          }
        ]
      }
    }
  }
}
```

Key differences with other nx projects in the example repository:

* `executor` property has the value `nx:run-commands`.
* A `command` property is added within `options`. This executes `npx pwc-p run` for orchestration. See [Orchestration Setup](/guides/ci-optimization/playwright-orchestration).
* Reporter config in `playwright.config` file is not needed
* Orchestration runs the full suite by default — use `or8n-discover` first to filter tests

To locally execute orchestration nx project:

```bash
CURRENTS_RECORD_KEY=recordkey \
CURRENTS_PROJECT_ID=projectid \
CURRENTS_CI_BUILD_ID=unique-id \
nx run-many -t or8n
```

Or with discovery (for filtered runs):

```bash
CURRENTS_RECORD_KEY=recordkey \
CURRENTS_PROJECT_ID=projectid \
CURRENTS_CI_BUILD_ID=unique-id \
nx run-many -t or8n-discover -- --grep @smoke && nx run-many -t or8n -- --pwc-discovery-file tests.txt
```

```yaml
name: Run or8n Tests

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main
  workflow_dispatch:

jobs:
  e2e_tests:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        shard: [1, 2, 3]

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Install Dependencies
        run: npm install

      - name: Reset NX
        run: npx nx reset

      - name: Run All E2E Tests
        env:
          CURRENTS_PROJECT_ID: ${{secrets.CURRENTS_PROJECT_ID}}
          CURRENTS_RECORD_KEY: ${{secrets.CURRENTS_RECORD_KEY}}
          CURRENTS_CI_BUILD_ID: ${{ github.run_id }}-${{ github.sha }}
        run: npx nx run-many -t or8n
```


# Other Frameworks

Currents is focused on Playwright ecosystem, but is also compatible with other testing frameworks - Cypress, WebdriverIO, Jest, Vitest, Node.JS Test Runner and more.

<figure><img src="/files/kYnc0EN863GTP3iFEj2g" alt=""><figcaption></figcaption></figure>


# JUnit

Integrate Currents with any framework by using JUnit compatible XML reporters

Currents has flagship integrations with various testing frameworks via the dedicated reporters (like Playwright, [Jest](/getting-started/other-frameworks/jest), [@currents/node-test-reporter](/resources/reporters/currents-node-test-reporter) and [Cypress](/getting-started/other-frameworks/cypress)), and framework-specific instructions for [Vitest](/getting-started/other-frameworks/vitest).

Integration with other frameworks is possible by uploading a JUnit XML (or compatible) test results report to Currents using our CLI utilities from [@currents/cmd](/resources/reporters/currents-cmd) package.

<figure><img src="/files/svGylC0b6oiPcC66ruiI" alt=""><figcaption><p>Send results from any framework that supports JUnit XML format</p></figcaption></figure>

> JUnit is an XML document used to represent the outcomes of automated tests. It is widely adopted for test reporting in CI/CD pipelines, allowing CI tools like Jenkins, GitHub Actions, ands other to parse and display test results.
>
> JUnit reports typically contains information about:
>
> * Test suites - groups of test cases (e.g., a set of related tests)
> * Test cases - individual test scenarios with details like execution time, status (pass/fail), and optional logs (e.g., errors or skipped messages)
>
> See a detailed [example of a complete JUnit XML file](https://github.com/testmoapp/junitxml?tab=readme-ov-file#complete-junit-xml-example).

### Overview

A typical workflow for reporting JUnit XML results to Currents:

{% stepper %}
{% step %}

#### Configure testing framework

Configure your testing tool to generate the results in JUnit XML format
{% endstep %}

{% step %}

#### Run the tests

Run the tests and save the test results at a known location
{% endstep %}

{% step %}

#### Conver JUnit XML file

Run [currents convert](/resources/reporters/currents-cmd/currents-convert) command to convert JUnit XML report to a format compatible with Currents
{% endstep %}

{% step %}

#### Upload the results to Currents

Run [currents upload](/resources/reporters/currents-cmd/currents-upload)command to send the results to Currents for processing
{% endstep %}
{% endstepper %}

### Setup

* Install [@currents/cmd](/resources/reporters/currents-cmd) package

```bash
npm i @currents/cmd
```

### Run the tests

Refer to your framework documentation or contact Currents support for help with enabling JUnit reporter for your framework

<table><thead><tr><th width="232">Framework</th><th>Instructions</th></tr></thead><tbody><tr><td>Vitest</td><td><a href="/pages/5UEfHq7tsOanYw9nuCQz">Vitest</a></td></tr><tr><td>NodeJS Test Runner</td><td><a href="https://nodejs.org/api/test.html#test-reporters">https://nodejs.org/api/test.html#test-reporters</a></td></tr><tr><td>WebdriverIO</td><td><a href="https://webdriver.io/docs/junit-reporter/">https://webdriver.io/docs/junit-reporter/</a></td></tr><tr><td>Cypress</td><td><a href="https://github.com/michaelleeallen/mocha-junit-reporter">https://github.com/michaelleeallen/mocha-junit-reporter</a></td></tr><tr><td>Postman (Newman)</td><td><a href="https://github.com/postmanlabs/newman?tab=readme-ov-file#junitxml-reporter">https://github.com/postmanlabs/newman?tab=readme-ov-file#junitxml-reporter</a></td></tr></tbody></table>

When running the tests, make sure to save the results at a known location - you will need to provide path to the generated files later.

### Convert the JUnit XML report

Use [currents convert](/resources/reporters/currents-cmd/currents-convert) command to convert JUnit format to internal Currents format. Refer to [currents convert](/resources/reporters/currents-cmd/currents-convert) documentation for the list of supported formats and frameworks.

For example:

```
npx currents convert \
  --input-format=junit \
  --input-file=junit-file.xml \
  --output-dir=.currents \
  --framework=postman \
  --framework-version=v11.2.0
```

### Upload the results

Use [currents upload](/resources/reporters/currents-cmd/currents-upload) command to send the results to Currents. Get a [Record key](/guides/record-key) and [Project ID](/dashboard/projects) from Currents dashboard.

```bash
npx currents upload --project-id=xxx --key=yyy
```

### Example

Check out the [example repository](https://github.com/currents-dev/currents-junit-xml-example) that demonstrates how to generate and report test results from various testing frameworks to Currents.

* [Postman](https://github.com/currents-dev/currents-junit-xml-example/tree/main/packages/postman)
* [Vitest](https://github.com/currents-dev/currents-junit-xml-example/tree/main/packages/vitest)
* [NodeJS Test Runner](https://github.com/currents-dev/currents-junit-xml-example/tree/main/packages/nodejs-test-runner)
* [WebdriverIO](https://github.com/currents-dev/currents-junit-xml-example/tree/main/packages/wdio)


# CI Setup


# Node.js - GitHub Actions

Running Node.js Tests on GitHub Actions

{% hint style="info" %}
TL;DR Check out the example repository:

[https://github.com/currents-dev/currents-examples](https://github.com/currents-dev/currents-examples/tree/main/generic-reporter/junit/nodejs-github-actions)
{% endhint %}

Here's an example workflow configuration file:

{% code title=".github/workflows /node.yml" overflow="wrap" %}

```yaml
name: Run Node.JS

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        shard: [1, 2]

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "24.x"

      - name: Install dependencies
        run: npm install

      - name: install currents
        run: npm install @currents/node-test-reporter @currents/cmd

      - name: Run tests in shard ${{ matrix.shard }}
        run: node --test --test-shard=${{ matrix.shard }}/2 --test-reporter @currents/node-test-reporter --test-reporter-destination=./report.xml tests/**.test.mjs || true && echo '✅ Script executed successfully'

      - name: Convert test results to Currents format
        run: npx currents convert --input-format=junit --input-file=./report.xml --framework=node

      - name: Upload test results to Currents.dev
        # CURRENTS_RECORD_KEY is a secret stored in the repository settings
        env:
          CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
        run: |
          npx currents upload --project-id JOw2i3 --ci-build-id ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}

```

{% endcode %}

* Get your [Record Key](/guides/record-key) and set [GH secret](https://docs.github.com/en/actions/reference/encrypted-secrets) variable`CURRENTS_RECORD_KEY`.
* Set the Project ID
  * Option 1: Update `npx currents upload` `--project-id` argument to [your project's id](/dashboard/projects/project-settings).
  * Option 2: Set it up in the [reporter config](https://docs.currents.dev/resources/reporters/currents-jest#configuration) instead.

### Explore

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>@currents/node-test-reporter</td><td></td><td></td><td><a href="/pages/JEiqp4P3rNF1mTWwEc7Q">/pages/JEiqp4P3rNF1mTWwEc7Q</a></td></tr><tr><td>CI Build ID</td><td></td><td></td><td><a href="/pages/d7NOovtmXVrt6HaVXgKq">/pages/d7NOovtmXVrt6HaVXgKq</a></td></tr><tr><td>@currents/cmd</td><td></td><td></td><td></td></tr></tbody></table>


# Jest


# Your First Jest Run

Running Jest tests with Currents dashboard

Setting up Currents for running and recording Jest tests in parallel can be done seamlessly within a few minutes.

## Prerequisites

<details>

<summary>Create an Organization and a Project</summary>

After signing up for the dashboard service, you will be prompted to create a new organization and a project. You can change their names later.

<img src="/files/kZ7AZ9THWF2rb1MkzV3d" alt="Creating an Organization and a Project in Currents dashboard" data-size="original">

After creating a new organization and a project, you'll see on-screen instructions with your newly created **Project ID** and **Record Key.**

Select Jest from the framework selection list.

</details>

<details>

<summary>Install @currents/jest and @currents/cmd packages</summary>

```bash
npm install @currents/jest @currents/cmd --save-dev
```

**Note:** `@currents/jest` requires

* **Jest** `v29.5.0+`
* **Node.js** `v18.20.4+`

</details>

<details>

<summary>Use the Currents reporter</summary>

You have two options on how to use our reporter.

**Option 1**: Update Jest configuration file:

{% code title="jest.config.js" %}

```javascript
import type { Config } from "jest";

const config: Config = {
  reporters: ["default", "@currents/jest"], // Add this line to your config
};

export default config;
```

{% endcode %}

**Option 2**: Pass our reporter as an argument when executing Jest.

{% code title="package.json" %}

```json
{
  ...
  "scripts": {
    ...
    "test": "jest --reporters=@currents/jest",
  },
  ...
}
```

{% endcode %}

</details>

<details>

<summary>Update your .gitignore</summary>

Add a line in your .gitignore to avoid pushing temporary generated reports to your repository.

```
.currents
```

</details>

## Your First Jest Run

Upon running Jest tests, Currents reporter for jest generates a temporary folder containing the test results. To upload the results to Currents, you must run [currents upload](/resources/reporters/currents-cmd/currents-upload)

#### Step 1: Run the tests

```sh
npx jest --reporters=@currents/jest
```

#### Step 2: Upload the results

Run the following command to upload the last results to Currents dashboard (see [currents upload](/resources/reporters/currents-cmd/currents-upload))

```sh
npx currents upload --key=XXX --project-id=YYY
```

Set the [**Record Key**](/guides/record-key), and [**Project ID**](/dashboard/projects/project-settings) obtained from Currents dashboard in the previous step.

{% hint style="info" %}
You can defined the Record Key and Project ID in the [Reporter configuration](/resources/reporters/currents-jest#configuration).
{% endhint %}

## Explore Your First Run

The execution results will show on the Currents dashboard. The latest report should be uploaded to Currents, and a link to the run will be displayed.

<figure><img src="/files/jjG3nJcJ2DzHWzbNLKOH" alt=""><figcaption><p>A link to the recorded results</p></figcaption></figure>

## Good To Know

To provide reliable information about your tests, Currents run a "discovery" process - i.e. exploring the full test suite details. The discovery runs as part of `currents upload` command. Behind the scenes, the command runs `jest` in discovery mode.

{% hint style="info" %}
It is important to ensure that

`npx jest --reporters=@currents/jest` and `currents upload` share the same environment variables
{% endhint %}


# Detox + Jest

Follow this guide to enable integrating Detox + Jest with Currents

[Detox](https://wix.github.io/Detox/) is a popular gray-box end-to-end testing and automation framework for React Native apps.

Detox delegates scheduling and running tests onto a test runner. Jest is the default and the recommended choice, for many reasons, including - but not limited to, parallel test suite execution capability, and complete integration with Detox API.

Currents integration with Jest allows sending the results of your Detox tests to Currents.

### Add Currents Reporter for Jest

After you setup and configure Detox for your mobile application, add [@currents/jest](/resources/reporters/currents-jest) reporter to `jest.config.js`

{% code title="jest.config.js" %}

```javascript
/** @type {import('jest').Config} */
module.exports = {
  maxWorkers: 1,
  globalSetup: './globalSetup.ts',
  globalTeardown: 'detox/runners/jest/globalTeardown',
  testEnvironment: 'detox/runners/jest/testEnvironment',
  setupFilesAfterEnv: ['./setup.ts'],
  testRunner: 'jest-circus/runner',
  testTimeout: 120000,
  testMatch: ['**/*.test.ts'],
  transform: {
    '\\.tsx?$': 'ts-jest'
  },
  reporters: ['detox/runners/jest/reporter', '@currents/jest'], // 👈🏻
  verbose: true
};
```

{% endcode %}

### Run Detox Tests

Run detox tests:

```
npx detox test --configuration android.emu.release
```

Running this command with [@currents/jest](/resources/reporters/currents-jest) reporter enabled generates results in a format compatible for processing by Currents.

In order to send the results for processing you'd invoke an additional command `currents upload` from [@currents/cmd](/resources/reporters/currents-cmd) npm package.

### Uploading Results to Currents

Run the following command to upload the results to Currents (see [currents upload](/resources/reporters/currents-cmd/currents-upload) for details)

```
npx currents upload --key=KPEvZL0LDYzcZH3U --project-id=X7niCl
```

Before running `currents upload` you must explicitly define detox configuration that matches the configuration used to run the tests.

For example, if you run the tests using `--configuration android.emu.release`, then you should also define the same configuration value for `currents upload` command.

{% hint style="warning" %}
Without specifying the configuration, you may encounter an error:

{% code overflow="wrap" %}

```
Jest: Got error running globalSetup
Cannot determine which configuration to use from Detox config at path:
_path/detox-example/.detoxrc.js

HINT: Use --configuration to choose one of the following:
* android.emu.release
* ios
```

{% endcode %}
{% endhint %}

#### Setting Detox Configuration

To explicitly set Detox configuration set the `selectedConfiguration: <configuration key>` in the Detox [config file](https://wix.github.io/Detox/docs/config/overview/#config-structure):

{% code title=".detoxrc.js" %}

```javascript
  selectedConfiguration: "android.emu.release",
  configurations: {
    "android.emu.release": {
      device: "emulator",
      app: "android.release",
    },
    ios: {
      device: "ios.simulator",
      app: "ios",
    },
  }
```

{% endcode %}

If you have only one configuration value in the `configurations` object of detox configuration file, Detox will pick it by default and there's no need to explicitly set the configuration.

{% hint style="info" %}
The `currents upload` command will execute `jest` to discover the full test suite. During this process, the `globalSetup` script will be run, which can only utilize the `selectedConfiguration` option or the single value from the `configurations` object.
{% endhint %}

### Detox retries limitation

When retries are used (e.g. with Detox), results can end up in **multiple report directories** or show **only the last attempt**. This section explains why and how to configure the reporter.

#### How the report directory works

The reporter writes results into a **report directory**. One Jest process uses one directory per run.

* **Not set:** A new unique directory is created for each run (e.g. `.currents/2025-03-05-…-uuid`). If your workflow starts Jest **more than once** (e.g. Detox re-runs failed tests in a new process), each run gets its own directory. Results are split across folders and upload may see only one or fail.
* **Set:** Every run writes to the same folder. Upload sees one report. If a later run only re-runs failed tests, it **overwrites** those tests results in that folder, so Currents shows only the **last attempt** for retried specs.

**Configuration:** Set the path in Jest config (`reportDir` in the reporter options) or with the `CURRENTS_REPORT_DIR` environment variable. Env var overrides the config option when both are set.

#### Why Detox is different

Detox runs tests via Jest in separate processes. With [`detox test --retries <n>`](https://wix.github.io/Detox/docs/config/testRunner/#testrunnerretries-number), Detox **starts Jest again** for failed test files only. So you get multiple Jest runs in one logical run - which leads to either multiple report directories (if report dir is not set) or overwritten retry results (if it is set). The same applies to any setup that runs Jest more than once.

#### What to do

**Option 1: Use Jest retries (recommended)**

Use **Jest's built-in retries** (e.g. [`jest.retryTimes()`](https://jestjs.io/docs/jest-object#jestretrytimesnumretries-options) in config). Retries stay in the same Jest process, so there is one run, one report directory, and full retry history in Currents.

Use this when Jest-level retries are enough and you don't need Detox’s “re-run only failed files in a new process” behavior.

**Option 2: Fixed report directory with Detox retries**

When you must use [Detox's retries](https://wix.github.io/Detox/docs/config/testRunner/#testrunnerretries-number), set a **fixed report directory** so every run writes to the same place and upload finds a single report.

**Jest config:**

```js
// jest.config.js
module.exports = {
  reporters: [
    'detox/runners/jest/reporter',
    ['@currents/jest', { reportDir: './e2e/.test-results' }],
  ],
  // ...
};
```

**Or environment variable:**

```bash
CURRENTS_REPORT_DIR=./e2e/.test-results
```

**Trade-off:** The retry run writes to the same directory and overwrites the first run’s results for those tests, so Currents shows only the last attempt for retried specs.

#### Quick reference

| Scenario                                         | No fixed report directory                    | Fixed report directory                                             |
| ------------------------------------------------ | -------------------------------------------- | ------------------------------------------------------------------ |
| Single Jest run (or Jest retries in one process) | One directory, full results                  | One directory, full results                                        |
| Multiple Jest runs (e.g. Detox `--retries`)      | Several directories; upload may use only one | One directory; retried tests overwrite → only last attempt visible |

**Recommendation:** Prefer Jest retries when possible (one directory, full retry history). If using Detox `--retries`, set a fixed report directory and accept that retried specs show only the last attempt.

{% hint style="info" %}
Improved support for Detox-style retries (e.g. merging retry runs into one report or full retry history in Currents) is proposed on [Featurebase](https://currents.featurebase.app/p/improved-detox-retries-support). Upvote there to help prioritise implementation.
{% endhint %}


# Troubleshooting Jest

Troubleshooting Jest integration with Currents

If you are experiencing issues with using `@currents/jest`, please collect more information about the failure and submit a support request via our support channels.

### 1. Collecting Environment Information

Please collect the following information to help us effectively debug the problem:

* The associated dashboard Run URL
* Screenshots if applicable
* Your setup method and configuration files
* The exact command used to run Jest
* Environment information (use the command below)

Use the following command to print information about your CI environment

```bash
npx envinfo --system --binaries --browsers --npmPackages --duplicates --npmGlobalPackages
```

### 2. Activate Debug Mode

Set `DEBUG=currents*` before running `jest` to obtain detailed information about the reporter execution process.

For more details on how to troubleshoot Jest tests, refer to [their documentation](https://jestjs.io/docs/troubleshooting).


# CI Setup


# Jest - GitHub Actions

Running Jest in Parallel on GitHub Actions using Matrix Workflow

{% hint style="info" %}
TL;DR Check out the example repository:

[https://github.com/currents-dev/currents-examples](https://github.com/currents-dev/currents-examples/tree/main/generic-reporter/jest/github-actions)
{% endhint %}

Currents uses the native [Jest sharding](https://jestjs.io/docs/next/cli#--shard) (Jest v28+) to split the tests between multiple containers.

Here's an example workflow configuration file:

{% code title=".github/workflows /jest.yml" overflow="wrap" %}

```yaml
name: Run Jest

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        shard: [1, 2]

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "24.x"

      - name: Install dependencies
        run: npm install

      - name: Run tests in shard ${{ matrix.shard }}
        run: |
          npx jest --shard=${{ matrix.shard }}/2

      - name: Upload test results to Currents.dev
        # CURRENTS_RECORD_KEY is a secret stored in the repository settings
        env:
          CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
        run: |
          npx currents upload --project-id mdXsz8 --ci-build-id ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}
```

{% endcode %}

* Get your [Record Key](/guides/record-key) and set [GH secret](https://docs.github.com/en/actions/reference/encrypted-secrets) variable`CURRENTS_RECORD_KEY`.
* Set the Project ID
  * Option 1: Update `npx currents upload` `--project-id` argument to [your project's id](/dashboard/projects/project-settings).
  * Option 2: Set it up in the [reporter config](https://docs.currents.dev/resources/reporters/currents-jest#configuration) instead.

### Explore

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>@currents/jest</td><td></td><td></td><td><a href="/pages/JEiqp4P3rNF1mTWwEc7Q">/pages/JEiqp4P3rNF1mTWwEc7Q</a></td></tr><tr><td>CI Build ID</td><td></td><td></td><td><a href="/pages/d7NOovtmXVrt6HaVXgKq">/pages/d7NOovtmXVrt6HaVXgKq</a></td></tr><tr><td></td><td></td><td></td><td></td></tr></tbody></table>


# Vitest

Integrate Vitest with Currents using the JUnit XML reporter


# Your First Vitest Run

Running Vitest tests with Currents dashboard

Vitest doesn't have a dedicated Currents reporter. Instead, Vitest writes a JUnit XML report using its built-in `junit` reporter, and [@currents/cmd](/resources/reporters/currents-cmd) converts and uploads it to Currents.

## Prerequisites

<details>

<summary>Create an Organization and a Project</summary>

After signing up for the dashboard service, you will be prompted to create a new organization and a project. You can change their names later.

<img src="/files/kZ7AZ9THWF2rb1MkzV3d" alt="Creating an Organization and a Project in Currents dashboard" data-size="original">

After creating a new organization and a project, you'll see on-screen instructions with your newly created **Project ID** and **Record Key.**

</details>

<details>

<summary>Install @currents/cmd package</summary>

```bash
npm install @currents/cmd --save-dev
```

</details>

<details>

<summary>Enable the JUnit reporter</summary>

**Option 1**: Update the Vitest configuration file:

{% code title="vitest.config.js" %}

```javascript
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    reporters: ["default", "junit"],
    outputFile: {
      junit: "./results.xml",
    },
  },
});
```

{% endcode %}

**Option 2**: Pass the reporter as an argument when executing Vitest.

{% code title="package.json" %}

```json
{
  ...
  "scripts": {
    ...
    "test": "vitest run --reporter=default --reporter=junit --outputFile.junit=./results.xml",
  },
  ...
}
```

{% endcode %}

See [Vitest reporters documentation](https://vitest.dev/guide/reporters#junit-reporter) for the full list of the JUnit reporter options.

</details>

<details>

<summary>Update your .gitignore</summary>

Add the converted reports directory and the JUnit XML file to your .gitignore to avoid pushing temporary generated reports to your repository.

```
.currents
results.xml
```

</details>

## Your First Vitest Run

#### Step 1: Run the tests

```sh
npx vitest run
```

Vitest saves the JUnit XML report at the location configured by `outputFile.junit` — `./results.xml` in the examples above.

#### Step 2: Convert the results

Run [currents convert](/resources/reporters/currents-cmd/currents-convert) to convert the JUnit XML report to a Currents-compatible format. Set `--framework-version` to the Vitest version you're running.

```sh
npx currents convert \
  --input-format=junit \
  --input-file=./results.xml \
  --output-dir=.currents \
  --framework=vitest \
  --framework-version=v3.2.4
```

#### Step 3: Upload the results

Run [currents upload](/resources/reporters/currents-cmd/currents-upload) to send the results to Currents dashboard.

```sh
npx currents upload --key=XXX --project-id=YYY
```

Set the [**Record Key**](/guides/record-key) and [**Project ID**](/dashboard/projects/project-settings) obtained from Currents dashboard in the previous step.

## Explore Your First Run

The execution results will show on the Currents dashboard. A link to the run is printed when the upload completes.

<figure><img src="/files/jjG3nJcJ2DzHWzbNLKOH" alt=""><figcaption><p>A link to the recorded results</p></figcaption></figure>

## Good To Know

`vitest run` exits with a non-zero code when tests fail, which stops a CI job before the results are converted and uploaded. Run the conversion and upload steps unconditionally — see [Vitest - GitHub Actions](/getting-started/other-frameworks/vitest/ci-setup/vitest-github-actions) for an example.

## Example

Check out the [Vitest example](https://github.com/currents-dev/currents-junit-xml-example/tree/main/packages/vitest) in the JUnit XML example repository.


# Troubleshooting Vitest

Troubleshooting Vitest integration with Currents

If you are experiencing issues with reporting Vitest results, please collect more information about the failure and submit a support request via our support channels.

### 1. Collecting Environment Information

Please collect the following information to help us effectively debug the problem:

* The associated dashboard Run URL
* The JUnit XML file produced by Vitest
* Your setup method and configuration files
* The exact commands used to run `vitest`, `currents convert` and `currents upload`
* Environment information (use the command below)

Use the following command to print information about your CI environment

```bash
npx envinfo --system --binaries --browsers --npmPackages --duplicates --npmGlobalPackages
```

### 2. Activate Debug Mode

Set `DEBUG=currents*` before running `currents convert` or `currents upload` to obtain detailed information about the conversion and upload process. Alternatively, pass the `--debug` flag to either command.

### 3. Common Issues

<details>

<summary>No results are uploaded</summary>

Check that Vitest actually wrote the JUnit XML file at the path passed to `currents convert --input-file`. Vitest only writes the file when the `junit` reporter is enabled and `outputFile.junit` is set — without `outputFile`, the report is printed to stdout instead.

</details>

<details>

<summary>Conversion or upload is skipped when tests fail</summary>

`vitest run` exits with a non-zero code when tests fail. In CI this stops the job before the results are reported. Make the conversion and upload steps run regardless of the test outcome — see [Vitest - GitHub Actions](/getting-started/other-frameworks/vitest/ci-setup/vitest-github-actions).

</details>

For more details on how to troubleshoot Vitest tests, refer to [their documentation](https://vitest.dev/guide/debugging).


# CI Setup


# Vitest - GitHub Actions

Running Vitest in Parallel on GitHub Actions using Matrix Workflow

{% hint style="info" %}
TL;DR Check out the example repository:

[https://github.com/currents-dev/currents-junit-xml-example](https://github.com/currents-dev/currents-junit-xml-example/tree/main/packages/vitest)
{% endhint %}

Currents uses the native [Vitest sharding](https://vitest.dev/guide/cli#shard) to split the tests between multiple containers. Each shard writes its own JUnit XML report, converts it and uploads it under a shared [CI Build ID](/guides/parallelization-guide/ci-build-id).

Here's an example workflow configuration file:

{% code title=".github/workflows /vitest.yml" overflow="wrap" %}

```yaml
name: Run Vitest

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  test:
    runs-on: ubuntu-latest

    strategy:
      fail-fast: false
      matrix:
        shard: [1, 2]

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "24.x"

      - name: Install dependencies
        run: npm install

      - name: Run tests in shard ${{ matrix.shard }}
        run: npx vitest run --shard=${{ matrix.shard }}/2 --reporter=default --reporter=junit --outputFile.junit=./results.xml

      # `vitest run` exits non-zero on test failures - report the results anyway
      - name: Convert test results to Currents format
        if: always()
        run: npx currents convert --input-format=junit --input-file=./results.xml --output-dir=.currents --framework=vitest --framework-version=v3.2.4

      - name: Upload test results to Currents.dev
        if: always()
        # CURRENTS_RECORD_KEY is a secret stored in the repository settings
        env:
          CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
        run: |
          npx currents upload --project-id XXXXXX --ci-build-id ${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}
```

{% endcode %}

* Get your [Record Key](/guides/record-key) and set [GH secret](https://docs.github.com/en/actions/reference/encrypted-secrets) variable`CURRENTS_RECORD_KEY`.
* Update `npx currents upload` `--project-id` argument to [your project's id](/dashboard/projects/project-settings).
* Set `--framework-version` to the Vitest version installed in the workflow.

### Explore

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td>@currents/cmd</td><td></td><td></td><td><a href="/pages/gYsC6lIgqlpAND2vLZwQ">/pages/gYsC6lIgqlpAND2vLZwQ</a></td></tr><tr><td>CI Build ID</td><td></td><td></td><td><a href="/pages/d7NOovtmXVrt6HaVXgKq">/pages/d7NOovtmXVrt6HaVXgKq</a></td></tr><tr><td>currents convert</td><td></td><td></td><td><a href="/pages/YOhXCVL31whmI0wKNcAX">/pages/YOhXCVL31whmI0wKNcAX</a></td></tr></tbody></table>


# Cypress


# Your First Cypress Run

Running Cypress tests in parallel with Currents Dashboard

{% hint style="warning" %}
**We are suspending our support of Cypress test runner version 13+**

We will continue to support [prior versions](/getting-started/other-frameworks/cypress/integrating-with-cypress/alternative-cypress-binaries) of Cypress.

[Read more](https://currents.dev/posts/v13-blocking)
{% endhint %}

Setting up Currents for running and recording cypress tests in parallel can be done seamlessly within a few minutes.

Here's an overview of what steps you'll need to take to start running cypress tests in parallel using the Currents dashboard:

* Create an organization and a project
* Install `cypress` and [`cypress-cloud`](https://github.com/currents-dev/cypress-cloud) npm packages
* Create a new configuration file `currents.config.js` with the newly created `projectId` and a record key
* Update `cypress.config.js` to include the `cypress-cloud/plugin` plugin
* Use `cypress-cloud` CLI command to create your cypress run
* Update your CI provider configuration

### Create New Organization and a Project

After signing up for the dashboard service, you will be prompted to create a new organization and a project. You can change the name later.

After creating a new organization and a project, you'll see on-screen instructions with your newly created `projectId`

### Install `cypress` and `cypress-cloud`

```bash
npm install cypress cypress-cloud
```

### Create `currents.config.js`

Create a new configuration file and put it in your project's root folder:

```javascript
// currents.config.js
module.exports = {
  projectId: "Ij0RfK", // the projectId from https://app.currents.dev
  recordKey: "xxx", // the record key from https://app.currents.dev
};
```

### Install cypress-cloud plugin

{% tabs %}
{% tab title="cypress.config.js" %}

```javascript
const { defineConfig } = require('cypress')
const { cloudPlugin } = require("cypress-cloud/plugin");

module.exports = defineConfig({
  // ...
  e2e: {
    setupNodeEvents(on, config) {
      return cloudPlugin(on, config);
    },
  }
})
```

{% endtab %}

{% tab title="cypress.config.ts" %}

```typescript
import { defineConfig } from 'cypress'
import { cloudPlugin } from 'cypress-cloud/plugin'
export default defineConfig({
  // ...
  e2e: {
    setupNodeEvents(on, config) {
      return cloudPlugin(on, config);
    },
  }
})
```

{% endtab %}

{% tab title="cypress.json" %}
`cypress-cloud` requires cypress version 10.0.0+. Please refer to our [legacy integration](/resources/reporters/currents-cli) for the setup instructions
{% endtab %}
{% endtabs %}

### Create your first cypress run

Run `currents` command to create your first cypress run in Currents dashboard.

<pre><code><strong>npx cypress-cloud run \
</strong>--parallel \
--record \
--ci-build-id hello-currents
</code></pre>

See all the available options `npx cypress-cloud --help`.

Running this command will create a new run in Currents dashboard.

![Newly Created Cypress Run](/files/jEYG5xmgLoEpbo1p0oWt)

{% hint style="info" %}
Learn more about

* [Integration with Cypress](/getting-started/other-frameworks/cypress/integrating-with-cypress)
* [Record Key](/guides/record-key)
* [CI Build ID](/guides/parallelization-guide/ci-build-id)
  {% endhint %}

### Update your CI provider configuration <a href="#update-your-ci-provider-configuration" id="update-your-ci-provider-configuration"></a>

To unlock the full power of Currents dashboard, update your CI provider configuration to use Currents for running your cypress tests in parallel. Please read our [Parallelization Guide](https://currents.dev/readme/guides/parallelization) and check out few [CI Setup examples](https://currents.dev/readme/ci-setup) for popular CI tools.\ <br>

###


# Integrating with Cypress

Overview of tools available for integrating cypress with Currents or Sorry Cypress

{% hint style="warning" %}
**We are suspending our support of Cypress test runner version 13+**

We will continue to support [prior versions](/getting-started/other-frameworks/cypress/integrating-with-cypress/alternative-cypress-binaries) of Cypress.

[Read more](https://currents.dev/posts/v13-blocking)
{% endhint %}

Currents and Sorry Cypress provide two ways to integrate with cypress runner using the following npm packages:

* [@currents/cli](/resources/reporters/currents-cli) (and its "community" edition [cy2](https://www.npmjs.com/package/cy2))
* [cypress-cloud](/resources/reporters/cypress-cloud)

Both solutions are open-source tools that provide an executable + a programmatic API for integrating cypress with cloud orchestration and recording services like Currents or Sorry Cypress.

The tools use cypress behind the scenes and provide the same flags and configuration options as the original cypress runner.

### What is the difference between @currents/cli and cypress-cloud?

**@cypress/cli** works by rerouting orchestration and recording network requests to currents.dev (or sorry-cypress) servers. It uses the original, "native" orchestration protocol defined by the cypress runner. In Feb 2023, Cypress.io team decided to [restrict access](#user-content-fn-1)[^1] to its internal orchestration and recording protocol, preventing the use of @currents/cli (affected versions are 12.6.0+).

**cypress-cloud** implements its own parallelization and recording protocol and runs cypress in "offline" mode, without tinkering with the cypress internals. The package uses the conventional public APIs that are available for every developer and that are being used by hundreds of [plugins and complimentary tools](https://docs.cypress.io/plugins) of Cypress ecosystem. It is compatible with version 10.0.0+ until version 12.7.4 using the [Alternative Cypress Binaries](/getting-started/other-frameworks/cypress/integrating-with-cypress/alternative-cypress-binaries) for the latest ones.

### What package should I use?

We recommend using **cypress-cloud** for all new installations.

[^1]: ...by showing "Cypress does not support recording test results to this third party service."


# Compatibility

Integrating Cypress with Currents - compatibility table

{% hint style="warning" %}
**We are suspending our support of Cypress test runner version 13+**

We will continue to support [prior versions](/getting-started/other-frameworks/cypress/integrating-with-cypress/alternative-cypress-binaries) of Cypress.

[Read more](https://currents.dev/posts/v13-blocking)
{% endhint %}

We provide several packages to integrate cypress runner with Currents (or Sorry Cypress) orchestration services:

* ☁️ [cypress-cloud](https://github.com/currents-dev/cypress-cloud) - standalone runner for Sorry Cypress and Currents
* \[deprecated] [cy2](https://github.com/sorry-cypress/cy2) - package for integrating arbitrary cloud orchestration services with cypress
* \[deprecated] [@currents/cli](https://www.npmjs.com/package/@currents/cli) - a dedicated package for integrating cypress with Currents cloud service

Please use the table below to select the version of the compatible package.

#### Currents Customers

<table><thead><tr><th>Cypress Version</th><th width="242.33333333333331">@currents/cli [deprecated]</th><th>cypress-cloud</th></tr></thead><tbody><tr><td>13.2.0+</td><td>not supported</td><td>not supported</td></tr><tr><td>13.1.0</td><td>not supported</td><td>not supported</td></tr><tr><td>12.6.0+ (<a href="/pages/z5MkJNyV6aoIsGhQJcdl">Alternative Binaries</a>)</td><td>not supported</td><td>1.4.1+</td></tr><tr><td>12.1.0+</td><td>4.0.3+</td><td>1.4.1+</td></tr><tr><td>12.0.0+</td><td>3.1.3+</td><td>1.4.1+</td></tr><tr><td>11.0.0+</td><td>3.0.0+</td><td>1.4.1+</td></tr><tr><td>6.7.0+</td><td>any version</td><td>not supported</td></tr></tbody></table>

#### Sorry Cypress Users

<table><thead><tr><th>Cypress Version</th><th width="242.33333333333331">cy2 [deprecated]</th><th>cypress-cloud</th></tr></thead><tbody><tr><td>13.2.0+</td><td>not supported</td><td>not supported</td></tr><tr><td>13.1.0</td><td>not supported</td><td>not supported</td></tr><tr><td>12.6.0+ (<a href="/pages/z5MkJNyV6aoIsGhQJcdl">Alternative Binaries</a>)</td><td>not supported</td><td>1.4.1+</td></tr><tr><td>12.1.0+</td><td>4.0.6+</td><td>1.4.1+</td></tr><tr><td>11.0.0+</td><td>4.0.1+</td><td>1.4.1+</td></tr><tr><td>6.7.0+</td><td>any version</td><td>not supported</td></tr></tbody></table>

#### **NX Users**

NX users can use [@currents/nx](https://www.npmjs.com/package/@currents/nx) plugin to conveniently integrate Currents or Sorry Cypress with their project

<table><thead><tr><th width="152.5">Cypress</th><th align="right">@currents/nx</th></tr></thead><tbody><tr><td>12.6.0+ (<a href="/pages/z5MkJNyV6aoIsGhQJcdl">Alternative Binaries</a>)</td><td align="right">2.0.0+</td></tr><tr><td>12.1.0+</td><td align="right">2.0.0+</td></tr><tr><td>12.0.0+</td><td align="right">0.2.1+</td></tr><tr><td>11.0.0+</td><td align="right">0.1.0+</td></tr><tr><td>6.7.0+</td><td align="right">any version</td></tr></tbody></table>


# Alternative Cypress Binaries

Using alternative Cypress Binaries

{% hint style="info" %}
**We are suspending our support of Cypress test runner version 13+**

We will continue to support prior versions of Cypress.
{% endhint %}

Following the blocking of [Sorry Cypress, Currents and DeploySentintel](https://currents.dev/posts/v13-blocking) packages, we are suspending our support of Cypress 13+.

We apologize for the interruption of your workflows and possible downtime caused by the sudden blocking on November 7. We received no communication from Cypress.io team about the intent to release the breaking change.

We will continue supporting prior versions of the MIT-licensed Cypress test runner using independent, block-free versions of binaries.

***

As a background - Cypress installation has 2 components:

* an [npm package](https://www.npmjs.com/package/cypress) `cypress`- a lightweight NodeJS wrapper that parses command line flags, downloads and runs an OS/platform-specific Electron binary application.
* Electron application (binary) - an OS/platform-specific binary code, it is usually pre-installed and cached on docker images or is being downloaded by the npm package.

We are hosting independent versions of the electron app and docker images with pre-installed binaries that you can use without the risk of being blocked. The supported versions:

| Version          | Supported OS-Architecture |
| ---------------- | ------------------------- |
| 9.0.0 - 9.7.0    | All                       |
| 10.0.0 - 10.11.0 | All                       |
| 11.0.0 - 11.1.0  | All                       |
| 12.0.0 - 12.17.3 | `linux-x64, linux-arm64`  |
| 12.17.4          | All                       |

{% hint style="success" %}
Missing specific version, OS or architecture? Not sure what version to use? Let us know!
{% endhint %}

#### Using the alternative binaries

Use a one-liner to install alternative cypress binaries:

```
CYPRESS_DOWNLOAD_MIRROR=https://cy-cdn.currents.dev npx cypress install --force
```

*Alternatively*, follow the step-by-step instructions below:

* Pin `cypress` version to one of the supported versions in `package.json`
  * For example: `"cypress": "12.17.0"`
  * Update your package manager lock file
* Clean the existing Cypress binary `npx cypress cache clear`
* Define [download mirror](https://docs.cypress.io/guides/references/advanced-installation#Mirroring) by configuring environment variable:
  * Linux: `export CYPRESS_DOWNLOAD_MIRROR=https://cy-cdn.currents.dev`
  * Windows cmd: `set CYPRESS_DOWNLOAD_MIRROR=https://cy-cdn.currents.dev`
  * Window PowerShell: `$env:CYPRESS_DOWNLOAD_MIRROR = "https://cy-cdn.currents.dev"`
* Reinstall Cypress App binary from the alternative mirror: `npx cypress install`
* Run your workflows as usual

#### Using Docker images with pre-installed binaries

Use the following [docker image](https://hub.docker.com/r/currentsdev/cypress-included) that has pre-installed, block-free binaries to run your workflows:

`docker pull currentsdev/cypress-included:<version>`

#### Examples

* GitHub Actions [example workflow](https://github.com/currents-dev/currents-examples/blob/main/cypress/github-actions/.github/workflows/currents.yml) with `cypress-io/github-action@v6`

Please contact our support channels for additional information and assistance.


# CI Setup


# Cypress - GitHub Actions

Using GitHub Actions Matrix for parallelizing Cypress tests

{% hint style="info" %}
TL;DR Check out the GitHub repository:

[https://github.com/currents-dev/currents-examples](https://github.com/currents-dev/currents-examples/tree/main/cypress/github-actions)
{% endhint %}

By using [GitHub Actions matrix execution strategy](https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstrategymatrix), you can create multiple containers that will run Cypress tests in parallel. Currents orchestrates the tests between multiple containers, applying intelligent optimizations to reduce the overall runtime of your workflow, and records screenshots and videos for later troubleshooting.

<figure><img src="/files/8ZAetkXmthHKtz1KIulH" alt="Tests Parallelization with Github Actions"><figcaption><p>Tests Parallelization with Github Actions</p></figcaption></figure>

Please take a look at the [example repository](https://github.com/currents-dev/currents-examples/tree/main/cypress/github-actions) that showcases running cypress tests in parallel using GitHub Actions.

{% code overflow="wrap" %}

```yaml
name: Cypress Tests

on:
  push:

jobs:
  cypress-tests:
    runs-on: ubuntu-20.04
    strategy:
      fail-fast: false
      matrix:
        # 👉🏻 run 3 copies of the current job in parallel
        containers: [1, 2, 3]
    steps:
      - name: Checkout
        uses: actions/checkout@v3
        # 👉🏻  populate commit message for merge commits
        # see https://currents.dev/readme/ci-setup/github-actions
        # with:
        #  ref: ${{ github.event.pull_request.head.sha }}

      - uses: actions/setup-node@v3
        with:
          node-version: "24.x"

      - name: Install dependencies
        run: |
          npm ci

      # More about the blocking:
      # - https://currents.dev/posts/v13-blocking
      # - https://currents.dev/readme/integration-with-cypress/alternative-cypress-binaries
      - name: Unblock Cypress
        run: |
          echo 🕊️ Download Free Cypress
          CYPRESS_DOWNLOAD_MIRROR=https://cy-cdn.currents.dev npx cypress install --force

          echo ✅ Verify Cypress
          npx cypress verify

          echo 👀 Cypress Cache
          npx cypress cache list
          npx cypress cache path

      # 
      - name: Run Cypress on Currents.dev
        env:
          # enable verbose logging for cypress-io/github-action
          DEBUG: \@cypress/github-action
        uses: cypress-io/github-action@v6
        continue-on-error: true

        with:
          # 🔥 Set to false to prevent restoring cachedCypress binary
          install: false
          command: |
            npx cypress-cloud --record --parallel --browser chrome --key ${{ secrets.CURRENTS_RECORD_KEY }} --ci-build-id "${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt}}"

      - name: Cancel the run if workflow is cancelled
        if: ${{ cancelled() }}
        uses: currents-dev/cancel-run-gh-action@v1
        with:
          api-token: ${{ secrets.CURRENTS_API_KEY }}
          github-run-id: ${{ github.run_id }}
          github-run-attempt: ${{ github.run_attempt }}
```

{% endcode %}

The example [workflow config file](https://github.com/currents-dev/currents-examples/blob/main/cypress/github-actions/.github/workflows/currents.yml):

* runs 3 containers with cypress tests in parallel
* uses [Custom Test Command](https://github.com/cypress-io/github-action#custom-test-command) to run `cypress-cloud` for recording test results and parallelization with [Currents.dev](https://currents.dev)
* Note: set the `projectId` in `currents.config.js` (you can obtain the project id from [Currents.dev](https://app.currents.dev) in Project Settings)
* Note: install `cypress-cloud/plugin` in `cypress.config.js`
* Note: use CLI arguments to customize your cypress runs, e.g.: `cypress-cloud run --parallel --record --key <your currents.dev key> --group groupA`
* Note: create an organization, get your record key on [Currents.dev](https://app.currents.dev) and set [GH secret](https://docs.github.com/en/actions/reference/encrypted-secrets) variable `CURRENTS_RECORD_KEY`


# Cypress - GitLab CI/CD

Running Cypress test in parallel on GitLab

{% hint style="info" %}
TL;DR Take a look at an example repository:

<https://gitlab.com/currents.dev/gitlab-currents-example>
{% endhint %}

GitLab CI/CD platform allows effectively running your Playwright and Cypress test in parallel, using multiple containers and Currents for tests orchestration.

To run Cypress tests in parallel, define [`parallel`](https://docs.gitlab.com/ee/ci/jobs/job_control.html#parallelize-large-jobs) job parameters in GitLab CI/CD pipeline configuration file.

GitLab will run the jobs on multiple containers - each container will run a unique set of tests using Currents orchestration service. Currents applies intelligent optimizations and sorts the test to reduce the overall runtime of the pipeline.

![Using Gitlab CI/CD parallel jobs for running cypress tests in parallel](/files/csQ6bDuwbqgEtNoXBkwK)


# Cypress - Jenkins

Running Cypress tests in parallel with Jenkins and Currents Dashboard

Here's an example of Jenkins pipeline that is running cypress tests in parallel on 2 workers and is connected to Currents Dashboard for orchestrating the parallel runs and reporting the results.

The pipeline will be running 2 workers, based on `cypress/base:16` Docker image. Those workers will run all the tests in parallel.

The steps are:

* Use `cypress/base:18` as the base image
* Install the necessary dependencies: `cypress` and `cypress-cloud`
* Populate the environment variable `CURRENTS_RECORD_KEY` using [Jenkins Credentials Store](https://jenkins.io/doc/book/using/using-credentials/). Learn more about [Record Key](/guides/record-key)
* Run cypress tests on 2 workers, using CI Build ID for "connecting" the workers to the same parallel run.

{% code overflow="wrap" %}

```
npx cypress-cloud run --parallel --record --key ${env.CURRENTS_RECORD_KEY} --ci-build-id ${env.BRANCH_NAME}-${env.BUILD_ID}"
```

{% endcode %}

Here's the full Jenkins pipeline configuration file:

{% code overflow="wrap" %}

```groovy
pipeline {
  agent {
    // this image provides everything needed to run Cypress
    docker {
      image 'cypress/base:18'
    }
  }

  stages {
    // installs node dependencies and Cypress binary
    stage('build') {
      steps {
        echo "Running build ${env.BUILD_ID} on ${env.JENKINS_URL}"
        sh 'npm install cypress cypress-cloud'
      }
    }

    // this stage runs cypress tests, and each agent uses the workspace
    // from the previous stage
    stage('cypress parallel tests') {
      environment {
        // see https://jenkins.io/doc/book/using/using-credentials/
        CURRENTS_RECORD_KEY = credentials('currents-record-key')
        // Prevent deletion of videos to avoid race condition
        CYPRESS_trashAssetsBeforeRuns = 'false'
      }

      // Run parallel workers, see:
      // https://jenkins.io/doc/book/pipeline/syntax/#parallel
      parallel {
        // each worker is running the same command, 
        // Currents Dashboard will orchestrate the tests between 
        // the workers
        stage('tester A') {
          steps {
            echo "Running build ${env.BUILD_ID}"
            sh "npx cypress-cloud run --parallel --record --key ${env.CURRENTS_RECORD_KEY} --ci-build-id ${env.BRANCH_NAME}-${env.BUILD_ID}"
          }
        }

        // second tester runs the same command
        stage('tester B') {
          steps {
            echo "Running build ${env.BUILD_ID}"
            sh "npx cypress-cloud run --parallel --record --key ${env.CURRENTS_RECORD_KEY} --ci-build-id ${env.BRANCH_NAME}-${env.BUILD_ID}"
          }
        }
      }

    }
  }
}
```

{% endcode %}


# Cypress - CircleCI

Running Cypress tests in parallel on CircleCI and Currents dashboard

{% hint style="info" %}
TL;DR Check out the example repository:

[https://github.com/currents-dev/currents-examples](https://github.com/currents-dev/currents-examples/tree/main/cypress/circleci)
{% endhint %}

This is an example repository that showcases using [CircleCI](https://circleci.com/) with [Currents.dev](https://currents.dev/).

We are hosting independent versions of the Cypress App and [docker images](https://hub.docker.com/r/currentsdev/cypress-included) with pre-installed binaries. Please refer to the [documentation](https://currents.dev/readme/integration-with-cypress/alternative-cypress-binaries) for the list of supported binaries and versions.

The example [config file](https://github.com/currents-dev/currents-examples/blob/main/cypress/circleci/.circleci/config.yml) installs the custom Cypress App and runs 3 containers with Cypress tests in parallel using various setup scenarios.

### Prerequisites

* Create an account at https\:/app.currents.dev.
* Obtain **ProjectId** and **Record Key**.
* Set `CURRENTS_RECORD_KEY`:
  * create [CircleCI context](https://circleci.com/docs/guides/security/contexts/) and set `CURRENTS_RECORD_KEY`.
  * alternatively, set [Environment variable](https://circleci.com/docs/guides/security/env-vars/) `CURRENTS_RECORD_KEY`
* Follow the setup instructions at [cypress-cloud](/resources/reporters/cypress-cloud) to create `currents.config.js` set your `projectId`

### Bare CircleCI configuration

Please refer to the setup scenario that fits your needs.

#### Use Docker image with pre-installed Cypress

CircleCI configuration that uses Docker image with pre-installed cypress app. Refer to the [documentation](https://currents.dev/readme/integration-with-cypress/alternative-cypress-binaries) for the list of supported binaries and versions.

```
version: 2.1

jobs:
  # Use pre-built image with alternative Cypress binary
  noorbs currents-image:
    parallelism: 3
    docker:
      - image: currentsdev/cypress-included:12.17.4
    steps:
      - checkout
      - run:
          name: Install Dependencies
          command: npm ci
      - run:
          name: Run tests
          command: npx cypress-cloud run --parallel --record --key $CURRENTS_RECORD_KEY

workflows:
  noorbs:
    jobs:
      - noorbs currents-image:
          context: currents
```

#### Explicitly downloading alternative Cypress binary

CircleCI configuration that explicitly downloads alternative Cypress binary. Refer to the [documentation](https://currents.dev/readme/integration-with-cypress/alternative-cypress-binaries) for the list of supported binaries and versions.

```
version: 2.1

jobs:
  # Explicitly download Cypress binary
  noorbs explicit-download:
    parallelism: 3
    docker:
      - image: cypress/base:18.16.1
    steps:
      - checkout
      - run:
          name: Install dependencies
          command: npm ci
      - run:
          name: Download Alternative Cypress Binaries
          command: CYPRESS_DOWNLOAD_MIRROR=https://cy-cdn.currents.dev npx cypress install --force
      - run:
          name: Run tests
          command: npx cypress-cloud run --parallel --record --key $CURRENTS_RECORD_KEY

workflows:
  noorbs:
    jobs:
      - noorbs explicit-download:
          context: currents
```

### Using Cypress Orb with default executor

[Cypress Orb](https://circleci.com/developer/orbs/orb/cypress-io/cypress) has pre-defined commands that facilitate creating CircleCI configuration. The examples below show how to integrate Cypress tests with Currents using Cypress Orb and various setup scenarios.

The examples below use [Custom Test Command](https://github.com/currents-dev/currents-examples/blob/main/cypress/circleci/.circleci/config.yml#L9) to run `cypress-cloud` for recording test results and parallelization with [Currents.dev](https://currents.dev/)

#### Using `cypress/default` executor example

The configuration below uses the default `cypress/default` [CircleCI executor](https://circleci.com/docs/executor-intro/) and installs custom Cypress binary during `cypress/install` step:

```
version: 2.1

orbs:
  cypress: cypress-io/cypress@3

jobs:
  # Use cypress/default executor example
  default-executor cypress-install:
    executor: cypress/default
    steps:
      - cypress/install:
          post-install: CYPRESS_DOWNLOAD_MIRROR=https://cy-cdn.currents.dev npx cypress install --force
      - persist_to_workspace:
          root: ~/
          paths:
            - .cache/Cypress
            - project

  default-executor cypress-run:
    executor: cypress/default
    parallelism: 3
    steps:
      - attach_workspace:
          at: ~/
      - cypress/run-tests:
          cypress-command: npx cypress-cloud run --parallel --record --key $CURRENTS_RECORD_KEY

workflows:
  with-orbs default-executor:
    jobs:
      - default-executor cypress-install
      - default-executor cypress-run:
          context: currents
          requires:
            - default-executor cypress-install
```

#### Using custom executor with pre-installed Cypress App

The configuration below uses the [custom executor](https://circleci.com/docs/executor-intro/) with pre-installed Cypress App.

```
version: 2.1

orbs:
  cypress: cypress-io/cypress@3

executors:
  # define custom executors
  currents-executor:
    docker:
      - image: currentsdev/cypress-included:12.17.4

jobs:
  # Use currentsdev executor with pre-installed Cypress binary
  custom-executor cypress-install:
    executor: currents-executor
    steps:
      - cypress/install
      - persist_to_workspace:
          root: ~/
          paths:
            - project

  custom-executor cypress-run:
    executor: currents-executor
    parallelism: 3
    steps:
      - attach_workspace:
          at: ~/
      - cypress/run-tests:
          cypress-command: npx cypress-cloud run --parallel --record --key $CURRENTS_RECORD_KEY

workflows:
  with-orbs custom-executor:
    jobs:
      - custom-executor cypress-run:
          context: currents
```

#### Use Docker image with pre-installed Cypress

CircleCI configuration that uses Docker image with pre-installed cypress app. Refer to the [documentation](https://currents.dev/readme/integration-with-cypress/alternative-cypress-binaries) for the list of supported binaries and versions.


# Cypress - Bitbucket Pipelines

Running Cypress tests in parallel on Bitbucket Pipelines and Currents dashboard

{% hint style="info" %}
TL;DR Check out the example repository:

[https://bitbucket.org/currents-org/currents-cypress-example](https://bitbucket.org/currents-org/currents-cypress-example/src/master/)
{% endhint %}

The example [config file](https://bitbucket.org/currents-org/currents-cypress-example/src/2e36527ccf01c9135dd51afaf620e7f930571dd9/bitbucket-pipelines.yml):

* uses a [docker image](https://hub.docker.com/r/currentsdev/cypress-included) with a pre-installed [alternative Cypress test runner](https://currents.dev/readme/integration-with-cypress/alternative-cypress-binaries) that allows using alternative orchestration services like Sorry Cypress and Currents.
* runs 3 containers with cypress tests in parallel using [`cypress-cloud`](https://github.com/currents-dev/cypress-cloud) integration package and the command below:

```
npx cypress-cloud --key $CURRENTS_RECORD_KEY --parallel
```

### Setup <a href="#markdown-header-setup" id="markdown-header-setup"></a>

* Create an account at <https://app.currents.dev>
* Get your **Record Key** and set [Secure Bitbucket Pipeline variable](https://support.atlassian.com/bitbucket-cloud/docs/variables-and-secrets/#Secured-variables) `CURRENTS_RECORD_KEY`
* Get your **Project ID** and update the contents of `currents.config.js`
* Follow the install instructions for [`cypress-cloud`](https://github.com/currents-dev/cypress-cloud) package
* Use CLI arguments to customize your cypress-cloud runs, e.g.: `npx cypress-cloud run --parallel --record --key <your currents.dev key> --group groupA`
* Note: Currents will automatically detect CI Build ID for Bitbucket Pipeline execution. Read the [guide](https://currents.dev/readme/guides/ci-build-id) for more advanced use cases.
* Note: Refer to the recent [Pipeline executions](https://bitbucket.org/currents-org/currents-cypress-example/pipelines/results/page/1) to see the setup in action

### Adding Bitbucket status check <a href="#markdown-header-adding-bitbucket-status-check" id="markdown-header-adding-bitbucket-status-check"></a>

[Currents integration with Bitbucket](https://currents.dev/readme/integrations/bitbucket) posts runs progress and outcome for every Bitbucket Pipeline invocation:

![](https://bytebucket.org/currents-org/currents-cypress-example/raw/2e36527ccf01c9135dd51afaf620e7f930571dd9/images/integration.png)

### Using Alternative Cypress Binaries <a href="#markdown-header-using-alternative-cypress-binaries" id="markdown-header-using-alternative-cypress-binaries"></a>

Currents team is maintaining an alternative version of the MIT-licensed Cypress test runner, compatible in features and open for using with recording services like Sorry Cypress and Currents.

See [Alternative Cypress Binaries](/getting-started/other-frameworks/cypress/integrating-with-cypress/alternative-cypress-binaries).


# Cypress - Azure DevOps

Running Cypress test in parallel on Azure DevOps and Currents Dashboard

This guide will help you to run Cypress tests in parallel using Azure DevOps and Currents Dashboard. The example showcases using 3 Azure DevOps containers for parallelizing the execution using Currents as an orchestration and reporting service.

{% hint style="info" %}
TLDR; Check out the example Azure DevOps pipeline [configuration file](https://github.com/currents-dev/currents-examples/blob/main/cypress/azure-devops/azure-pipelines.yml)
{% endhint %}

* Connect a new/existing pipeline to a repository containing your Cypress tests
* Make sure that your `cypress.config.js` file has the correct `projectId`. You can fetch the `projectId` by navigating to <https://app.currents.dev> and then **Project Name > Manage Project**
* Make sure that both `cypress` and [cypress-cloud](/resources/reporters/cypress-cloud) are listed in your `package.json` as dependencies
* Create or modify an existing [Variable Group](https://learn.microsoft.com/en-us/azure/devops/pipelines/library/variable-groups?view=azure-devops\&tabs=yaml), and add a new secret variable called `CURRENTS_SECRET`. You can grab the secret key at **Currents Dashboard > Org Name (Header Menu) > Record Keys**
* Modify your `azure-pipelines.yml` file and use [this file](https://github.com/currents-dev/currents-examples/blob/main/cypress/azure-devops/azure-pipelines.yml) as a reference.

```yaml
jobs:
  - job: Cypress_e2e_tests
    pool:
      vmImage: "ubuntu-latest"
    # Use 3 containers for parallel execution, use 
    strategy:
      parallel: 3
    # Fetch the secrets from Variable Group names "Currents"
    variables:
      - group: Currents
    steps:
      # Use Node@16 container
      - task: NodeTool@0
        inputs:
          versionSpec: "16.x"
          displayName: "Install Node.js"

      # Speed up the execution by caching the dependencies
      - task: CacheBeta@1
        inputs:
          key: npm | $(Agent.OS) | package-lock.json
          path: /home/vsts/.npm
          restoreKeys: npm | $(Agent.OS) | package-lock.json
        displayName: Cache NPM packages

      # cache cypress binary, which is installed at a different location
      - task: CacheBeta@1
        inputs:
          key: cypress | $(Agent.OS) | package-lock.json
          path: /home/vsts/.cache/Cypress
          restoreKeys: cypress | $(Agent.OS) | package-lock.json
        displayName: Cache Cypress binary

      # Install Node dependencies
      - script: npm ci
        displayName: "Install NPM dependencies"

      # Grab 
      # - CURRENTS_PROJECT_ID
      # - CURRENTS_RECORD_KEY
      # at https://app.currents.dev 
      #
      # Read more about CI Build ID:
      # https://currents.dev/readme/guides/cypress-ci-build-id

      # Note the use of `currents` command
      - script: |
          npx cypress-cloud run --record --parallel --key $CURRENTS_RECORD_KEY --ci-build-id $BUILD_BUILDNUMBER
        displayName: "Run Currents tests"
        env:
          CURRENTS_RECORD_KEY: $(CURRENTS_SECRET)
```

Pipeline executions will be orchestrated via the Currents Dashboard, and execution results and artifacts will be automatically uploaded as well.

<figure><img src="/files/DjiqO8kw8NtErgwKInKu" alt=""><figcaption><p>Running Cypress Tests in Azure DevOps Pipeline</p></figcaption></figure>

<figure><img src="/files/Q2klfrhorvt4Bc7oeO9d" alt=""><figcaption><p>Running Cypress Tests in Azure DevOps Pipeline</p></figcaption></figure>


# Cypress - AWS Code Build

Running Cypress in parallel on AWS CodeBuild

{% hint style="info" %}
TL;DR Check out the example repository:

[https://github.com/currents-dev/currents-examples](https://github.com/currents-dev/currents-examples/tree/main/cypress/aws-codebuild)
{% endhint %}

Executing Cypress tests in parallel on AWS CodeBuild can significantly reduce the overall run duration. AWS CodeBuild supports [Batched Build](https://docs.aws.amazon.com/codebuild/latest/userguide/batch-build.html) in [matrix mode](https://docs.aws.amazon.com/codebuild/latest/userguide/batch-build.html#batch_build_matrix) for launching several workers in parallel.

Those workers will use Currents as an orchestration service - each worker will run a subset of spec files and report the results to the cloud dashboard for convenient reporting and troubleshooting.

### Prerequisites

To enable parallel runs, please make sure:

* you have privileged access to your AWS Account
* you have an AWS CodeBuild project created with the batched configuration enabled

### Configuration Steps

The first step is to create a `buildspec.yml` file in the root directory of your application's source code repository. This file defines the build and test steps for your application.

In the `buildspec.yml` file, you need to create multiple workers that will run your Cypress tests in parallel by setting the desired number of workers. See an example with 3 workers below:

```yaml
## buildspec.yml
version: 0.2

batch:
  fast-fail: false
  build-matrix:
    dynamic:
      buildspec:
        - buildspec.yml
      env:
        variables:
          WORKERS:
            - 1
            - 2
            - 3

  phases:
    install:
      runtime-versions:
        nodejs: latest
      commands:
        # Set COMMIT_INFO variables to send Git details to Currents
        - export COMMIT_INFO_BRANCH="$(git rev-parse HEAD | xargs git name-rev |
          cut -d' ' -f2 | sed 's/remotes\/origin\///g')"
        - export COMMIT_INFO_MESSAGE="$(git log -1 --pretty=%B)"
        - export COMMIT_INFO_EMAIL="$(git log -1 --pretty=%ae)"
        - export COMMIT_INFO_AUTHOR="$(git log -1 --pretty=%an)"
        - export COMMIT_INFO_SHA="$(git log -1 --pretty=%H)"
        - export COMMIT_INFO_REMOTE="$(git config --get remote.origin.url)"
        - npm ci
    build:
      commands:
        - npx cypress-cloud run --record --parallel --ci-build-id $CODEBUILD_INITIATOR
```

You must also include the necessary commands to install Cypress, configure parallel execution, and run your tests.

By distributing tests to each worker, Currents enables faster execution of Cypress tests on AWS CodeBuild. This parallel execution ensures quicker feedback from your browser test suite while leveraging intelligent optimizations to minimize the overall runtime.

Additionally, Currents captures screenshots and videos during the test execution, facilitating troubleshooting efforts.

### Example: Cypress Tests in parallel on AWS CodeBuild

Please refer to [example repository](https://github.com/currents-dev/currents-examples/tree/main/cypress/aws-codebuild) that demonstrates how to set up AWS Code Build for running cypress tests in parallel using [Currents](https://currents.dev) service.

The example [config file](https://github.com/currents-dev/currents-examples/blob/main/cypress/aws-codebuild/buildspec.yml):

* uses 3 workers in [matrix mode](https://docs.aws.amazon.com/codebuild/latest/userguide/batch-build.html#batch_build_matrix).
* is designed to be executed within a [batch build](https://docs.aws.amazon.com/codebuild/latest/userguide/batch-build.html).

Note:

* The example uses [CODEBUILD\_INITIATOR](https://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref-env-vars.html) as a [CI Build ID](https://currents.dev/readme/guides/cypress-ci-build-id). When testing interactively, the CODEBUILD\_INITIATOR will be set to the username of the build initiator. When running a batched build, the variable will have the batch build id. Read more about [CI Build ID](/guides/parallelization-guide/ci-build-id)
* get your record key from [Currents.dev](https://app.currents.dev/) and set [AWS CodeBuild Environment Variable](https://docs.aws.amazon.com/codebuild/latest/userguide/change-project-console.html#change-project-console-environment) variable `CURRENTS_RECORD_KEY`. Read more about [Record Key](/guides/record-key)
* set the `projectId` in `currents.config.js` - obtain the project id from [Currents.dev](https://app.currents.dev/)
* use CLI arguments to customize your cypress-cloud runs, e.g.: `npx cypress-cloud run --parallel --record --key <your currents.dev key> --group groupA`


# Cypress - NX

Running Cypress tests with NX

{% hint style="info" %}
The instructions below apply to **@currents/nx 2.0.0+**
{% endhint %}

### Running cypress tests in NX project with Currents

[Nx](https://github.com/nrwl/nx) is a build system with monorepo support and powerful integrations. You can run cypress tests on Currents using [`@currents/nx` plugin](https://www.npmjs.com/package/@currents/nx) and defining a few configuration options.

### Example

See <https://github.com/currents-dev/currents-nx> for an example installation and configuration

### Setting up cypress with NX

First, install `@currents/nx` npm package.

```sh
npm i --save-dev @currents/nx cypress-cloud
# install cypress if needed
npm i --save-dev cypress
```

Add `currents` target to your project configuration.

```json
{
  "targets": {
    "currents": {
      "executor": "@currents/nx:currents",
      "options": {
        "record": true,
        "parallel": true,
        "cypressConfig": "apps/app-e2e/cypres.config.ts",
        "devServerTarget": "my-react-app:serve",
        "testingType": "e2e"
      }
    }
  }
}

```

Create a new configuration file: `currents.config.js` next to `cypress.config.{jt}s`

```javascript
// currents.config.js
module.exports = {
  // Set the `projected` and the record key obtained from https://app.currents.dev or your self-hosted instance of Sorry Cypress
  projectId: 'IfERfK',
  // Sorry Cypress users - set the director service URL
  cloudServiceUrl: 'https://cy.currents.dev',
};
```

Add `cypress-cloud/plugin` to `cypress.config.{js|ts|mjs}`

```typescript
import { nxE2EPreset } from '@nrwl/cypress/plugins/cypress-preset';
import { defineConfig } from 'cypress';
import cloudPlugin from 'cypress-cloud/plugin';

export default defineConfig({
  e2e: {
    ...nxE2EPreset(__dirname, {
      bundler: 'vite',
    }),
    specPattern: './src/**/*.cy.ts',
    setupNodeEvents(on, config) {
      return cloudPlugin(on, config);
    },
  },
});
```

### Usage

```
npx nx run web-e2e:currents --key <recordKey> --ci-build-id hello-currents-nx
```

* Update your `currents.config.js` file with `projectId` obtained at [https://app.currents.dev](https://app.currents.dev/)
* Use the record key obtained at [https://app.currents.dev](https://app.currents.dev/)
* Learn more about [CI Build ID](/guides/parallelization-guide/ci-build-id)


# Troubleshooting Cypress

Troubleshooting Currents integration with Cypress

{% hint style="warning" %}
**We are suspending our support of Cypress test runner version 13+**

We will continue to support [prior versions](/getting-started/other-frameworks/cypress/integrating-with-cypress/alternative-cypress-binaries) of Cypress.

[Read more](https://currents.dev/posts/v13-blocking)
{% endhint %}

If you are experiencing issues with using `@currents/cli` or `cypress-cloud`, please submit a support request either via in-app support chat or on GitHub:

* [@currents/cli GitHub Issues](https://github.com/currents-dev/cli/issues)
* [cypress-cloud GitHub Issues](https://github.com/currents-dev/cypress-cloud/issues)

Please collect the following information to help us effectively debug the problem:

* The associated dashboard run URL
* Screenshots if applicable
* The exact command used to run `currents` or `cypress-cloud`
* Configuration files (`cypress.config.{jt}s` and `currents.config.js`)
* CI environment information (use the command below)

```bash
npx envinfo --system --binaries --browsers --npmPackages --duplicates --npmGlobalPackages
```

* Activate debug mode and collect the logs

{% hint style="info" %}
Please capture and share the **whole** debug log - that will help the support person identify the root cause faster
{% endhint %}

### Enabling `DEBUG` mode for `cypress-cloud@1.9.0+`

Starting from version 1.9.0 `cypress-cloud` provides a CLI flag for activating the debug mode.

```
npx cypress-cloud run ... --cloud-debug
```

You can specify the scope of debug messages printed

* `true | all` show all debug messages
* `cypress` activate debug mode for cypress only
* `currents` activate the debug mode for currents only
* `commit-info` activate the debug mode for git commit info only

### Enabling DEBUG mode for `@currents/cli` and `cypress-cloud < 1.9.0`

{% tabs %}
{% tab title="cypress-cloud" %}

```
# on Linux
DEBUG=currents:*,cypress:* npx cypress-cloud run ...

# on Windows
cmd /V /C "set DEBUG=currents:*,cypress:*&& npx cypress-cloud run ..."
```

{% endtab %}

{% tab title="@currents/cli" %}

```
# on Linux
DEBUG=cy2*,cypress:* npx currents run ...

# on Windows
cmd /V /C "set DEBUG=cy2*,cypress:*&& npx currents run ..."
```

{% endtab %}
{% endtabs %}


# Overview

Fix and auto-heal failing Playwright tests in CI with AI agents - MCP server, IDE extension, dashboard prompts, agent skills, and automation

Currents captures everything about your Playwright test runs in CI: errors, stack traces, traces, console and network logs, historical pass/fail data, flakiness rates, and performance metrics. This page is an overview of the ways to put that data in front of an AI agent - whether you are debugging interactively in your editor, triaging failures from the dashboard, or building pipelines that auto-heal failing tests before anyone looks at the run.

## Why context matters

Pasting an error message into an AI chat is the least effective way to get an AI fix for a Playwright test failure. The error message alone is missing most of what determines the right fix:

* Is this test flaky, or did it just start failing? An agent that doesn't know the test's history will "fix" a flaky test by treating a symptom.
* What was on the page when the assertion failed? Without the DOM state, the agent guesses why a locator didn't match.
* Did other tests in the run fail for the same reason? A selector change that breaks 12 tests needs one fix, not 12.

Currents post-processes test results on the server into a structured troubleshooting context that answers these questions:

* Full error message, stack trace, and code frame (ANSI codes stripped)
* An **error-context snapshot** captured at the moment of failure: the page accessibility tree, console output, and network logs
* Historical pass/fail data and flakiness rates for the test
* Run, spec, instance, and attempt identifiers the agent can use to query further details via [MCP](/ai/mcp-server)

Every entry point below delivers this same context - they differ in where you are when you use them and how much of the loop is automated.

## Entry points

| Method                                                                   | Where                             | Best for                                                                         |
| ------------------------------------------------------------------------ | --------------------------------- | -------------------------------------------------------------------------------- |
| [MCP Server](/ai/mcp-server)                                             | Any MCP-capable agent             | Agents querying runs, tests, and analytics on demand; autonomous troubleshooting |
| [IDE Extension](/ai/ide-extension)                                       | VS Code, Cursor, compatible forks | Debugging CI failures without leaving the editor                                 |
| [Fix with AI](#fix-with-ai-from-the-dashboard)                           | Currents dashboard                | Handing a failure to an agent while triaging a run                               |
| [Slack Fix with AI](/resources/integrations/slack/slack-app#fix-with-ai) | Slack                             | Handing a failed-test notification to an agent from a channel                    |
| [Playwright Skill](/ai/agent-skill-playwright-best-practices)            | Claude Code, Cursor, other agents | Teaching agents how to write and fix Playwright tests correctly                  |
| [n8n](/resources/integrations/n8n)                                       | n8n workflows                     | Automated triage, notifications, and agent pipelines without code                |

### MCP Server

The [Currents MCP server](/ai/mcp-server) is the foundation the other entry points build on. It exposes tools for retrieving projects, runs, test results, spec instances, and performance analytics, so any MCP-capable agent - Claude Code, Cursor, or a custom agent built on the Model Context Protocol - can pull test data on demand instead of relying on what you paste into the prompt.

This is what makes auto-healing possible rather than one-shot fixes: an agent given a run ID can enumerate the failures, fetch each test's error details and history, decide which failures share a root cause, implement a fix, and verify it - querying for more context at every step instead of working from a fixed snapshot.

What agents accomplish with the MCP server in practice:

* **Failure triage** - summarize a run, group failures by root cause, and separate new regressions from known flaky tests
* **AI fixes with verification** - fix a failing test, then check the next run's results to confirm the fix held
* **Flakiness burn-down** - rank tests by flakiness over a date range and work through them systematically
* **Performance investigation** - find the slowest specs and tests, and track duration changes across runs
* **Cross-run analysis** - answer "when did this start failing?" or "does this fail on every branch or just mine?" from run history

Example prompts:

* "Tests are failing in CI. Get the details for run `<runId>` and fix the failures."
* "Summarize the last run - group the failures by likely root cause and tell me which are new versus known flaky."
* "What were the top flaky tests in the last 30 days? Fix the three worst ones."
* "What are the slowest specs in the last 7 days? Suggest what to split or parallelize."
* "When did `checkout.spec.ts` start failing, and what changed in its error message between runs?"

The Currents MCP server pairs well with browser-automation MCP servers such as [Playwright MCP](https://github.com/microsoft/playwright-mcp): Currents supplies what failed in CI and why, and the browser tools let the agent reproduce the failure in a live browser before committing a fix.

Access is scoped by the API key you configure. Use a **Read Only** key when the agent only needs to read results; a **Read & Write** key additionally allows operations like canceling runs or managing webhooks, including some irreversible deletions. See [MCP Server](/ai/mcp-server) for the permission model and [API Keys](/dashboard/administration/api-keys) for creating scoped keys.

### IDE Extension

The [IDE extension](/ai/ide-extension) brings CI runs, failure details, and flaky test analytics into VS Code, Cursor, and other compatible editors. Its **Fix with agent** actions assemble the full troubleshooting context - the processed error, test history, and the error-context snapshot - and hand it to your editor's AI assistant, scoped to a single test, a spec file, or all failures in a run.

{% embed url="<https://player.mux.com/iA00R00026FMz9ktoCreZIl89xjOKbi1T2Mk3OrPy00S1j8?metadata-video-title=Current+IDE+Extension+-+fastest+way+to+fix+CI+failure&video-title=Current+IDE+Extension+-+fastest+way+to+fix+CI+failure>" %}

The extension also registers the Currents MCP server automatically, so the agent can follow up with its own queries after the initial prompt. An **Analyze with Currents** action on every test definition pulls recent failure and flakiness data for that specific test - useful for investigating a test before it becomes a problem, not just after it fails.

This is the fastest interactive loop: failure feed, trace viewer, source code, and agent all in one place.

### Fix with AI from the dashboard

When you're triaging a run in the dashboard, every failed test attempt has a **Fix with AI** action. It generates a prompt containing the processed error, code frame, a link to the error-context snapshot, and the MCP identifiers (project, run, instance, test, attempt) an agent needs to fetch deeper context.

You can copy the prompt to your clipboard for any agent, or open it directly in a supported tool - Cursor, GitHub Copilot, Claude Code, Zed, Conductor, or Codex. The dashboard remembers your preferred target.

<figure><img src="/files/lYpx7zUoyVOfgwoRMaKy" alt=""><figcaption></figcaption></figure>

This is the bridge from investigation to action: whoever is looking at the failing run - not necessarily the person with the repo open - can package the failure with its full context and route it to an agent in one click.

### Fix with AI from Slack

Failed-test notifications from the [Slack App](/resources/integrations/slack/slack-app#fix-with-ai) include a **Fix with AI** button. You can send the failed test context to Cursor, GitHub Copilot, Claude Code, Codex, Zed, Conductor, and other AI agents - routing a failure to an agent from a team channel without opening the Currents dashboard.

### Playwright Skill

Context tells an agent *what* failed; the [Playwright Best Practices skill](/ai/agent-skill-playwright-best-practices) tells it *how* to fix it well. It's an [Agent Skill](https://agentskills.io/home) - an open standard supported by Claude Code, Cursor, VS Code, and others - that packages expert Playwright knowledge: locator strategy, web-first assertions, debugging flaky tests, CI configuration, and more.

{% hint style="success" icon="trophy" %}
As of July 2026, it is the most-installed Playwright skill on [skills.sh](https://skills.sh) - over 64K installs - and the second-ranked result among all skills for the "playwright" keyword.
{% endhint %}

<figure><img src="/files/8RLijAPE6P06ThtOmF8I" alt=""><figcaption></figcaption></figure>

Without it, agents fall back on generic patterns from training data - sprinkling `waitForTimeout` calls, brittle CSS selectors, retries that mask real bugs. With it, fixes follow the same practices an experienced Playwright engineer would apply. Install it alongside any of the entry points above; the agent picks it up automatically when a task involves Playwright.

```bash
npx skills add https://github.com/currents-dev/playwright-best-practices-skill
```

### n8n

The [n8n integration](/resources/integrations/n8n) connects Currents to more than a thousand apps for workflows that run without a human in the loop. The Currents n8n node reads runs and test results via the API, so you can build automations that react to test outcomes: route new failures to Slack with context attached, open tickets for tests that cross a flakiness threshold, or feed failure data to an AI agent node for automated analysis and triage.

Combined with [HTTP webhooks](/resources/integrations/http-webhooks) as a trigger, this covers the fully autonomous end of the spectrum - no editor, no dashboard, just test results flowing into whatever process you define.

## Combining entry points

These methods compose - most teams end up using several:

* **Interactive debugging**: the IDE extension for the failure feed and one-click fixes, with the MCP server (auto-registered) letting the agent query beyond the initial prompt, and the Playwright skill shaping the fixes it writes.
* **Triage to fix**: whoever monitors the dashboard uses Fix with AI to package failures for the engineer's agent of choice - the MCP identifiers in the prompt let that agent pick up the investigation with full access to the run.
* **Auto-healing CI**: an n8n workflow or webhook triggers on run completion, an agent with the MCP server and the Playwright skill analyzes the failures and drafts a fix - a triaged ticket, a root-cause summary, or a PR that heals the failing test before anyone opens the run.


# MCP Server

Connect AI Agents to Currents

### What is MCP

MCP stands for [**Model Context Protocol**](https://modelcontextprotocol.io/introduction). It's an open pattern, introduced by Anthropic, that provides a consistent way for systems to expose tools and resources that can be used by AI models.

[Currents MCP server](https://github.com/currents-dev/currents-mcp) is a context layer for AI tools that leverage information about Playwright test results, such as failed tests, errors, and more.

### Get started

**Install our NPM package**

```bash
npm install @currents/mcp
```

**Setup the MCP Server**

{% tabs %}
{% tab title="Cursor" %}

1. Go to Cursor Settings > MCP > Enable
2. Add the following to your `mcp.json`

```json
{
  "mcpServers": {
    "currents": {
      "command": "npx",
      "args": [
        "-y",
        "@currents/mcp"
      ],
      "env": {
        "CURRENTS_API_KEY": "your-api-key"
      }
    }
  }
}
```

{% endtab %}

{% tab title="Claude " %}
Add the following to your `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "currents": {
      "command": "npx",
      "args": [
        "-y",
        "@currents/mcp"
      ],
      "env": {
        "CURRENTS_API_KEY": "your-api-key"
      }
    }
  }
}
```

{% endtab %}
{% endtabs %}

**Example Prompt**

> @folder Tests are failing in CI. Get all the details from the run `<runId>` fix the failures

Get the `runId` from the run's "Advanced" tab in the dashboard. Soon, the MCP server will be able to fetch the latest runs for an organization, removing the need for users to provide a specific run id.

### Use Cases & Capabilities

Currents MCP server exposes a variety of tools to retrieve projects, runs, test results, and performance metrics.

For a complete and up-to-date list of available tools and their usage, please refer to the [Currents MCP GitHub Repository](https://github.com/currents-dev/currents-mcp).

These tools can be used to provide context to the AI agent about all the details of a run, test executions, and specs, including historical data like error rate, debugging logs, duration, flakiness, and more.

Here are some examples of AI prompts:

* "Please fix this test"
* "Summarize my last test run"
* "What were the top flaky tests in the last 30 days?
* "What were the slowest specs in the last 7 days?"
* "Please fix all my flaky tests"

### Permissions & Security

The MCP server authenticates with the configured `CURRENTS_API_KEY`, and **every operation is limited by that API key's permissions**. The server does not grant any access beyond what the key already allows.

* When the server is configured with a **Read Only** API key, all write operations (for example deleting a run, creating a webhook, or changing an action) are rejected by the Currents API with an **HTTP 403 Forbidden** - regardless of which tools the MCP server exposes to the agent.
* A **Read & Write** key allows the agent to perform write operations. A Read Only key is recommended when the agent only needs to read test results and analytics.

A dedicated key with the appropriate permission should be created to restrict what an AI agent can do through the MCP server. See [API Keys](/dashboard/administration/api-keys) for how to create and scope API keys.

{% hint style="danger" %}
**Beware of destructive, irrecoverable operations.** When used with a **Read & Write** key, the MCP server can perform permanent deletions with no confirmation step and no way to restore the data. Currently the irrecoverable tools are:

* **`currents-delete-run`** - permanently deletes a run and all associated data (test results, test records, instances, and analytics). This cannot be undone.
* **`currents-delete-webhook`** - permanently removes a webhook configuration.
* **`currents-delete-action`** - permanently removes an action.

Other write operations - such as `currents-cancel-run`, `currents-reset-run`, webhook and action creation/updates, and Jira issue creation/linking - are impactful but reversible. Grant a Read & Write key to an agent only when these capabilities are required.
{% endhint %}


# Agent Skill: Playwright Best Practices

Empower your AI Agents to write, debug, and maintain Playwright tests with expert knowledge

### Installation

```bash
npx skills add https://github.com/currents-dev/playwright-best-practices-skill
```

After installing, the AI will automatically use the skill when your tasks involve Playwright. No additional configuration is required.

<details>

<summary>What is an Agent Skill</summary>

[Agent Skills](https://agentskills.io/home) are a new open standard for **providing expertise to agents without bloating the context window**. Created by Anthropic, skills are now available in all major AI development tools, including [Claude Code](https://code.claude.com/docs/en/skills), [Cursor](https://cursor.com/docs/context/skills), [VS Code](https://code.visualstudio.com/docs/copilot/customization/agent-skills), [Google Gemini](https://geminicli.com/docs/cli/skills/), and more.

At its simplest, a skill is a directory containing a `SKILL.md` file with metadata and expert knowledge that tells an agent how to perform a task in an opinionated way.

```
playwright-best-practices-skill/
├── SKILL.md          # Instructions + metadata
└── references/       # Topic-specific documentation
    ├── locators.md
    ├── assertions-waiting.md
    ├── debugging.md
    └── ...
```

Skills are **progressively disclosed** to preserve context. When an agent starts, only the skill's name and description are loaded. When a task matches the skill's purpose, the agent reads the full instructions and pulls in relevant references as needed.

This means the agent gets precise, expert knowledge exactly when it's relevant—without loading everything at once.

</details>

### How is it used?

The skill triggers automatically when the AI infers you need help with Playwright-related tasks. You don't have to mention "skill" or "Playwright best practices", just describe your task and the AI will use the skill when it's relevant.

#### **Example prompts:**

* "Fix this flaky login test" → The agent pulls in debugging and assertions guidance
* "Add a test for the checkout flow" → The agent uses test organization and locator best practices
* "Refactor these tests to use Page Object Model" → The agent references POM patterns and structure
* "Why is this test timing out in CI?" → The agent consults debugging and CI/CD references
* "Set up parallel execution for our test suite" → The agent uses performance and CI/CD guidance
* "Add accessibility tests for the dashboard" → The agent uses axe-core and keyboard navigation guidance
* "Test the mobile layout and touch gestures" → The agent references device emulation and touch patterns
* "Mock the payment gateway in tests" → The agent uses third-party service mocking patterns
* "Test the real-time collaboration feature" → The agent references multi-user and WebSocket testing

#### The skill covers:

* Writing new E2E, component, API, visual regression, or accessibility tests
* Testing mobile/responsive layouts, touch gestures, or device emulation
* Implementing file uploads/downloads, date/time mocking, or WebSocket testing
* Handling OAuth popups, geolocation, permissions, or multi-tab flows
* Testing iframes, canvas/WebGL, service workers, or PWA features
* Testing Electron desktop apps or browser extensions
* Internationalization (i18n), locales, RTL layouts, or date/number formats
* Testing error states, offline mode, or network failure scenarios
* Security testing (XSS, CSRF, authentication, authorization)
* Performance testing with Web Vitals or Lighthouse
* Reviewing or refactoring Playwright test code
* Fixing flaky tests or debugging failures
* Setting up CI/CD, test coverage, or global setup/teardown
* Configuring projects, dependencies, parallel runs, or sharding

### Learn more

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="image">Cover image</th><th data-hidden data-type="image">Cover image (dark)</th><th data-hidden data-card-cover-dark data-type="image">Cover image (dark)</th></tr></thead><tbody><tr><td><strong>View on GitHub</strong></td><td>See the full source code and documentation</td><td><a href="https://github.com/currents-dev/playwright-best-practices-skill">https://github.com/currents-dev/playwright-best-practices-skill</a></td><td data-object-fit="contain"><a href="/files/hy4ak1W2RCMNRdV0SHRZ">/files/hy4ak1W2RCMNRdV0SHRZ</a></td><td><a href="/files/iymLJcP8PjWTjG627SE7">/files/iymLJcP8PjWTjG627SE7</a></td><td data-object-fit="contain"><a href="/files/iymLJcP8PjWTjG627SE7">/files/iymLJcP8PjWTjG627SE7</a></td></tr></tbody></table>


# IDE Extension

Add Currents extension to VS Code, Cursor and others

Debugging CI test failures typically means jumping between your terminal, a CI dashboard, log files, and your editor. Each context switch costs time and breaks your focus. By the time you piece together the error, the stack trace, and the relevant source code, the simple fix you needed has taken 10 minutes of tab-juggling.

The Currents IDE extension eliminates that loop. It brings CI run results, failure details, flaky test analytics, and AI-powered fixes directly into your editor so you can go from "build failed" to "fix committed" without leaving your code.

* See CI failures the moment they happen, right in the sidebar
* Jump from an error message to the exact line of code in one click
* Hand full failure context (errors, stack traces, history) to an AI agent to draft a fix
* Surface your flakiest and slowest tests before they become a problem

It works with VS Code, Cursor, and any VS Code-compatible editor that supports the [Open VSX](https://open-vsx.org/) registry.

## Installation

<figure><img src="/files/ggQ69Bfgq5edIUPIzFvT" alt=""><figcaption></figcaption></figure>

* [VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=currents.currents)
* [Open VSX Registry](https://open-vsx.org/extension/currents/currents) (Cursor and other VS Code forks)

Or search "Currents" in the Extensions panel of your editor.

## Getting Started

1. Open the Currents panel in the Activity Bar.
2. Click **Set API Key** and paste your Currents [API key](/api/get-started/authentication#managing-the-api-keys).
3. Select a project -- your runs appear immediately.

<figure><img src="/files/qMrvBoXbzCVatXOHsY8u" alt=""><figcaption></figcaption></figure>

## Features

{% embed url="<https://player.mux.com/F8NYHWt01dG5KB00UGv7HOYNwzlKEIGBKqcLivLGhi3YA?metadata-video-title=Currents+IDE+Extension&video-title=Currents+IDE+Extension>" %}

### Run Feed

<figure><img src="/files/qdiyvm1GRxIumBslLXK8" alt=""><figcaption></figcaption></figure>

Browse your latest CI test runs directly in the sidebar. Runs refresh automatically every 30 seconds so you always see the current state of your builds.

* Filter by branch, author, tags, or status
* Toggle auto-refresh on or off
* Load older runs on demand

### Pull Requests

<figure><img src="/files/S7Q0MxGfJyNEj36WiuRL" alt=""><figcaption></figcaption></figure>

Surface CI failures grouped by pull request. Each PR shows a timeline of commits and builds so you can spot regressions immediately and fix them before merging.

* Filter by branch, author, tags, or status
* Toggle auto-refresh on or off

### Run Details

<figure><img src="/files/vLdj7Lcjtx00r7bhyp34" alt=""><figcaption></figcaption></figure>

Click any run to open a detail panel with every spec and test result. Failed tests show error messages and stack traces inline.

* **Fix all failures** / **Fix with agent** -- send failures to your AI agent with enriched context (see [Fix with AI](#fix-with-ai) below)
* **Fix spec failures** -- same flow scoped to a single spec file, bundling its failed and flaky tests into one prompt
* **Go to file** -- jump to the test file and line in one click
* **Trace Viewer** -- open the Playwright Trace Viewer inline (see [Inline Trace Viewer](#inline-trace-viewer) below)
* **Open in Dashboard** -- open the full Currents dashboard for deeper analysis of the run, spec, or test attempt

### Test Explorer

<figure><img src="/files/VYeGGuOaPTg3g3pQ87NY" alt=""><figcaption></figcaption></figure>

Surface the flakiest and slowest tests across your project over a configurable date range (14, 30, 60, or 90 days). Use this view to proactively address test reliability before flaky tests slow down your team.

* Sort by flakiness rate or average duration
* Jump to the test file and line in one click
* Send flaky or slow tests to AI for analysis and automated fixes
* Open in Dashboard for historical trends

### Inline Trace Viewer

<figure><img src="/files/cNlZgozBiszgtyKd4efA" alt=""><figcaption></figcaption></figure>

When a Playwright test fails, the trace file is often the fastest path to understanding what went wrong. Normally that means downloading the trace, opening it in a browser, and mentally mapping it back to your source code. The inline Trace Viewer removes those steps entirely.

Click the **Trace Viewer** button on any failed test attempt in the Run Details panel to open the full Playwright Trace Viewer in an editor tab, right next to your code. The viewer embeds `trace.playwright.dev` in a webview panel so you can step through actions, inspect DOM snapshots, view network requests, and read console logs without leaving the editor.

* Opens alongside your source code so you can cross-reference actions with test lines
* Reuses the same panel when you open another trace, keeping your layout clean
* "Open in browser" button if you need the trace in a full browser window
* Trace data streams directly from Currents -- no manual download or local file management

### Fix with AI

{% embed url="<https://player.mux.com/h7mDts1TwwARJseGM01u0001W638rJB9TKLlr01rkLRNtMI?metadata-video-title=Currents+IDE+Error+Context&video-title=Currents+IDE+Error+Context>" %}

Copying error messages from a CI log into an AI chat loses the surrounding context that makes a fix possible -- the stack trace gets truncated, the test history is missing, and the agent has to guess at what the test was doing when it failed. The "Fix with agent" actions solve this by assembling a rich, server-processed context package before the prompt ever reaches your AI assistant.

When you click **Fix with agent** on a single test, the extension uses Currents results post-processing to create an enhanced troubleshooting context that includes:

* The full error message and stack trace (ANSI codes stripped)
* The spec file path and test title
* Historical pass/fail data for the test
* Instance and attempt metadata the AI agent can use to query further details via MCP

Alongside the markdown prompt, the extension fetches a separate **error-context snapshot** powered by Currents backend that includes the page accessibility tree, console, network logs and other diagnostic data captured at the moment of failure. Giving the agent structured context that goes well beyond what a raw error message provides.

The same flow scales up:

* **Fix all failures** fetches a run-level context document covering up to 25 failing tests, plus individual error-context snapshots (up to 5) attached as separate files. The prompt instructs the agent to analyze root causes across the entire run and implement fixes.
* **Fix spec failures** bundles all failed and flaky tests within a single spec into one prompt with their respective context documents and attachments.
* **Test Explorer** builds a targeted prompt for flaky or slow tests, including the flakiness rate or average duration and the test signature, then directs the agent to use MCP tools for deeper analysis.

If the AI chat API is not available (for example in editors without a built-in chat), the prompt is copied to the clipboard with an informational notification.

### Analyze with Currents

An inline CodeLens action appears above every `test`, `it`, `describe`, and `context` definition in your code. Click it to pull recent failure data from the Currents API and send a context-rich prompt to your AI assistant that:

1. Retrieves the test signature and recent run results via MCP tools
2. Checks for failures, flakiness patterns, and performance issues
3. Builds a concrete plan to fix any problems found

A Quick Fix action (Cmd+. / Ctrl+.) is also always available on any test line, even when the CodeLens display is set to `quickfix` mode.

### MCP Server

The extension automatically registers a [Currents MCP server](https://www.npmjs.com/package/@currents/mcp) so AI agents in Cursor and VS Code can query runs, test results, and spec instances directly through tool calls. No manual configuration needed -- the extension passes your API key to the MCP server and keeps it in sync.

You can disable auto-registration if you already have `@currents/mcp` configured manually (see Settings below).

### Settings

| Setting                          | Default                       | Description                                                                            |
| -------------------------------- | ----------------------------- | -------------------------------------------------------------------------------------- |
| `currents.filterByCurrentBranch` | `false`                       | Auto-filter runs by the current git branch when a project is selected                  |
| `currents.notifyOnRunComplete`   | `false`                       | Show an OS notification when a run finishes                                            |
| `currents.analyzeTestDisplay`    | `always`                      | Show "Analyze with Currents" as CodeLens (`always`) or only via Quick Fix (`quickfix`) |
| `currents.apiBaseUrl`            | `https://api.currents.dev/v1` | API base URL (for self-hosted or enterprise setups)                                    |
| `currents.registerMcpServer`     | `true`                        | Auto-register the Currents MCP server for AI agents                                    |

### Requirements

* A [Currents.dev](https://currents.dev) account with an API key
* VS Code 1.85+ or Cursor


# Record Key

Using record key to associate your runs with your organization

### What is Record Key?

Record key is a secret you use to associate runs with your organization in Currents dashboard.

When running tests in parallel using Currents dashboard, provide your Record Key as `--key` argument.

### Can I publish my Record Key?

You'd treat your Record Key as a secret and not publish it. Having your Record Key would allow creating new runs on behalf of your organization.

### Where is my Record Key?

You can obtain your record key by navigating to "Record Keys" section of your organization menu. Accessed by clicking on your Organization's Name in the side menu.

<div data-with-frame="true"><figure><img src="/files/wFhlxXokeuwzOpB1fqAH" alt="Record Keys for Currents Dashboard"><figcaption><p>Record Keys for Currents Dashboard</p></figcaption></figure></div>

### Can I rotate my Record Key?

Yes, in "Record Keys" section of your organization menu, delete the existing key and create a new key.

<div data-with-frame="true"><img src="/files/uAzJnJTUbTir98lxb9T4" alt="Rotating a record key"></div>

{% hint style="info" %}
Please note: requests to create a run for non-existing or deleted Record Key will be rejected
{% endhint %}


# Reporting


# Reporting Strategy

How to structure and organize the reporting of CI test results to Currents

This guide aims to help readers understand how to structure and organize the test result reporting in Currents. It covers key concepts such as project, runs and groups hierarchy, test result handling, and integration strategies.

By following this guide, users can optimize their test reporting workflow and gain clearer insights into their test runs.

## Currents Reporting Terms

<figure><img src="/files/5PJ8OXbtq8CQLuCyuNLU" alt=""><figcaption><p>Reporting entities and their relationship</p></figcaption></figure>

### **Project**

The top-level entity representing reporting destination. Each organization can have multiple projects, there’s no limit on the number of projects.

You specify the project when running tests in your CI pipeline using environment variables `CURRENTS_PROJECT_ID` or via reporter configuration. Please refer to reporter documentation for available options.

{% hint style="info" %}
Each project maintains separate settings and data, with no crossover
{% endhint %}

#### **Test Results and History**

* Test results from different projects remain separate, even for identical tests.
* Test history displays results only from the same project.
* Performance metrics only include test recordings from the same project.

#### **Integrations**

Each project has its own integrations with 3rd parties (see [Integrations](/resources/integrations)). However, multiple projects can be connected to the same destination.

For example, enabling a GitHub integration allows selecting the same GitHub organization and repository for different projects. However, this may result in duplicate PR comments originating from separate projects connected to the same repository.

***

### **Run**

A recording of test results from a CI run, uniquely identified by a [CI Build ID](/guides/parallelization-guide/ci-build-id), git commit information and CI provider execution details.

By default each run represents a build (or execution of a CI pipeline), however, you can send results from different stages of a pipeline or even different pipelines to the same run using the same CI Build ID value. See [CI Build ID](/guides/parallelization-guide/ci-build-id).

***

### **Group**

A collection of spec files and the corresponding test results. For example:

* in Playwright you can create two Playwright projects that run the same tests for `chrome` and `firefox` - Currents will create a separate group, accordingly.
* in Postman each “collection” corresponds a separate group.

Each group can contain multiple spec files and test results.

***

### **Spec File**

A file containing one or more test cases, identified by its reporter filesystem path. Currents collects certain performance metrics for specs. Spec file can contain zero or more test recordings.

***

### **Test Recording**

A single test execution result, including attempts, attachments (screenshots, videos, traces, arbitrary attachments, visual diff results, annotations, error details. Each test record can have multiple attempts.

***

### **Attempt**

An attempt to run of a test case. Multiple attempts may occur depending on retry strategies.

## Reporting Scenarios

You can implement various reporting scenarios using a combination of Projects, Runs and Groups. Consider the following popular scenarios.

### Single product / repository

<figure><img src="/files/sIAvJ1drIZiejc1UHGDl" alt=""><figcaption><p>Reporting scenario: single repository with (optionally) multiple groups</p></figcaption></figure>

You have a single product (and a repository) and a testing suite that runs as part of a CI pipeline, all tests run together, optionally multiple groups (e.g. `chromium` and `firefox` ) will be automatically detected.

It is recommended to have a single project and create a unique run on every invocation of the CI pipeline.

* Create a single project
* Create a unique run for each CI invocation
* Create single or multiple groups within each run

### Multiple standalone products / repositories

<figure><img src="/files/uKAiNDpOme43Lc722IAT" alt=""><figcaption><p>Reporting scenario: multiple standalone repositories report to different Currents Projects</p></figcaption></figure>

For bigger organizations, each product has its own repository and testing suite that runs as part of a CI pipeline.

* Create a dedicated project for each product / repository
* Create a single run for each CI invocation
* Create a single or multiple groups for each run

### Mixed reporting, multiple environments

A more complicated scenario is when you have a testing suite that runs in different "environments" and you need to decide how to organize the test results. For example:

* running different Playwright projects in separate CI steps
* running the same set of tests in multiple environments, e.g. based on locale (`en-us`, `en-ca` ) or a domain (`com`, `.co.uk`)
* running a subset of tests based on tags or glob pattern, e.g. `playwright test --grep @desktop`
* running a subset of tests from different CI steps (or different pipelines) while separating the results

To implement the variety of possible scenarios you need to use the combination of Project, CI build ID, Groups and Tags, become familiar with the limitations and implications.

### Example

For example, consider testing an e-commerce web app with a slightly different set of Playwright tests for different domains (`.com`, `.co.uk` etc.).

You've defined the following [Playwright projects](#user-content-fn-1)[^1]

{% code title="playwright.config.ts" %}

```typescript
export default {
  // ...
  projects: [
    {
      name:"UK",
      testMatch: ["./e2e/shared/*.spec.ts", "./e2e/uk/*.spec"],
      use: {
        baseURL: "example.co.uk" // 🇬🇧
      }
    },
    {
      name: "US",
      testMatch: ["./e2e/shared/*.spec.ts", "./e2e/us/*.spec"],
      use: {
        baseURL: "example.com" // 🇺🇸
      }
    },
  ]
}
```

{% endcode %}

Let's consider various setups and the implications.

#### Single project, single run, multiple groups

<figure><img src="/files/HKJfaS9glPUQsyj389ZU" alt=""><figcaption><p>Mixed reporting: CI steps create separate groups in a run</p></figcaption></figure>

<details>

<summary>Example: single project, single run, multiple groups</summary>

This is the default reporting model that uses the same `projectId` (hence sends results to the same project) and the same `ci-build-id` (hence sends the results to the same run) for each command. Assuming Currents reporter is already configured.

* Running `playwright test --project UK` will create a new run with a group `UK`
* Running `playwright test --project US` will update the previosuly created run by adding the new group `US`

<table><thead><tr><th width="297">Item</th><th>Description</th></tr></thead><tbody><tr><td>Project Settings: Timeout</td><td>Each run has its own timeout, both groups will have to finish within the designated time to prevent a timeout</td></tr><tr><td>Project Settings: Default branch</td><td>Same for all runs and groups</td></tr><tr><td>Project Settings: Run title source</td><td>Same for all runs and groups (same project)</td></tr><tr><td>Project Settings: Fail fast</td><td>Each run has its own fail-fast settings</td></tr><tr><td><a data-mention href="/pages/d44bzRXv64zE5vf3hjLZ">/pages/d44bzRXv64zE5vf3hjLZ</a></td><td>Integration settings are set on a project level. Each run will activate its own notifications. Depending on integration settings you may receive a separate notification for each group completion or only for the whole run.</td></tr><tr><td><a data-mention href="/pages/0AwLLZphUa1wLpuVDCYv">/pages/0AwLLZphUa1wLpuVDCYv</a></td><td>Actions are defined on Project level and apply to each run and both groups.</td></tr><tr><td>Run Results</td><td>Each run contains results for run both group and all the included tests.</td></tr><tr><td>Run Metrics</td><td>Run metrics are based on mixed results from the two groups: aggregated run duration includes both groups, suite size includes test from both groups.</td></tr><tr><td>Test Metrics</td><td>Test metrics are based on both groups, for example if test A runs in group UK and US then both samples of the test will be included in its metrics (duration, flakiness rate, failure rate). It is possible to include only samples from particular group by using group filter.</td></tr><tr><td>Coverage Reports</td><td>Coverage reports are collected on a group level</td></tr><tr><td>Scheduled Reports</td><td>Scheduled automated reports are defined on project level and will contain results for both groups</td></tr><tr><td>Error Aggregations</td><td>Error aggregations include results from both groups</td></tr><tr><td>Test Explorer and History</td><td>Test results, including history contain results from both groups. It is possible to filter the results only from particular group</td></tr><tr><td><p>Project Taxonomy</p><p>(tags, git info, groups) - filters</p></td><td>Project taxonomy includes items from all runs and groups</td></tr></tbody></table>

</details>

#### Single project, multiple runs, single group

<figure><img src="/files/9e3m8yLc9xGBmIXq7RYm" alt=""><figcaption><p>Mixed reporting: Each CI step create a new run</p></figcaption></figure>

<details>

<summary>Example: Single project, multiple runs, single group</summary>

Instead of sending the results to the same run, you can chose to create a separate run for each playwright group. Run the following commands as part of your CI pipeline (assuming Currents reporter is already configured).

* Use the same `projectId` (send results to the same project)
* Use a different `ci-build-id` for each group - setting a different value would create a new run:
  * <mark style="color:yellow;">`CURRENTS_BUILD_ID=build-001-uk`</mark>` `` ``playwright test --project UK ` (creates a new run with a single group UK)
  * <mark style="color:yellow;">`CURRENTS_BUILD_ID=build-001-us`</mark>` `` ``playwright test --project US ` (creates a new run with a single group US

In this case, instead of a single run that contains two groups, you will create two separate runs with with 1 group each.

<table><thead><tr><th width="280">Item</th><th>Description</th></tr></thead><tbody><tr><td>Project Settings: Timeout</td><td>Each run has its own timeout</td></tr><tr><td>Project Settings: Default branch</td><td>Same for all runs</td></tr><tr><td>Project Settings: Run title source</td><td>Same for all runs</td></tr><tr><td>Project Settings: Fail fast</td><td>Each run has its own fail-fast settings</td></tr><tr><td><a data-mention href="/pages/d44bzRXv64zE5vf3hjLZ">/pages/d44bzRXv64zE5vf3hjLZ</a></td><td>Integration settings are set on a project level. Each run will activate its own notifications</td></tr><tr><td><a data-mention href="/pages/0AwLLZphUa1wLpuVDCYv">/pages/0AwLLZphUa1wLpuVDCYv</a></td><td>Actions are defined on Project level and apply to each run</td></tr><tr><td>Run Results</td><td>Each run contains results of a single group</td></tr><tr><td>Run Metrics</td><td>Aggregated run metrics are based on mixed results from the two types of runs. For example, suite size includes test from both groups. It is possible to refine the aggregation metrics to only include runs with particular tags. See <a data-mention href="/pages/3bFA5CQIB0OZOlCyqucM">/pages/3bFA5CQIB0OZOlCyqucM</a></td></tr><tr><td>Test Metrics</td><td>Test metrics are based on all runs, for example if test A runs in both environments, then both samples of the test will be included in its metrics (duration, flakiness rate, failure rate). It is possible to include only samples from particular run or group by using tags. See <a data-mention href="/pages/3bFA5CQIB0OZOlCyqucM">/pages/3bFA5CQIB0OZOlCyqucM</a>.</td></tr><tr><td>Coverage Reports</td><td>Coverage reports are collected on a group level.</td></tr><tr><td>Scheduled Reports</td><td>Scheduled automated reports are defined on project level and will contain results for both types of runs. It possible to refine the reports using <a data-mention href="/pages/3bFA5CQIB0OZOlCyqucM">/pages/3bFA5CQIB0OZOlCyqucM</a>.</td></tr><tr><td>Error Aggregations</td><td>Error aggregations include results from both types of runs.</td></tr><tr><td>Test Explorer and History</td><td>Test results, including history contain results from all runs.. It is possible to filter the results only from particular run using <a data-mention href="/pages/3bFA5CQIB0OZOlCyqucM">/pages/3bFA5CQIB0OZOlCyqucM</a>..</td></tr><tr><td><p>Project Taxonomy</p><p>(tags, git info, groups) - filters</p></td><td>Project taxonomy includes items from all runs</td></tr></tbody></table>

</details>

<details>

<summary>Multiple projects, single run, single group</summary>

As an edge case it is possible to use completely different projects. Keep in mind that each project's data is completely separated - each project has into own set of settings, analytics, results and integrations.

Use different `projectId` for each command (assuming projects already exist)

* <mark style="color:yellow;">`CURRENTS_PROJECT_ID=1cVv3a`</mark>` `` ``playwright test --project UK ` (creates a new run with a single group UK)
* <mark style="color:yellow;">`CURRENTS_PROJECT_ID=aXcR4sa`</mark>` `` ``playwright test --project US ` (creates a new run with a single group US

</details>

## Using Tags

Regardless of the reporting strategy we recommend to annotate your tests and executions with tags. Adding tags allows granular access to the data.

* Read more about using [Playwright Tags](/guides/playwright-tags) to dynamically add tags to runs, groups and tests
* Consider using `removeTitleTag`in [@currents/playwright](/resources/reporters/currents-playwright) to remove tags from test title and keep test history consistent

[^1]: don't confuse with Currents Projects


# CI Build ID

Using CI Build ID for reporting to Currents

## What is CI Build ID?

**CI Build ID** is a unique identifier used by Currents to collect test results. Think of it as a hard drive "folder". We call it a Run (see [Runs](/dashboard/runs)).

For example, when multiple CI machines run tests in parallel, their combined results are combined if they use the same CI Build ID.

* results with `--ci-build-id build001` will go to `build001` "folder"
* results with `--ci-build-id build002` will go to `build002` "folder"

<figure><img src="/files/Z6x3RNXaAdzevsQxrtt8" alt=""><figcaption><p>Creating two distinct runs by using different CI Build ID</p></figcaption></figure>

## Creating a CI Build ID

You can choose between leveraging our auto-detection algorithm, or manually generating a CI Build ID.

### Automatic Detection

Currents automatically detects CI Build ID for popular CI providers based on the presence of environment variables. Please refer to [#build-id-for-popular-ci-providers](#build-id-for-popular-ci-providers "mention") to see the environment variables used for each provider.

Otherwise, if not explicitly provided, Currents generates a random unique id.

### Explicit Value

You can also specify CI Build ID explicitly.

{% tabs %}
{% tab title="CLI" %}
With the CLI, you can use the `--ci-build-id` flag, for example:

```bash
pwc run --ci-build-id CI_BUILD_ID --key xxx --project-id yyy
```

{% endtab %}

{% tab title="Reporter Configuration" %}
Example on passing ciBuildId to Playwright Reporter configuration:

```javascript
// playwright.config.ts
import { currentsReporter } from '@currents/playwright';

//...
reporter: [
  currentsReporter({
    //... 
    ciBuildId: process.env.CURRENTS_CI_BUILD_ID
  }),
]
```

{% endtab %}

{% tab title="Environment Variable" %}
You can also set the `CURRENTS_CI_BUILD_ID` environment variable to provide an explicit CI Build ID value.
{% endtab %}
{% endtabs %}

In order to manually construct a CI Build ID that is unique for each build (but similar across all the parallel machines) it is recommended to use your CI provider's environment variables that combine pipeline/workflow/build identifier and also an attempt number.

For example, for GitHub Actions:

```
--ci-build-id "${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}"
```

Refer to your CI provider documentation for the list of available environment variables.

## Examples

### Different CI Build ID, Different Builds

Imagine a CI pipeline running tests in parallel using multiple machines. Starting two builds with a **different CI Build ID** will create 2 distinct "Runs" in Currents dashboard.

The reporting will happen for each build independently from the other. That is usually the desired situation - each build should have a unique CI Build ID.

### Same CI Build ID, Different builds

In contrast, consider a situation when 2 **different** builds use the **same** CI Build ID. That's an uncommon situation, but it's worth demonstrating for understanding the use of CI Build ID.

<figure><img src="/files/0uizDcp4aRAGKATuB10p" alt=""><figcaption><p>A single run is created when using a similar CI Build ID</p></figcaption></figure>

We created two different builds with the same CI Build ID. That will result in 6 machines reporting their results to the same run.

### Build ID for Popular CI Providers

Currents tries to automatically detect the CI provider by looking at the environment variables and picking the best combination.

<details>

<summary>Build ID for Popular CI Providers Table</summary>

<table><thead><tr><th width="193">Provider</th><th width="317">Variables</th><th>Fallback</th></tr></thead><tbody><tr><td>AppVeyor</td><td><ul><li>APPVEYOR_PULL_REQUEST_HEAD_REPO_BRANCH</li><li>APPVEYOR_BUILD_NUMBER</li></ul></td><td><ul><li>APPVEYOR_BUILD_NUMBER</li></ul></td></tr><tr><td>Azure</td><td><ul><li>BUILD_BUILDID</li></ul></td><td></td></tr><tr><td>AWS Code Build</td><td><ul><li>CODEBUILD_BUILD_ID</li><li>CODEBUILD_SOURCE_VERSION</li></ul></td><td><ul><li>CODEBUILD_BUILD_ID</li></ul></td></tr><tr><td>Bamboo</td><td><ul><li>bamboo_buildKey</li><li>bamboo_buildNumber</li></ul></td><td><ul><li>bamboo_buildKey</li></ul></td></tr><tr><td>Bitbucket</td><td><ul><li>BITBUCKET_REPO_SLUG</li><li>BITBUCKET_BUILD_NUMBER</li></ul></td><td><ul><li>BITBUCKET_BUILD_NUMBER</li></ul></td></tr><tr><td>Buildkite</td><td><ul><li>BUILDKITE_BUILD_ID</li></ul></td><td></td></tr><tr><td>CircleCI</td><td><ul><li>CIRCLE_WORKFLOW_ID</li></ul></td><td><ul><li>CIRCLE_BUILD_NUM</li></ul></td></tr><tr><td>Codeship</td><td><ul><li>CI_REPO_NAME</li><li>CI_BUILD_ID</li></ul></td><td><ul><li>CI_BUILD_ID</li></ul></td></tr><tr><td>Concourse</td><td><ul><li>BUILD_ID</li><li>BUILD_NAME</li></ul></td><td><ul><li>BUILD_ID</li></ul></td></tr><tr><td>CodeFresh</td><td><ul><li>CF_BUILD_ID</li><li>CF_CURRENT_ATTEMPT</li></ul></td><td><ul><li>CF_BUILD_ID</li></ul></td></tr><tr><td>Drone</td><td><ul><li>DRONE_PULL_REQUEST</li><li>DRONE_BUILD_NUMBER</li></ul></td><td><ul><li>DRONE_BUILD_NUMBER</li></ul></td></tr><tr><td>GitHub Actions</td><td><ul><li>GITHUB_REPOSITORY</li><li>GITHUB_RUN_ID</li><li>GITHUB_RUN_ATTEMPT</li></ul></td><td><ul><li>GITHUB_RUN_ID</li></ul></td></tr><tr><td>GitLab</td><td><ul><li>CI_PIPELINE_ID</li></ul></td><td></td></tr><tr><td>GoCD</td><td><ul><li>GO_REVISION</li><li>GO_PIPELINE_COUNTER</li></ul></td><td><ul><li>GO_REVISION</li></ul></td></tr><tr><td>Google Cloud</td><td><ul><li>REPO_NAME</li><li>BUILD_ID</li></ul></td><td><ul><li>BUILD_ID</li></ul></td></tr><tr><td>Jenkins</td><td><ul><li>BUILD_NUMBER</li></ul></td><td></td></tr><tr><td>Semaphore</td><td><ul><li>SEMAPHORE_GIT_REPO_SLUG</li><li>SEMAPHORE_PIPELINE_ID</li></ul></td><td><ul><li>SEMAPHORE_PIPELINE_ID</li></ul></td></tr><tr><td>TeamFoundation</td><td><ul><li>BUILD_BUILDID</li><li>BUILD_BUILDNUMBER</li></ul></td><td><ul><li>BUILD_BUILDID</li></ul></td></tr><tr><td>Travis</td><td><ul><li>TRAVIS_REPO_SLUG</li><li>TRAVIS_BUILD_ID</li></ul></td><td><ul><li>TRAVIS_BUILD_ID</li></ul></td></tr><tr><td>Netlify</td><td><ul><li>BUILD_ID</li></ul></td><td></td></tr></tbody></table>

</details>

## Next Steps

Now, after you're familiar with CI Build ID, explore [Reporting Strategy](/guides/parallelization-guide/reporting-strategy) to customizing your reporting to Currents.

## FAQ

<details>

<summary>Retrying builds and CI Build ID</summary>

Imagine a situation

* You start a new build with CI Build ID **build-001**
  * Build completes and reports all the results to Currents Dashboard
  * Currents marks build-001 as "finished" and all the files as completed
* You restart the build (attempt B), but keep the same CI build ID **build-001**
  * Currents considers **build-001** as already completed
  * Currents won't accept new results for **build-001**, because all the results were already reported
  * Currents will not send any new files for Cypress orchestration, because build-001 already ran all the spec files on the first attempt

To resolve this ambiguity, we need to have a different CI build ID for each rerun.

Most CI providers provide a different set of environment variables for different attempts and Currents dashboard can identify it automatically - it will create an entirely new run for retries.

You can also construct an explicit CI Build ID when retrying a build, for example, for GitHub Actions:

```
"${{ github.repository }}-${{ github.run_id }}-${{ github.run_attempt }}"
```

If you are generating CI Build ID manually, please make sure to include the retry/attempt identifier.

Please refer to your CI tool documentation to explore what environment variables are available for composing a valid CI Build ID.

</details>

<details>

<summary>Using commit SHA as CI Build ID</summary>

Using commit SHA as a CI Build ID is a valid approach and can work for many setups. However, please be aware that rerunning a build with the same commit SHA can result in a duplicate CI Build ID and prevent orchestration and reporting (see [#faq-retrying-builds-and-ci-build-id](#faq-retrying-builds-and-ci-build-id "mention"))

</details>

<details>

<summary>How to rerun CI with only failed tests?</summary>

See [Re-run Only Failed Tests](/guides/ci-optimization/re-run-only-failed-tests)

</details>


# Reporting in CI

Playwright Sharding and reporting the results to Currents

By default, Playwright runs the test files in parallel using several worker processes that run on the same machine (see [Playwright docs](https://playwright.dev/docs/test-parallel)). In addition to machine-level parallelization with workers, you can split the spec files between multiple machines using **sharding**.

### What is Playwright Sharding?

As mentioned, Playwright runs test files in parallel by default, but you can scale this behaviour by running tests on multiple machines simultaneously. This is called [sharding in Playwright](https://playwright.dev/docs/test-sharding).

<figure><img src="/files/m0ijPSC49iUzXwbpCkEF" alt=""><figcaption><p>Running Playwright tests with sharding</p></figcaption></figure>

This behaviour is activated by using the `--shard` flag. For example:

```
npx playwright test --shard 1/2
```

Currents collects test results across different machines + workers and presents them in the cloud dashboard, using CI Build ID to assign the results to a build/run.

### Reporting Sharded Playwright from localhost

Running Playwright tests with sharding enabled on localhost requires running two or more `playwright` commands with the `--shard` flag and the same [CI Build ID](/guides/parallelization-guide/ci-build-id).

Open two separate terminals and run an identical `pwc` command with `--shard=1/2` and `--shard=2/2` flag respectively and `--ci-build-id` flag with identical values in both terminals. In the example below we use a dummy CI build ID `ciid`, you can replace it with any value as long as it's the same.

{% code overflow="wrap" %}

```
npx pwc --key <currents key> --project-id <currents project id> --ci-build-id ciid --shard=1/2
```

{% endcode %}

{% code overflow="wrap" %}

```
npx pwc --key <currents key> --project-id <currents project id> --ci-build-id ciid --shard=2/2
```

{% endcode %}

You will see that two shards are executing different spec files and running in parallel as well as the amount of workers executing tests on each one of the shards.

### Splitting Test Files for Sharding

You don't need to split files manually when using Currents - Playwright does that for you automatically and distributes the spec files between Playwright shards and workers.

By default, Playwright runs test files in alphabetical order and distributes the files between shards and workers on each shard. You can use some naming convention to control the test order, for example:

* `001-user-signin-flow.spec.ts`
* `002-create-new-document.spec.ts`

and so on.

In addition, you can enable [Fully Parallel Mode](/guides/ci-optimization/fully-parallel-mode) in a single file, so Playwright will split individual tests instead of test files.

### What CI Providers Support Playwright Sharding?

Any CI provider or tool that allows creating multiple containers/jobs can be integrated with Currents for running Playwright sharding.

Here are a few example setups for popular CI providers:

* [GitHub Actions](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/github-actions)
* [GitLab](https://gitlab.com/currents.dev/gitlab-playwright-currents)
* [CircleCI](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/circleci)
* [Jenkins](/getting-started/ci-setup/jenkins)


# Step-Level Reporting

Live test results: near-realtime streaming of step-level progress from CI machines

Traditionally, Playwright reporters generate results **after** the run completion, when all the results are ready. This approach works well when executions are successful. However, when an execution fails to complete, no results are reported at all.

For example, imagine running a spec file with 10 tests on a CI machine. Nine tests can be completed successfully, but the last test can cause a crash. If we report after completion, no results will be reported at all, even for the nine finished tests.

<figure><img src="/files/nt09E1wUISYe1DOn5JCe" alt="Failure to finish test execution can result in no results reported at all"><figcaption><p>Failure to finish test execution can result in no results reported at all</p></figcaption></figure>

This problem affects not only the test results per se but also the generating and uploading of artifacts like traces, screenshots, and videos. We observed this issue occurring in different scenarios, ranging from infrastructure issues to Playwright bugs.

We wanted to provide a crash-resilient solution that would help debug failed CI tests and provide as much information as possible as soon as it is available. The Currents reporter **streams the results for each individual step**, including step-level lifecycle events (e.g., step started, step ended), as soon as they're available. So, even if an execution crashes, Currents will capture the last step that caused the failure.

In addition, Currents uploads the generated artifacts to cloud storage as soon as they are available, so you can access them even if the execution crashes.

<figure><img src="/files/scV6WaWz7u7h9vbQFliJ" alt=""><figcaption><p>Streaming step-level results in Currents reporter for Playwright tests</p></figcaption></figure>

In addition to being resilient to crashes, collecting data about individual steps allows Currents to present detailed information via its web interface. The results are stored in cloud storage, providing easy access to the entire team during Playwright tests execution. Think of it as a light version of Playwright traces that are available immediately and are not dependent on the test completion or the successful upload of a trace file.

Such detailed information unlocks more insights, like step-level analytics and performance analysis.

<figure><img src="/files/XgXtg5TPoQQgrgJm5IsQ" alt=""><figcaption><p>Streaming step-level results in Currents reporter for Playwright tests</p></figcaption></figure>

It's important to note that step-level reporting is available because the Playwright team and other contributors have designed and provided the necessary APIs to capture the lifecycle events of the test execution.


# Test Orchestration

The better alternative to Playwright Sharding

Scaling a test suite comes with many challenges. As the test suite grows, CI becomes slower.

Playwright [parallelism](https://playwright.dev/docs/test-parallel) helps reducing the bottleneck, but they aren't as efficient as they could be. Sharding splits test files based on the lexical order of file paths, leading to unbalanced workloads.

Currents Test Orchestrator fixes that by balancing the load using historical execution data, continuously creating the most optimal execution order for test runs, resulting in [up to 40% reduction the CI execution time](https://currents.dev/posts/currents-and-fundguard) with minimal changes to configuration.

<figure><img src="/files/WqNYERiI0IUWWeWW1keg" alt=""><figcaption></figcaption></figure>

Instead of pre-allocating tests to CI nodes, the orchestrator keeps a live queue of pending tests and dynamically assigns them to machines as they become available. This allows continuous communication and coordination across all nodes, improving overall throughput.

* **Learning from history** — tracks test durations and uses that data to improve distribution in future runs.
* **No renaming hacks** — you don’t need to rename spec files or manually tune splits for better balance.
* **Dynamic test distribution** — tests are split based on real-time machine availability, not pre-assigned upfront.
* **Handles CI quirks** — automatically adapts to runner spin-up delays or unresponsive machines.
* **Scales with your suite** — maintains high throughput as test count, duration, or structure evolves.
* **Your CI, your environment** — the tests are running on your existing environment, the orchestrator client communicates with Currents for task assignments and reporting the results.
* **It's just Playwright** — an orchestrator uses Playwright internally, using the same configuration and interfaces to run the tests.

### Get Started

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="image">Cover image</th></tr></thead><tbody><tr><td><strong>Technical Deep Dive</strong></td><td><sup>Fully understand how Test Orchestration works and how it compares to native Playwright Sharding.</sup></td><td><a href="/pages/E6tuQL4SrxQMz0GP0jbd">/pages/E6tuQL4SrxQMz0GP0jbd</a></td><td><a href="/files/OnSf8jDtsMhZdUSbVOgn">/files/OnSf8jDtsMhZdUSbVOgn</a></td></tr><tr><td><strong>Setup Orchestration</strong></td><td><sup>Read the guide on how to setup Test Orchestration in your test suite.</sup></td><td><a href="/pages/2L9djVKE49TZn5eCXnDW">/pages/2L9djVKE49TZn5eCXnDW</a></td><td data-object-fit="contain"><a href="/files/15aQR6oKck3VBpFb8aMi">/files/15aQR6oKck3VBpFb8aMi</a></td></tr></tbody></table>


# CI Optimization

A guide on optimizing Playwright tests in CI for better efficiency

Currents offers several ways to speed up and optimize your CI pipeline. Whether you’re just starting with basic test sharding or looking to squeeze every bit of efficiency from your infrastructure, the following strategies can help you reduce runtime, cut costs, and make test results more actionable.

<table data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><strong>Speed up CI by running Playwright Tests in Parallel</strong></td><td>Start with sharding and switch to Currents Orchestration for more efficient use of resource.<br><br><strong>Speed up CI by up to 50%</strong></td><td><a href="/pages/E6tuQL4SrxQMz0GP0jbd">/pages/E6tuQL4SrxQMz0GP0jbd</a></td></tr><tr><td><strong>Reduce CI costs with</strong><br><strong>Cloud Spot Instances</strong></td><td>Dynamically reroute tests from a to-be-terminated to a healthy instance.<br><br><strong>Save CI costs by up to 70%</strong></td><td><a href="/pages/fCC6WzwvaOnd3mxfjxh3">/pages/fCC6WzwvaOnd3mxfjxh3</a></td></tr><tr><td><strong>Enable Playwright Fully Parallel Mode</strong></td><td>Run tests from the same test file in parallel using all the available CPUs.</td><td><a href="/pages/pI7vPgZfCGBAcyNmzxB6">/pages/pI7vPgZfCGBAcyNmzxB6</a></td></tr><tr><td><strong>Explore Load Balancing Strategies</strong></td><td>Run frequently failing or flaky tests first with Currents Orchestration.</td><td><a href="/pages/qhU0oLzv4CprI9mCbzVl">/pages/qhU0oLzv4CprI9mCbzVl</a></td></tr><tr><td><strong>Re-run only failed tests</strong></td><td>Save CI computing time by re-running only tests that have failed.</td><td><a href="/pages/4m9nslQvHqgGJugXaZvK">/pages/4m9nslQvHqgGJugXaZvK</a></td></tr><tr><td><strong>Fail-fast</strong></td><td>Automatically cancel your test suite right after the first failure.</td><td><a href="/pages/2dcrXtkuwAyT5FbJNv7G">/pages/2dcrXtkuwAyT5FbJNv7G</a></td></tr></tbody></table>


# Playwright Parallelization

A guide to Playwright Parallelization for speeding up Playwright tests in CI

Running Playwright tests in parallel is most popular technique for speeding up end-to-end tests in CI. Playwright is highly concurrent — you can run multiple tests in parallel by:

* splitting tests between multiple machines (sharding)
* running multiple tests in parallel on the same machine using [playwright worker processes](https://playwright.dev/docs/test-parallel#worker-processes)

<figure><img src="/files/U4a8Vh2fZXE2hbLWMYxu" alt=""><figcaption><p>Playwright concurrency example - 5 shard with 4 workers each allows parallel execution of 20 tests</p></figcaption></figure>

In the example above, the overall "bandwidth" is 20 concurrent tests — 5 shards with 4 workers each. Consider setting the number of workers according to the CI resource class, and also consider enabling [Fully Parallel Mode](/guides/ci-optimization/fully-parallel-mode).

In addition to using multiple workers, we will explore the parallelization methods:

* Playwright Sharding
* Currents Orchestration

## Playwright Sharding

Playwright has a built-in support of [Sharding](https://playwright.dev/docs/test-sharding) — given the overall amount of machines and the current shard index, only a subset of tests runs on each CI machine.

```bash
npx playwright test --shard 1/2 # current shard = 1; overall shards = 2.
```

<figure><img src="/files/m0ijPSC49iUzXwbpCkEF" alt=""><figcaption><p>Example of running 12 test files on 5 CI machines in parallel using Playwright Sharding</p></figcaption></figure>

The example above demonstrates running 12 test files on 5 CI machines. Each shard only runs a subset of tests, which is faster than running all the tests on a single machine.

The overall CI job duration is determined by the slowest (busiest) shard. There are multiple factors that affect its duration:

* Playwright configuration
  * number of workers
  * [Fully Parallel Mode](/guides/ci-optimization/fully-parallel-mode)
* Optimal splitting of tests between the shards

{% hint style="info" %}
**Load Balancing**

Optimally splitting tests between shards can significantly affect the CI execution time. Sharding splits test files based on the lexical order of test file paths — it often leads to unbalanced workloads.

Take, for example, a testing suite consisting of 4 test files with the following durations:

* `spec01`: 10 minutes
* `spec02`: 10 minutes
* `spec03`: 3 minutes
* `spec04`: 2 minutes

  <figure><img src="/files/iD5LMHlLYZAdElzY1M89" alt=""><figcaption><p>Sharding splits the files inefficiently (20 minutes vs 13 minutes).</p></figcaption></figure>

With 2 machines, sharding splits the files inefficiently (20 minutes vs 13 minutes).

* Shard 1: `spec01`, `spec02` (20 minutes total)
* Shard 2: `spec03`, `spec04` (5 minutes total)
  {% endhint %}

## Playwright Orchestration

{% hint style="success" %}
**Orchestration for Playwright** is included with your Currents subscription.

* ✅ Integrate with any CI provider and run tests on your own infrastructure
* ✅ Speeds up your CI pipeline by analyzing your test suite and intelligently distributing tests across available CI runners
* ✅ Minimizes total runtime and maximizes resource utilization, eliminating custom scripts and reducing manual maintenance
  {% endhint %}

An alternative approach to sharding is **orchestration** — using an external service that instructs each machine what tests to run in real time.

<figure><img src="/files/KOqLocCnNjgKNc3lmehJ" alt=""><figcaption></figcaption></figure>

The orchestrator replaces static test allocation with a dynamic task queue. As your CI runners come online, they pull test tasks from this queue in real time. The orchestrator:

* Optimally balances the load across all available machines.
* Continuously updates duration stats to optimize future runs.
* Adapts to changes — like autoscaling or changes in test suite.

All test executions stays entirely within your environment, using your existing machines and configuration — nothing is offloaded, nothing leaves your CI boundary. This ensures your CI pipeline runs as fast and efficiently as possible, regardless of test suite size or environment variability.

Orchestration is especially effective for suites with 20+ files of various duration, resulting in up to [40% reduction the CI execution time](https://currents.dev/posts/currents-and-fundguard) with minimal changes to configuration.

## Sharding vs Orchestration

### Sharding

Sharding is a great start for speeding up CI runs:

* **Supported out-of-the-box** — just add `--shard i/n` to enable;
* **it is a core feature** — and has been supported by the Playwright team.

As your testing suite grows, you an discover some limitations:

* **Fixed split** — sharding is static; tests are pre-assigned with no coordination between machines during execution.
* **Shards are blocking** — each CI job (or shard) receives a fixed subset of tests. Even if some shards finish early, the overall job cannot proceed until *all* shards complete.
* **Runner spin-up delays** — each machine is assigned a fixed portion of tests upfront. If one machine takes longer to provision or initialize (common with GitHub Actions or CircleCI), the tests assigned to it just wait. Meanwhile, other machines *cannot* take over those tests.
* **Test suite changes** — static sharding relies on fixed assumptions, distributing tests by file count and alphabetical order. It doesn’t account for changes in test duration, or infrastructure variability (like runners availability). As your suite evolves, the imbalance grows — long tests may clog one shard while others finish quickly, leading to inefficient and slower builds over time.
* **No shared state** — shards don’t know about each other or the status of other runners. If a machine fails, the system doesn’t know which tests were affected. There’s no built-in retry or redistribution mechanism unless you build custom logic on top.

### Orchestration

External orchestration services offer a more scalable solution by dynamically distributing tests, adapting to infrastructure variability, and handling fault tolerance out of the box.

Instead of pre-allocating tests to CI nodes, the orchestrator keeps a live queue of pending tests and dynamically assigns them to machines as they become available. This allows continuous communication and coordination across all nodes, improving overall throughput.

<figure><img src="/files/OnSf8jDtsMhZdUSbVOgn" alt=""><figcaption><p>Orchestration service instructs each machine what tests to run in real time.</p></figcaption></figure>

* **Dynamic test distribution** — tests are split based on real-time machine availability, not pre-assigned upfront.
* **Handles CI quirks** — automatically adapts to runner spin-up delays or unresponsive machines.
* **Learning from history** — tracks test durations and uses that data to improve distribution in future runs.
* **Scales with your suite** — maintains high throughput as test count, duration, or structure evolves.
* **No renaming hacks** — you don’t need to rename spec files or manually tune splits for better balance.
* **Your CI, your environment** — the tests are running on your existing environment, the orchestrator client communicates with Currents for task assignments and reporting the results.
* **It's just Playwright** — an orchestrator uses Playwright internally, using the same configuration and interfaces to run the tests.

Orchestration does come with its own limitations:

* [Playwright Project dependencies](https://playwright.dev/docs/test-projects#dependencies) are not supported — as a workaround, run the projects in the desired order explicitly by defining separate CI steps with `--project <name>` [specification.](https://playwright.dev/docs/test-projects#run-projects)
* [Global Setup and Teardown](https://playwright.dev/docs/test-global-setup-teardown) — an orchestrated execution runs `playwright` for each iteration. Beware, that the global setup or teardown routines will run accordingly.

### Comparing Sharding and Orchestration

| Feature                       | Sharding                                  | Orchestration                             |
| ----------------------------- | ----------------------------------------- | ----------------------------------------- |
| Setup                         | Built-in                                  | Requires external service                 |
| Test Distribution             | Static — split happens upfront            | Dynamic and real time                     |
| CI Runner Coordination        | Each runner works in isolation            | Continuous coordination                   |
| Handling CI Delays            | Blocked by slow spin-up                   | Automatically adapts                      |
| Adaptation to Test Changes    | No historical data used                   | Learns from past runs                     |
| File Renaming / Manual Tweaks | Required for balance                      | Balancing is automatic                    |
| Project Dependencies          | Fully supported                           | Not Supported                             |
| Global Setup/Teardown         | Runs once per shard                       | May run multiple times                    |
| Overall Efficiency            | Degrades as test suite becomes unbalanced | Maintains optimal performance across runs |

### <a href="/pages/2L9djVKE49TZn5eCXnDW" class="button primary">Next: Orchestration Setup Instructions</a>

## More CI Optimization Topics

Continue exploring more topics related to improving Playwright efficiency on CI

* **Reduce CI costs by utilizing Cloud Spot Instances** — orchestration allows dynamically reroute tests from a to-be-terminated to a healthy instance. See [Cloud Spot Instances](/guides/ci-optimization/ci-tests-on-spot-instances).
* **Enable Playwright Fully Parallel Mode** — run tests from the same test file in parallel using all the available CPUs. See [Fully Parallel Mode](/guides/ci-optimization/fully-parallel-mode).
* **Explore Load Balancing Strategies** — run frequently failing or flaky tests first with Currents Orchestration. See [Failing Fast](/guides/ci-optimization/fail-fast-strategy).


# Orchestration Setup

Setup instructions for Playwright Orchestration

{% hint style="warning" %}
Migrating from `v1`? See [Migration Guide](/guides/ci-optimization/playwright-orchestration/playwright-orchestration-migration-guide).
{% endhint %}

Orchestration helps decrease the duration of Playwright tests in CI pipelines. Read our detailed guide on [Playwright Parallelization](/guides/ci-optimization/playwright-parallelization) that compares native sharding with orchestration.

## How does it work

At a high level:

* creates a list of tests for orchestration using `pwc-p discover`
* establishes an orchestration session with Currents servers
* assigns work to available CI machines using historical execution and timing data
* records results to Currents for troubleshooting and analysis

`@currents/playwright` includes a CLI command `pwc-p` that implements Playwright Orchestration.

1. [`pwc-p discover`](/resources/reporters/currents-playwright/pwc-p/pwc-p-discover) — runs Playwright in discovery mode and writes the list of tests to be orchestrated to a file.
2. [`pwc-p run`](/resources/reporters/currents-playwright/pwc-p/pwc-p-run) — initiates the orchestrated execution based on the previous step.

## Setup

Install `@currents/playwright`

```bash
npm i @currents/playwright@latest
```

* Run `pwc-p discover` to create a discovery file with tests selected for orchestration, you can apply the same filters and CLI arguments as for `playwright` command.
* Run `pwc-p run` with `--pwc-discovery-file` to execute the orchestration. Run `pwc-p run --help` to see the available flags or refer to [@currents/playwright](/resources/reporters/currents-playwright).

{% code overflow="wrap" lineNumbers="true" %}

```bash
npx pwc-p discover --pwc-discovery-file <discovery-path> [...filters]
npx pwc-p run --pwc-discovery-file <discovery-path> --key <currents-record-key> --project-id <currents-project-id> --ci-build-id <ci-build-id>
```

{% endcode %}

A successfully created orchestration prints an output similar to this.

{% code overflow="wrap" %}

```bash
$ npx pwc-p run --key *secret* --project-id WeZwSj --ci-build-id example-001
🚀 Starting orchestration session...
📦 Currents reporter: 2.0.0
  - ci build id: example-001
  - project id: WeZwSj
  - orchestration id: 11b601f500893bacfa169acb126b6239
  - machine id: bA0qyMOxUiCz9XT0
🎭 Playwright: 1.60.0 5 tests in 1 project [chromium]

🌐 Executing orchestrated task: [chromium] test2.spec.ts, test.spec.ts
ℹ️  Batch size: 3
🌐 Run URL: https://app.currents.dev/run/4aefcb5cd3bb5c89
#...
```

{% endcode %}

{% hint style="info" %}
Currents automatically balances tests between all available CI machines, which makes `--shard` redundant — it should be removed.

Read more about [CI Build ID](/guides/parallelization-guide/ci-build-id) and [Reporting Strategy](/guides/parallelization-guide/reporting-strategy).
{% endhint %}

## When to use `discover`

`pwc-p discover` is required when you want to explicitly select tests for orchestration — for example:

* Filtering tests by tag: `--grep / -g @smoke`
* Filtering tests by last run outcome: `--last-failed` (see [#re-running-only-failed-tests](#re-running-only-failed-tests "mention"))
* Filtering tests by Playwright project: `--project chromium`
* Explicit spec file location: `playwright test <spec-file-path>`

Apply the desired arguments and parameters as if you are running `playwright` command, for example:

{% code overflow="wrap" lineNumbers="true" %}

```sh
# Create discovery file with filters applied
npx pwc-p discover --pwc-discovery-file ./test-list --grep @smoke --project chromium

# Use the discovery file as an input for orchestration
npx pwc-p run --pwc-discovery-file ./test-list --key currents-record-key --project-id currents-project-id --ci-build-id ci-build-id
```

{% endcode %}

Omitting discovery stage selects **all** tests for orchestration.

| Scenario                           | Commands                                        |
| ---------------------------------- | ----------------------------------------------- |
| Run the full suite (no filters)    | `pwc-p run ...`                                 |
| Filter tests with Playwright flags | first `pwc-p discover ...` then `pwc-p run ...` |

## Discovery output

Creates a discovery file at a destination, then use the file as an input for `pwc-p run` command

```bash
npx pwc-p discover --pwc-discovery-file tests.txt --grep @smoke --project frontend
npx pwc-p run --pwc-discovery-file tests.txt ...
```

Additional methods for providing discovery file:

* `CURRENTS_DISCOVERY_FILE` environment variable
* `orchestration.discoveryFile` in `currents.config.ts`

{% hint style="info" %}
`CURRENTS_DISCOVERY_FILE` or `orchestration.discoveryFile` are the recommended options for CI environments, as this setup applies to both `discover` and `run` commands.
{% endhint %}

## Examples

Filter with grep:

```bash
npx pwc-p discover --pwc-discovery-file tests.txt --grep @smoke
npx pwc-p run --pwc-discovery-file tests.txt --key <record-key> --project-id <project-id> --ci-build-id <ci-build-id>
```

Filter with last-failed:

```bash
npx pwc-p discover --pwc-discovery-file tests.txt --last-failed
npx pwc-p run --pwc-discovery-file tests.txt --key <record-key> --project-id <project-id> --ci-build-id <ci-build-id>
```

Add tags on the recorded run (no discovery step):

```bash
npx pwc-p run --key <record-key> --project-id <project-id> --ci-build-id <ci-build-id> --tag tagA --tag tagB
```

Run `pwc-p discover --help` or `pwc-p run --help` to see the list of supported flags.

## Orchestration in CI

Provider-specific orchestration examples are being updated for `discover` and `run`. Use these pages as starting points:

* [GitHub Actions](/getting-started/ci-setup/github-actions/playwright-github-actions)
* [GitHub Actions: re-run only failed tests](/getting-started/ci-setup/github-actions/re-run-failed-only-tests/re-run-failed-only-tests-orchestrated-v2)
* [GitHub Actions + NX](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/nx/.github/workflows/or8n.yml)
* [GitLab CI/CD](https://gitlab.com/currents.dev/gitlab-playwright-currents/-/blob/main/.gitlab/ci/with-reruns-pwcp.yml?ref_type=heads)
* [NX](/getting-started/ci-setup/nx)
* [Jenkins](/getting-started/ci-setup/jenkins)
* [CircleCI](/getting-started/ci-setup/playwright-circleci)
* [Azure DevOps](/getting-started/ci-setup/playwright-azure-devops)
* [AWS CodeBuild](/getting-started/ci-setup/playwright-aws-code-build)
* [Harness](/getting-started/ci-setup/playwright-harness)

## Orchestration and Reporters

### Additional Reporters

`pwc-p run` automatically injects Currents reporter [@currents/playwright](/resources/reporters/currents-playwright) into Playwright, replacing all other reporters configured in `playwright.config.ts`. To add additional reporters use one of the two options.

#### **Add reporters as a CLI parameter.**

{% code overflow="wrap" %}

```bash
pwc-p run --key <record-key> --project-id <id> --ci-build-id <build-id> --reporter="./myreporter/my-awesome-reporter.ts"
```

{% endcode %}

#### **Manual Configuration**

Create `currents.config.ts` with the following contents:

```typescript
import { CurrentsConfig } from "@currents/playwright";

const config: CurrentsConfig = {
  recordKey: process.env.CURRENTS_RECORD_KEY,
  projectId: process.env.CURRENTS_PROJECT_ID,
  ciBuildId: "value", // ⚠️ Set the value as described in CI build ID guide
  orchestration: {
    skipReporterInjection: true, // prevent automatic reporter injection
  },
};

export default config;
```

* Update `playwright.config.ts`

```typescript
import { currentsReporter } from "@currents/playwright";
import { PlaywrightTestConfig } from "@playwright/test";

const config: PlaywrightTestConfig = {
  reporter: [currentsReporter()],

  // ... rest of playwright configuration
};
```

* **Optional:** Update the `pwc-p run` CLI command

`pwc-p run` reads all the configuration from `currents.config.ts` — no need to use CLI params.

{% code overflow="wrap" %}

```bash
pwc-p run -- [...playwright-cli-params]
```

{% endcode %}

### Merging Fragmented Reports

Orchestration dynamically pulls test files from a central server, and each pull starts a fresh Playwright process. This can impact reporters that write output files—since a new process runs for each pull, you may need to handle file overwrites and merge results correctly.

The solution is to use the `blob` reporter to gather all the fragmented results and merge them.

```bash
# The PWTEST_BLOB_DO_NOT_REMOVE env variable is needed
# to preserve the `blob-report` directory between orchestrated spec runs
PWTEST_BLOB_DO_NOT_REMOVE=1 pwc-p run --key <record-key> --project-id <id> --ci-build-id <build-id> --reporter blob
```

You can generate other reports by passing the blob results to the `merge-reports` command.

```bash
npx playwright merge-reports --reporter=html ./blob-report
```

Check an [example of Github Actions setup here.](https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/github-actions/.github/workflows/test-or8n.yml)

## Orchestration and Multiple Workers

Orchestration distributes work at the **spec-file level** and uses two independent settings:

* **`--workers`** — Playwright's execution concurrency on a machine (passed straight to `playwright test`). Controls how many tests run in parallel locally.
* **`--pwc-batch-size`** — the number of parallel **lanes** the orchestrator fills for the machine currently requesting work. Defaults to `auto`, derived from your Playwright workers (project `workers` → global `workers` → `1`).

### How a batch is built

When a machine requests work, the orchestrator fills `batch-size` lanes by weight (a spec's weight is its expected duration from history):

1. The heaviest remaining spec goes into the first lane.
2. The other lanes are filled with lighter specs whose weight fits under that heaviest spec.

Because of step 2, **batch size is not a hard limit on how many spec files a machine claims** — with a batch size of 2 or more, a machine can claim *more* files than the batch size in a single request. The exception is `--pwc-batch-size 1`, which claims exactly one spec file per request (no packing).

{% hint style="warning" %}
`--pwc-batch-size` is a count of parallel lanes, not a count of spec files. With a batch size of 2 or more, a single machine may lock several spec files in one request (the heaviest spec plus lighter ones packed under it).
{% endhint %}

### Batch size vs. workers

For most suites these are effectively one dial, which is why `auto` ties them together:

* **File-level suites (not fully parallel):** Playwright runs one file per worker, so usable concurrency is bounded by the number of files in the batch. Keep `batch-size == workers` (the default). Setting them apart either queues files (`batch-size > workers`) or idles workers (`batch-size < workers`).
* **Fully parallel suites:** Playwright parallelizes individual tests, so one file can keep many workers busy. Here a small batch size with a larger worker count — e.g. `--pwc-batch-size 1 --workers 4` — gives fine-grained, even distribution across machines while still using all workers. See [Fully Parallel Mode](/guides/ci-optimization/fully-parallel-mode).

### Distribution across machines

The orchestrator is **machine-unaware**: it doesn't know how many machines will join the run, or when. It fills the machine asking for work right now and doesn't reserve specs for machines that connect later. As a result:

* A fast or early machine can claim a large share of the queue.
* A machine that joins after the queue is already claimed receives no specs and ends its session.

For the most even distribution across a large matrix, use `--pwc-batch-size 1`. Trade-off: in file-level suites each machine then runs its files one at a time, so you gain even distribution but reduce per-machine parallelism.

As of May 2025, the Playwright Test Runner [does not respect the execution order of test files](https://github.com/microsoft/playwright/issues/35743). This means that even if Currents suggests an optimal execution order, Playwright may run files in a different sequence when multiple workers are used. It only affects cases when multiple workers are involved and has a minor impact.

### Batch size configuration

The batch size can be configured via [env variable or cli option](https://docs.currents.dev/resources/reporters/currents-playwright/pwc-p-orchestration#pwc-batch-size-less-than-auto-or-number-greater-than).

Starting at `@currents/playwright` version `1.14.0` and `@playwright/test` version starting at `1.52.0` the option can be set per project.

This means that the batch size can be handled globally, that also supports automatic detection of global workers, but also the project level workers and batch size is taken into account for defining the batch size.

Batch size for each project is determined by evaluating options in the following order of priority:

{% stepper %}
{% step %}
**Global batch size**

A global batch size defined via [environment variable or CLI option](https://docs.currents.dev/resources/reporters/currents-playwright/pwc-p-orchestration#pwc-batch-size-less-than-auto-or-number-greater-than) will override any batch size or worker settings defined at the project level.

<sub>Starting with version</sub> <sub>`1.13.0`</sub><sub>, the reporter can automatically detect and use the global worker count as the batch size, if global workers are defined.</sub>
{% endstep %}

{% step %}
**Project batch size**

`currentsBatchSize` defined at [project level](#project-level-batch-size)

<sub>This configuration is available in</sub><sub>`@currents/playwright`</sub> <sub>version starting at</sub> <sub>`1.14.0`</sub> <sub>and</sub> <sub>`@playwright/test`</sub> <sub>version starting at</sub> <sub>`1.52.0`</sub>
{% endstep %}

{% step %}
**Project workers**

`workers` defined at [project level](#project-level-workers)

<sub>This configuration is available in</sub><sub>`@currents/playwright`</sub> <sub>version starting at</sub> <sub>`1.14.0`</sub> <sub>and</sub> <sub>`@playwright/test`</sub> <sub>version starting at</sub> <sub>`1.52.0`</sub>
{% endstep %}

{% step %}
**Global workers**

[Globally defined `workers`](https://playwright.dev/docs/api/class-testconfig#test-config-workers)
{% endstep %}

{% step %}
**Default**

If none of the above is defined, batch size is `1`
{% endstep %}
{% endstepper %}

### Project level workers

This feature allows you to set the number of workers at project level, enabling each project to specify its own batch size based on the workers.

This is how the workers can be defined:

```typescript
...
projects: [
    {
      name: "chromium",
      use: { ...devices["Desktop Chrome"] },
      workers: 2
    },
    {
      name: "firefox",
      use: { ...devices["Desktop Firefox"] },
      workers: 3
    },
  ],
...
```

Currents will use the batch size **`auto`** option by default. This means the reporter will read each project workers setting and use it as batch size.

If no workers are defined for a project, Currents will use the global workers value as batch size.

### Project level batch size

The Playwright project configuration can be extended with `currentsBatchSize` which explicitly sets the batch size per project. Import `CurrentsFixtures` for typescript suport.<br>

```typescript
import type { CurrentsFixtures } from "@currents/playwright";
import { defineConfig, devices } from "@playwright/test";

export default defineConfig<CurrentsFixtures>({
  ...
  projects: [
    {
      name: "chromium",
      use: {
        ...devices["Desktop Chrome"],
        currentsBatchSize: 3
      },
      workers: 2,
    },
    {
      name: "firefox",
      use: {
        ...devices["Desktop Firefox"],
        currentsBatchSize: "auto"
      },
    },
  ],
  ...
});

```

In this example, the `chromium` project has 2 workers defined. However, since the `currentsBatchSize` property is set, Currents will use the specified `currentsBatchSize` instead of the workers value.

For the `firefox` project, the `currentsBatchSize` is set to `auto`, so Currents will use the project's workers value. Since it is not defined, Currents will fall back to the global workers value.

## Re-running Only Failed Tests

Orchestrated reruns use `pwc-p discover` with `--last-failed` (or flags from the [playwright-last-failed](https://github.com/currents-dev/playwright-last-failed) action) to build the filtered test list, then `pwc-p run` with `--pwc-discovery-file`.

```bash
npx pwc-p discover --pwc-discovery-file tests.txt --last-failed
npx pwc-p run --key <record-key> --project-id <project-id> --ci-build-id <ci-build-id> --pwc-discovery-file tests.txt
```

See [Orchestrated runs](/guides/ci-optimization/re-run-only-failed-tests/re-run-only-failed-tests-orchestrated-v2) for the full implementation details.

## Limitations and Nuances

* Orchestration works on a **file level** — it balances test files (rather than individual tests).
* For [Fully Parallel Mode](/guides/ci-optimization/fully-parallel-mode), set Batch Size to 1 (and raise Playwright workers) so machines are balanced correctly — a single file's tests still run in parallel across workers.
* [Playwright Project dependencies](https://playwright.dev/docs/test-projects#dependencies) is not supported — if projects depend on one another, orchestration will not consider the dependencies. As a workaround, run the dependencies in the desired order explicitly by defining separate CI steps with `--project <name>` [specification.](https://playwright.dev/docs/test-projects#run-projects)
* [Global Setup and Teardown](https://playwright.dev/docs/test-global-setup-teardown). An orchestrated execution runs `playwright` multiple times. Beware that global setup or teardown routines run for each invocation of `playwright`.

## Next Steps

* Use [Cloud Spot Instances](/guides/ci-optimization/ci-tests-on-spot-instances) to reduce your CI bills by 90%


# Migration Guide

Migration Guide for Currents Orchestration v1 -> v2

{% hint style="info" %}
This guide is for migrating Currents Orchestration from `v1` to `v2` . If you are not using Currents Orchestration see [Compatibility Guide](/resources/reporters/currents-playwright/compatibility)&#x20;
{% endhint %}

## What Has Changed?

`v2` of Currents Orchestration requires running two separate commands:

* `pwc-p discover` — runs Playwright in discovery mode and writes the list of tests to be orchestrated to a file.
* `pwc-p run` — initiates the orchestrated execution based on the previous step, using the list of tests as an input.

That's different from `v1` that was using a single command for discovery and execution.&#x20;

The migration involves:

* Adding `pwc-p discover`  step
* Using `pwc-p run` command

## Migration Steps

{% stepper %}
{% step %}

### Update `@currents/playwright` to 2.0.0+

{% code overflow="wrap" lineNumbers="true" %}

```
npm i @currents/playwright@^2
```

{% endcode %}
{% endstep %}

{% step %}

### Use `pwc-p discover` command

* Run  `pwc-p discover` to create a discovery file with tests selected for orchestration, you can apply the same filters and CLI arguments as for `playwright` command.
* Run `pwc-p run` with `--pwc-discovery-file` to execute the orchestration. Run `pwc-p run --help`  to see the available flags or refer to [@currents/playwright](/resources/reporters/currents-playwright).

{% code overflow="wrap" lineNumbers="true" %}

```bash
npx pwc-p discover --pwc-discovery-file discovery-path [...filters]
npx pwc-p run --pwc-discovery-file discovery-path --key currents-record-key --project-id currents-project-id --ci-build-id ci-build-id
```

{% endcode %}
{% endstep %}

{% step %}

### Replace `pwc-p` with `pwc-p run`

Update your CI configuration to use `pwc-p run` instead of `pwc-p`

{% code overflow="wrap" %}

```bash
# Before
npx pwc-p --key record-key --project-id project-id --ci-build-id ci-build-id

# After
npx pwc-p run --pwc-discovery-file discovery-path --key record-key --project-id project-id --ci-build-id ci-build-id
```

{% endcode %}
{% endstep %}
{% endstepper %}

## When to use `discover`

`pwc-p discover` is required when you want to explicitly select tests for orchestration — for example:

* Filtering tests by tag:  `--grep / -g @smoke`
* Filtering tests by last run outcome:  `--last-failed`  (see [#re-running-only-failed-tests](#re-running-only-failed-tests "mention"))
* Filtering tests by Playwright project: `--project chromium`
* Explicit spec file location: `playwright test <spec-file-path>`

Apply the desired arguments and parameters as if you are running `playwright` command, for example:

{% code overflow="wrap" lineNumbers="true" %}

```sh
# Create discovery file with filters applied
npx pwc-p discover --pwc-discovery-file ./test-list --grep @smoke --project chromium

# Use the discovery file as an input for orchestration
npx pwc-p run --pwc-discovery-file ./test-list --key currents-record-key --project-id currents-project-id --ci-build-id ci-build-id
```

{% endcode %}

Omitting discovery stage selects **all** tests for orchestration.

| Scenario                           | Commands                                        |
| ---------------------------------- | ----------------------------------------------- |
| Run the full suite (no filters)    | `pwc-p run ...`                                 |
| Filter tests with Playwright flags | first `pwc-p discover ...` then `pwc-p run ...` |


# Orchestration (v1)

Playwright Orchestration Setup Guide for Currents v1

{% hint style="warning" %}
This page documents orchestration flow for deprecated `v1` version of Currents. See [Migration Guide](/guides/ci-optimization/playwright-orchestration/playwright-orchestration-migration-guide).
{% endhint %}

Orchestration helps decrease the duration of Playwright tests in CI pipelines. Read our detailed guide on [Playwright Parallelization](/guides/ci-optimization/playwright-parallelization) that compares native sharding with orchestration.

## How does it work

`@currents/playwright` contains a command-line executable `pwc-p` — a lightweight wrapper that implements Orchestration and runs Playwright behind the scenes.

* it scans the testing suite
* it establishes an orchestration session with Currents servers
* **it** runs Playwright, executing spec files in the optimal order
* the results are recorded to Currents for troubleshooting and analysis

## Setup

Install `@currents/playwright`:

```bash
npm i @currents/playwright
```

Replace `playwright` with `pwc-p`:

```bash
npx pwc-p --key <record-key> --project-id <project-id> --ci-build-id <ci-build-id>
```

`pwc-p` accepts additional Playwright arguments and flags (see [@currents/playwright](/resources/reporters/currents-playwright)), for example:

{% code overflow="wrap" %}

```bash
# Add additional playwright arguments and flags:
pwc-p --key <record-key> --project-id <id> --ci-build-id <build-id> -- --workers 2 --timeout 10000
```

{% endcode %}

{% hint style="success" %}
Read more about [CI Build ID](/guides/parallelization-guide/ci-build-id) and [Reporting Strategy](/guides/parallelization-guide/reporting-strategy).
{% endhint %}

{% hint style="info" %}
There's no need to define shards. Remove the `--shard` flag — Currents uses all available machines automatically.
{% endhint %}

A successfully created orchestration prints an output similar to this:

{% code overflow="wrap" %}

```bash
$ npx pwc-p --key **redacted** --project-id **redacted** --ci-build-id `date +%s` -c ./or8n/playwright.config.ts

🚀 Starting orchestration session...
📦 Currents reporter: 1.1.2 recording CI build 1712134904 for project JJzd65, orchestration id 260264cfa16950ab4dc98d5c54333136
🎭 Playwright: 1.42.1 5 tests in 1 project [chromium]

🌐 Executing orchestrated task: [chromium] spec-or8n-e.spec.ts
🌐 Run URL: https://app.currents.dev/run/9b93659915fe653f
# ...start executing the tests in an optimal order.
```

{% endcode %}


# Fully Parallel Mode

A guide on Playwright Fully Parallel mode

Playwright has multiple levels of concurrency:

* split all the tests between different machines using [sharding](https://playwright.dev/docs/test-sharding#sharding-tests-between-multiple-machines);
* each shard can have [multiple workers](https://playwright.dev/docs/api/class-testconfig#test-config-workers) (according to # of CPUs or explicit configuration).

<figure><img src="/files/JWwoLlgBxPRd2vXUhBzc" alt=""><figcaption><p>Playwright shards, workers and parallel execution</p></figcaption></figure>

Playwright Workers run the tests in parallel, allowing for a speedup in execution and full utilization of machine's resources.

By default, Playwright runs the tests of the **same spec file in the same worker** — one after another. Even if you have a powerful machine capable of supporting multiple workers, it can be under-utilized.

For example, if your machine has 4 workers and sharding assigns one spec file, only one worker will be utilized at a time and the tests will be executed one after another, not in parallel.

<figure><img src="/files/Apb5sC1rtOWJhv3R67JQ" alt="Underutilizing Workers"><figcaption><p>Underutilizing Workers</p></figcaption></figure>

Enabling `fullyParallel: true` ([see configuration details](https://playwright.dev/docs/api/class-testconfig#test-config-workers)) allows running tests from the **same spec file in parallel** on different workers. This way, all available workers can be utilized, and the tests will be executed faster.

<figure><img src="/files/F7lY5VAcld1aTTFFD153" alt="Enabling fullyParallel mode uses all available Playwright workers"><figcaption><p>Enabling fullyParallel mode uses all available Playwright workers</p></figcaption></figure>

Note that the tests are required to be isolated and not shared in any state. Playwright will run the tests on different workers or even on different machines (a.k.a shards).

To enable running individual tests from the [same spec file on different workers](https://playwright.dev/docs/api/class-testproject#test-project-fully-parallel), set `fullyParallel: true` in your configuration file.

Version 1.0.0+ of the reporter is compatible with fully parallel mode and will collect the results of concurrent parallel executions from distributed shards and workers. Moreover, the reporter will display the results of each step, which is crucial for debugging failed CI executions.


# Re-run Only Failed Tests

A guide on rerunning only failed Playwright tests in CI

Starting from version [1.44](https://playwright.dev/docs/release-notes?ref=playwrightsolutions.com#version-144) Playwright supports [running only the failed test from the last run](https://playwrightsolutions.com/how-to-run-failures-only-from-the-last-playwright-run/) using `--last-failed` CLI flag. For example:

```
playwright test --last-failed
```

<figure><img src="/files/Rmn7GrmtlB0LBbnFogT1" alt=""><figcaption><p>Rerunning Failed Only Playwright Tests</p></figcaption></figure>

While this feature works well for local environments, using it in CI with Playwright shards or Currents Orchestration is not straightforward.

We have created a set of tools that simplify rerunning only the failed Playwright tests in CI, including sharded parallel CI runs and runs created by Currents Orchestration.

## When to use it

`--last-failed` is not a replacement for [`retries`](https://playwright.dev/docs/test-retries). Retries handle flakiness automatically, within the same run, without human involvement.

Re-running failed tests is for the cases where a human fixed something between the two runs and the test code did not change — a missing environment variable, a disabled feature flag, a dependency that was down, a service that had not finished deploying. Instead of re-running the whole suite to validate the fix, you re-run only the tests that failed.

## How `--last-failed` works

Playwright records the outcome of each run in a `.last-run.json` file. On the next run, `--last-failed` reads that file and executes only the tests listed as failed.

By default the file is written to `<outputDir>/.last-run.json` — inside the first project's `outputDir` (commonly `test-results/`). That default is the source of most CI problems: `outputDir` is wiped before each run, so the file has to be preserved outside of it between runs.

Newer Playwright versions accept `--last-failed-file <path>` (or the `PLAYWRIGHT_LAST_RUN_OUTPUT_FILE` environment variable) to write the file to an explicit location, instead of depending on the internal `outputDir` layout:

```bash
npx playwright test --last-failed --last-failed-file .last-run.json
```

See the [Playwright CLI reference](https://playwright.dev/docs/test-cli) for the exact flag definition and your version's support.

{% hint style="warning" %}
Store the last-run file outside `test-results/` or any configured `outputDir` — those directories are deleted before tests start.
{% endhint %}

## Why CI makes it harder

Wiring `--last-failed` into CI requires solving a few problems that don't exist locally:

* The file must survive between runs. CI machines are ephemeral, so `.last-run.json` has to be cached or fetched from an external source.
* Each shard has its own file. With native `--shard` parallelism, the file records only the tests from that shard, so caching must be per-shard.
* Cache keys are immutable. On GitHub Actions an existing key cannot be overwritten, so the retry attempt (`run_attempt`) has to be part of the key it saves under — and the restore step then has to fall back to a prefix without the attempt, or the retry will never find the previous attempt's file.
* The file must be saved even when the job fails, which is exactly when it matters. On GitHub Actions this means `actions/cache/save` with `if: always()`, since the combined `actions/cache` action skips the save step on failure.
* The right re-run button matters. The correct choice differs between sharded and orchestrated runs — see the guides below.

The [`currents-dev/playwright-last-failed`](https://github.com/currents-dev/playwright-last-failed) action handles the caching, the per-shard keys, and the conditional flags for you, and outputs the flags to pass to Playwright.

## Follow the guide that matches how tests are run in CI

* [Sharded runs](/guides/ci-optimization/re-run-only-failed-tests/re-run-only-failed-tests-sharded) — fixed shard count and native Playwright `--shard` parallelism. Re-run with **Re-run failed jobs**, so passed shards are not restarted.
* [Orchestrated runs](/guides/ci-optimization/re-run-only-failed-tests/re-run-only-failed-tests-orchestrated-v2) — Currents assigns the failed tests to all available machines. Re-run with **Rerun All Jobs**.


# Sharded runs

Re-run only failed tests when using native Playwright sharding

Native Playwright sharding runs tests in parallel across a fixed set of jobs. On retry, each job should run only the tests that failed in the previous execution.

{% hint style="info" %}
Sharded reruns use **Re-run failed jobs** in the CI provider — not **Re-run all jobs**. See [#re-run-the-failed-jobs-only](#re-run-the-failed-jobs-only "mention").
{% endhint %}

## How sharding changes `--last-failed`

Each shard is an independent Playwright process with its own `.last-run.json`. A shard's file lists only the tests that ran in that shard, so:

* Every shard needs its own cached copy of `.last-run.json` — keyed by shard index.
* Shard 2 re-runs shard 2's failures. Shards never see each other's results, so there is nothing to merge.
* Shard assignment must stay stable between attempts. Playwright distributes tests deterministically, so keep the shard total and the test files unchanged between the original run and the retry.

## What the setup has to do

Four things have to be true for a sharded rerun to work:

1. `.last-run.json` survives between attempts. CI machines are ephemeral — the file must be cached (or fetched from Currents) and restored into the retried job.
2. The save key is unique per shard and per attempt. It needs the shard index, because each shard has a different file, and the attempt number, because on GitHub Actions an existing cache key cannot be overwritten — each retry has to write a new entry.
3. The restore key is a prefix that omits the attempt. This is the step that is easy to miss: a key containing the attempt number never hits on a retry, because that attempt has not written a cache yet. Restore has to fall back to a stable `run_id` + shard prefix so it picks up the most recent previous attempt.
4. `--last-failed` is passed conditionally. The first attempt has no `.last-run.json` — passing `--last-failed` when the file is missing is not what you want on a clean run. Add the flag only when a previous attempt's file was actually restored.

On GitHub Actions, points 2 and 3 come out as a save key with `run_attempt` and a restore prefix without it:

```yaml
key: last-run-${{ github.run_id }}-${{ matrix.shard }}-${{ github.run_attempt }}
restore-keys: |
  last-run-${{ github.run_id }}-${{ matrix.shard }}-
```

Scoping the key to `run_id` also keeps a previous workflow's results from leaking into a fresh run.

The file also has to be saved even when the job fails, which is the case that matters here. Use `actions/cache/save` with `if: always()` — the combined `actions/cache` action skips its save step when the job fails.

## Re-run the failed jobs only

Use the CI provider's **Re-run failed jobs** (GitHub Actions) or **Retry failed jobs** (GitLab CI):

* Shards that passed are not restarted.
* Shards that failed re-run with only their own failed tests.

**Re-run all jobs** would restart every shard, including the ones that passed — which defeats the purpose. This is the opposite of [Orchestrated runs](/guides/ci-optimization/re-run-only-failed-tests/re-run-only-failed-tests-orchestrated-v2), where **Rerun All Jobs** is the correct choice because Currents redistributes the failed tests across all available machines.

## Choosing an approach

<table><thead><tr><th width="220">Approach</th><th>When to use it</th></tr></thead><tbody><tr><td><a href="https://github.com/currents-dev/playwright-last-failed">playwright-last-failed</a> action</td><td>GitHub Actions. Handles the cache, the per-shard/per-attempt key, and the conditional flags, and outputs the flags to pass to Playwright.</td></tr><tr><td><a href="/pages/y1We6AaBZc6JbpNUbD9U">currents cache</a> with <code>--preset last-run</code></td><td>GitLab CI and other providers. Stores <code>.last-run.json</code> in Currents-managed storage and writes the shard and <code>--last-failed</code> flags to an env file.</td></tr><tr><td>Native CI cache</td><td>No extra tooling. You own the cache keys and the conditional flag logic — see the caveats above.</td></tr></tbody></table>

Playwright also accepts `--last-failed-file <path>` (or `PLAYWRIGHT_LAST_RUN_OUTPUT_FILE`) to write the last-run file to an explicit path instead of the default `<outputDir>/.last-run.json`. This is useful with a native cache, where caching a stable path is simpler than depending on the internal `outputDir` layout. See [Re-run Only Failed Tests](/guides/ci-optimization/re-run-only-failed-tests) for details.

## Step-by-step guides

* [**GitHub Actions**](/getting-started/ci-setup/github-actions/re-run-failed-only-tests/re-run-failed-only-tests-sharded)
* [**GitLab CI**](/getting-started/ci-setup/gitlab/re-run-failed-only-tests#playwright-sharding)
* [**Jenkins Pipeline**](/getting-started/ci-setup/jenkins#using-last-failed-flag-with-shards-and-orchestration)

See also the overview: [Re-run Only Failed Tests](/guides/ci-optimization/re-run-only-failed-tests).


# Orchestrated runs

Re-run only failed Playwright tests when using Currents Orchestration

{% hint style="info" %}
Failed orchestrated reruns require **Rerun All Jobs** in the CI provider, not **Rerun Failed Only**.
{% endhint %}

Orchestrated runs work differently from native Playwright sharding. Currents assigns tests to **all available machines**. More machines can run the tests faster, and the total number of CI machines does not need to be set in advance.

<figure><img src="/files/EH56Ma2yC20BHMChNq7e" alt=""><figcaption><p>Rerunning failed-only Playwright tests using Currents Orchestration</p></figcaption></figure>

That's why failed orchestrated CI reruns use **Rerun All Jobs** instead of **Rerun Failed Only**:

* The CI provider will spin up all the containers
* Currents will assign the failed tests to all the available containers
* More available containers will run the tests in parallel faster

## Orchestration flow

In Orchestration, Playwright filter flags such as `--last-failed` belong on `pwc-p discover`. The generated test list is passed to `pwc-p run` with `--pwc-discovery-file`.

```bash
npx pwc-p discover --pwc-discovery-file tests.txt --last-failed
npx pwc-p run --key <record-key> --project-id <project-id> --ci-build-id <ci-build-id> --pwc-discovery-file tests.txt
```

See [Orchestration Setup](/guides/ci-optimization/playwright-orchestration) for setup details.

## Step-by-step guides

* **GitHub Actions** — [Orchestrated runs](/getting-started/ci-setup/github-actions/re-run-failed-only-tests/re-run-failed-only-tests-orchestrated-v2)
* **GitLab CI** — [Re-run Only Failed Tests](/getting-started/ci-setup/gitlab/re-run-failed-only-tests)
* **Jenkins Pipeline** — [Jenkins](/getting-started/ci-setup/jenkins#using-last-failed-flag-with-shards-and-orchestration)

See also the overview: [Re-run Only Failed Tests](/guides/ci-optimization/re-run-only-failed-tests).


# Cloud Spot Instances

Running Playwright E2E tests on CI Spot Instances and using Currents Orchestration to automatically rerouting tests before an eviction.

An additional benefit of using Currents for balancing tests is the ability to automatically redrive tests from one machine to another.

{% hint style="info" %}

* Get familiar with [Orchestration Setup](/guides/ci-optimization/playwright-orchestration)
* Requires `@currents/playwright@1.13.0+`
  {% endhint %}

### Cost Efficiency of Spot Instances

Many cloud providers have an option to use [Spot Instances](https://aws.amazon.com/ec2/spot/) for running workloads. Using Spot Instances can cost up to 90% lower, compared to the traditionally allocated resources.

<figure><img src="/files/yv1MGK6I9k2ciivDhzop" alt=""><figcaption><p>Cost optimization with Spot Instances. Source: https://aws.amazon.com/blogs/containers/cost-optimization-for-kubernetes-on-aws/</p></figcaption></figure>

However, spot instances can be terminated at any time, which can cause the loss of the test results.

Currents Orchestration can automatically reassign the tests from to-be-terminated instance to another machine. This way, the execution can continue without manual intervention.

### How it works

Imagine a scenario when you have two machines running a testing suite consisting of two spec files.

* Machine A - running specA
* Machine B - running specB

When a spot instance is just about to be terminated (let's say Machine A), Currents will identify the affected spec files and reassign them a different machine.

<figure><img src="/files/wquDj3FeQBLlx6iyfFER" alt="Reassigning tests in case of spot instance termination"><figcaption><p>Reassigning tests in case of spot instance termination</p></figcaption></figure>

### Setup and Configuration

{% hint style="info" %}
Only tests orchestrated with `pwc-p` can be dynamically reassigned. Read more about [Orchestration Setup](/guides/ci-optimization/playwright-orchestration).
{% endhint %}

Starting from version `1.3.0` of `@currents/playwright` set `--pwc-reset-signal` CLI parameter:

```
pwc-p run .... --pwc-reset-signal SIGUSR1|SIGUSR2
```

When specified, `pwc-p run` starts listening to POSIX signal (`SIGUSR1` or `SIGUSR2`). After receiving the signal, it sends a request to Currents servers to reassign the affected tests to healthy machines. Currents updates the run status accordingly.

An example output you're expected to see upon termination:

{% code overflow="wrap" %}

```
$ npx pwc-p run --key XXX --project-id YYY --ci-build-id reset-001 --pwc-reset-signal SIGUSR1

🚥 Will reset tests on SIGUSR1. PID: 66640
🚀 Starting orchestration session...
📦 Currents reporter: 1.3.0 recording CI build reset-001 for project YYY
🎭 Playwright: 1.44.0 1 test in 1 project [chromium] 

🌐 Executing orchestrated task: [chromium] test.spec.ts 
🌐 Run URL: https://app.currents.dev/run/c11610c6e1644913

================================================================

2024-05-15T23:31:57.336Z starting test attempt #1: [chromium] › test.spec.ts:15:5 › A

# in another terminal: kill -SIGUSR1 66640

🚥 Received SIGUSR1
🚥 Resetting tests: machineId: <id>, runId: <run-id>
🚥 Success resetting tests: machineId: <id>, runId: <run-id>
```

{% endcode %}

{% hint style="warning" %}
It is your responsibility to capture the eviction notice, detect the PID and send the signal to `pwc-p` process before an eviction.

* `usr1` normally activates the Node.js debugger, but this ability is disabled when we listen on usr1
* `usr2` normally treated as a exit in Node.js, so if you pass it WITHOUT turning on our listener, you will immediately kill the process
* You must send the signal to the `pwc-p run` process — **not the npx or wrapper process**. The parent process will behave as noted above and not pass the signal down to our process.
  {% endhint %}

Refer to the following documentation for capturing the eviction notice for various cloud providers:

* [AWS - Spot Instance interruption notice](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-instance-termination-notices.html)
* [Azure - Simulate Spot Virtual Machine eviction](https://learn.microsoft.com/en-ca/azure/virtual-machines/windows/spot-powershell#simulate-an-eviction)
* [GCP - Spot VM preemption process](https://cloud.google.com/compute/docs/instances/spot#preemption-process)


# Failing Fast

Fail-fast or cancelling runs on first failure

Automatically cancelling your test suite right after the first failure is called a "fail-fast strategy". Currents dashboard allows tracking the outcome of your tests and automatically cancels runs whenever the first failed spec file is detected.

After executing a spec file, the runner sends the results to the Currents dashboard. The dashboard receives the results, identifies a failed test, and marks the associated run as "cancelled". Any new requests associated with the run will fail with a warning, as a result, cypress runners will not be able to start executing a new spec file for the run.

Please note, that any spec file that is still in progress will run to completion and its results will still be accepted.

![Example of a run automatically cancelled via "fail-fast" policy](/files/2TKoYsLbvRZk6tVpedrn)

Using a "fail-fast" strategy can be beneficial because:

* it reduces CI resources usage by preventing running additional tests after detecting just a single failure;
* potentially getting faster feedback for runs with a failed test - you don't need to wait for the run to finish;
* it reduces the number of tests results recorded on the Currents dashboard;
* it prevents [Run Timeouts](/dashboard/runs/run-timeouts) when an external tool (CI or a script) terminates cypress tests prematurely.

At the same time, utilizing a "fail-fast" strategy has some caveats:

* not all the tests will be executed - you will only see the results of a single test - the first test that triggered the "fail-fast" policy;
* tackling one failure at a time can result in more runs than necessary - one can invest more time and resources, compared to running all the tests regardless of their results.

![Automatically cancelled runs will be marked as failed and cancelled](/files/E0A0i1sc3Gn7VNiFR7Am)

If you are dealing with a stable and predictable suite of tests that rarely fail - "fail-fast" can be a great way to optimize your cypress tests.

{% hint style="info" %}
[Read more](/dashboard/runs/cancel-run) about how cancelling runs affects runs status, analytics and integrations
{% endhint %}

### Enabling fail-fast strategy

To enable the "fail-fast" strategy navigate to the **Manage Project** screen and toggle **Enable Fail Fast Strategy** controller.

Customers using our [cypress-cloud](/resources/reporters/cypress-cloud) integration can control the "fail-fast" behaviour using the command line CLI flag `--auto-cancel-after-failures <number | false>`.

Customers using our [@currents/playwright](/resources/reporters/currents-playwright) integration can use `--pwc-cancel-after-failures <number | false>` option.

If set, it overrides the project's default fail-fast strategy setting. If not set, use the default project settings:

* `false` prevents fail-fast
* `number` aborts the run across all the participating machines when the threshold is exceeded

{% hint style="info" %}
`@currents/playwright` ≥ 1.0 count failed tests only - skipped or interrupted tests do not trigger cancellation. `@currents/playwright` < 1.0 (0.x) and `cypress-cloud` count failed and skipped tests toward the threshold.
{% endhint %}

For example

* `npx pwc --key xxx --project-id xxx --ci-build-id id-001 --pwc-cancel-after-failures 1`
* `npx cypress-cloud run --parallel --record --key xxx --ci-build-id id-001 --spec "./cypress/e2e/*.spec.js" --auto-cancel-after-failures`**`false`** will deactivate the fail-fast strategy, regardless of your project settings
* `npx cypress-cloud run --parallel --record --key xxx --ci-build-id id-001 --spec "./cypress/e2e/*.spec.js" --auto-cancel-after-failures`**`5`** will stop the run if more than 5 failed tests detected


# Load Balancing

Review of Orchestration strategies for Cypress and Playwright tests

Running your tests suite in parallel on multiple machines can greatly reduce the overall duration. You can further optimize the speed of parallel tests by optimally balancing based on their expected duration. In some cases, it's worth prioritizing tests based on a different heuristic - for example, running tests with the highest failure or [flakiness rate](/dashboard/tests/flaky-tests).

Orchestration services like Currents Dashboard use historical data to optimize the execution order of cypress tests and utilize different strategies for ordering the execution.

### Optimal sorting by the expected duration

The default Currents dashboard orchestration strategy orders tests by their expected duration. Consider the example of 2 cypress runners, executing a suite consisting of 5 spec files.

Take, for example, a testing suite consisting of 4 spec files with varying durations:

* `spec01`: 10 minutes
* `spec02`: 10 minutes
* `spec03`: 3 minutes
* `spec04`: 2 minutes

With 2 machines, non-optimal balancing might distribute the files as follows, leading to an inefficient total execution time of 20 minutes due to one machine being heavily loaded while the other finishes quickly:

* Shard 1: `spec01`, `spec02` (20 minutes total)
* Shard 2: `spec03`, `spec04` (5 minutes total)

By ordering spec files according to their expected duration and optimizing the distribution of the files between runners (CI machines), we can significantly reduce the overall duration of runs and complete our tests suite faster.

<figure><img src="/files/BWDAIrpo97CnevsaRgPJ" alt=""><figcaption><p>Non-optimal distribution of spec files leads to under-utilized resources and longer duration</p></figcaption></figure>

An optimal assignment strategy that considers the duration of spec files can significantly improve the efficiency of test execution. By balancing the workload across shards based on test durations, you minimize overall execution time and make better use of resources. For the example provided:

* Shard 1: `spec01` (10 minutes) and `spec03` (3 minutes), totaling 13 minutes.
* Shard 2: `spec02` (10 minutes) and `spec04` (2 minutes), totaling 12 minutes.

<figure><img src="/files/Z4K5xYRV9QBdUqPHybcQ" alt=""><figcaption><p>Optimal distribution of spec files is 35% faster and uses the resources in an optimal way</p></figcaption></figure>

Having this kind of optimization reduces the overall duration of runs and saves valuable time, reduces CI machines utilization and allows developers to get feedback faster.

For larger teams with a significant amount of tests, the cumulative gains of reducing the duration of CI tests can be substantial.

### Optimal sorting by the failure rate

Sorting by Failure Rate is another popular parallelization strategy. The spec files with the highest expected failure rate will be prioritized for parallel execution - which allows for getting faster feedback from the CI builds.

Enabling this orchestration method and sorting by failure rate can also help to reduce the overall time and effort required for CI runs. By identifying and executing the most critical tests first, developers can quickly identify issues and fix them before moving on to less important tests. This can improve the quality of the code and reduce the likelihood of issues appearing in production.

Enabling this orchestration method and [Failing Fast](/guides/ci-optimization/fail-fast-strategy) can greatly reduce the CI resource usage. The tests that are likely to fail will be executed first, and whenever Currents detects a failure, the whole run will be stopped.

You can set the orchestration method by modifying individual project settings in Currents Dashboard: **Manage Project > Settings > Parallel Execution Strategy.**

<figure><img src="/files/eWd7ZGUJ9RJw1eEvhRWv" alt=""><figcaption><p>Setting the orchestration strategy on Currents Dashboard</p></figcaption></figure>


# Code Coverage

Collect Code Coverage reports for web applications using Playwright or Cypress

Code coverage is a popular technique for measuring what parts of the source code have been executed while running tests. It is commonly used to determine how thoroughly a test suite exercises a particular codebase.

[Playwright](https://playwright.dev/docs/api/class-coverage) and [Cypress](https://docs.cypress.io/guides/tooling/code-coverage) both support collecting code coverage from the underlying application. When running tests in a distributed and parallel CI environment, Currents collects coverage metrics from distributed, parallel tests; merges the individual coverage reports, and presents coverage information in Currents web dashboard.

### Coverage for Web Applications

When running browser-based end-to-end or component tests, we can talk about various types of "coverage".

**Code coverage**

Code coverage measures what parts of the source code were executed and how often. Code coverage metrics are related to code abstracts - lines of code, `if` statements (branches), functions and so on.

**Functional UI coverage**

Functional UI coverage determines how well software's functional requirements are tested, such as navigation and user interactions. It measures what end-user workflows have been tested and if the software performs as expected.

{% hint style="info" %}
This guide focuses on Code Coverage, specifically - on how to report Code Coverage to Currents when using Playwright and Cypress testing frameworks.
{% endhint %}

### Generating Code Coverage

**Code instrumentation**

The frontend source code goes through a transpilation before being loaded into a browser. It can be a manual build / bundling stage that you manage yourself (using tools like webpack, esbuild, rollup, swc etc.) or a build step of a popular frontend framework like vite, nextjs, remix, svelte, angular.

During the build phase we instrument the compiled code - for example, increment a counter before function invocations or before entering an `if` statement. Running the instrumented code activates the counters and that's how we measure the coverage.

<figure><img src="/files/1IhLgCrwWuBESGvBd4vE" alt=""><figcaption><p>Instrumenting code for collecting code coverage</p></figcaption></figure>

Instrumentation is the traditional way to generate coverage metrics on different browsers and JS engines.

[Instanbul ](https://istanbul.js.org/)is a popular ecosystem of coverage-related tools - it is widely used to instrument code and generate coverage reports.

**V8 Code Coverage**

An alternative approach is to use the built-in capabilities of Javascript engines. For example, NodeJS and chromium-based browsers use V8, which collects coverage metrics while executing JS code.

<figure><img src="/files/cqcrQdLuyuBhfIJBIe6F" alt=""><figcaption><p>V8 collects code coverage from browser engine</p></figcaption></figure>

There's no need to instrument the code in V8 - one can get the metrics by sending a series of [API calls](https://chromedevtools.github.io/devtools-protocol/tot/Profiler/#method-startPreciseCoverage). It is common to transform the output of V8 coverage report to other popular formats.

### Recording Coverage Fragments

Web automation tools like Cypress, Selenium or Playwright run your application in a browser. The tests navigate to various routes, interact with the page components - every interaction activates certain parts of the code and populates the coverage information.

Each individual test creates a partial coverage report. At the end of each test, we need to collect those fragments and merge them to create a complete snapshot of what parts of the source code are "covered" by your testing suite.

<figure><img src="/files/AEJl6CUktYzGby9q5KU4" alt=""><figcaption><p>Recording and merging coverage fragmented reports</p></figcaption></figure>

### Coverage Metrics

Code coverage metrics include line coverage, branch coverage, function coverage, and statement coverage.

* **Line coverage** measures the percentage of lines of code that have been called
* **Branch coverage** measures the percentage of if/else code branches that have been checked
* **Function coverage** measures the percentage of a program's functions that have been called
* **Statement coverage** measures the percentage of a program's statements that have been called

{% hint style="info" %}
Read more about [Code Coverage metrics meaning](https://en.wikipedia.org/wiki/Code_coverage)
{% endhint %}

### Code Coverage in CI

As your test suite grows and you start running tests in CI, often in parallel, you need to start maintaining the merging of coverage reports from multiple containers or shards, identifying changes in coverage metrics and tracing changes.

Currents simplifies this process by:

* Collecting coverage reports from distributed CI machines
* Handling test retries and interrupted runs accurately
* Uploading raw coverage reports for processing in the background
* Tracking coverage metrics over time, with support for filtering by tags, git metadata, and more

<figure><img src="/files/ybcLpY0iQggDaeKEMY6D" alt=""><figcaption><p>Collecting, merging and processing of distributed coverage reports</p></figcaption></figure>

### Coverage Metrics in Currents

{% hint style="info" %}

* The current version only shows aggregated **cross-file coverage metrics.**
* Only finished runs contribute to coverage reports. A run is finished if it reported results for all spec files and tests. Cancelled and timed-out runs are not considered finished, thus Currents will ignore their coverage reports.
  {% endhint %}

Currents collects, aggregates and stores the coverage information for recorded runs together with the associated metadata like git commit info or tags. After enabling code coverage for your testing suite, you'll be able to browse the code coverage details for individual runs, as well as explore trends and aggregated coverage metrics.

<figure><img src="/files/wVg0HnvmMPM30oLJbUkU" alt=""><figcaption><p>Run-specific code coverage details</p></figcaption></figure>

<figure><img src="/files/rohFmeCV7W9sH7yrsukC" alt=""><figcaption><p>Cross-run aggregated coverage metrics</p></figcaption></figure>


# Code Coverage for Playwright

Learn how to enable Code Coverage reporting for Playwright

## Intro

This guide teaches how to report Playwright Code Coverage to Currents. If you are looking for information about how Code Coverage works, or what is Currents, head to the pages below.

{% content-ref url="/pages/Pcg9IQJNeauR9a7LslII" %}
[Code Coverage](/guides/coverage)
{% endcontent-ref %}

{% content-ref url="/pages/7ZiTgPMGICI8hn8UzBjt" %}
[Overview](/)
{% endcontent-ref %}

## Report code coverage to Currents

Reporting code coverage to Currents as part of running your Playwright tests consist of 3 steps:

1. Setting up the project
2. Instrumenting the code
3. Configuring Playwright coverage fixtures
4. Updating the tests code

### Setting up the Currents reporter

{% hint style="info" %}

* Follow the [feature request](https://currents.featurebase.app/p/v8-coverage-reports-for-playwright) to get notified when we enable V8 coverage reports
* Check out the [example GitHub repository](https://github.com/currents-dev/currents-examples/tree/main/playwright/code-coverage/instrumented-coverage)
  {% endhint %}

{% hint style="info" %}
Requires`@currents/playwright` v1.7.0+
{% endhint %}

Install and configure Currents reporter following [Quick Start](/getting-started/your-first-playwright-run). Make sure that [@currents/playwright](/resources/reporters/currents-playwright) reporter is configured with the right [Record Key](/guides/record-key) and **Project ID**.

By default Currents reporter uploads all discovered coverage reports, you can include only certain Playwright projects by setting the coverage `projects` option, when using the reporter

{% code title="playwright.config.ts" %}

```typescript
import {
  CurrentsConfig,
  CurrentsFixtures,
  currentsReporter,
  CurrentsWorkerFixtures,
} from "@currents/playwright";
import { defineConfig, PlaywrightTestConfig } from "@playwright/test";

const currentsConfig: CurrentsConfig = {
  recordKey: "xxx",
  projectId: "yyy",
  coverage: {
    projects: ['projectA', 'projectB],
  },
};

const config = defineConfig<CurrentsFixtures, CurrentsWorkerFixtures>({
  use: {
    ...
    currentsConfigOptions: currentsConfig,
  },

  reporter: [currentsReporter(currentsConfig)],
  ...
});

export default config;
```

{% endcode %}

or setting the `--pwc-coverage projectA,projectB` when using the `pwc` CLI command

```bash
npx pwc --key <record-key> --project-id <project-id> --pwc-coverage projectA,projectB
```

To check other configuration options run `pwc` command with the `--help` flag.

### Instrumenting the code

Use the table below for enabling Istanbul instrumentation for your framework / bundler.

<table><thead><tr><th width="158">Bundler</th><th>Plugin</th></tr></thead><tbody><tr><td>webpack</td><td><a href="https://github.com/istanbuljs/babel-plugin-istanbul">babel-plugin-istanbul</a></td></tr><tr><td>vite</td><td><a href="https://github.com/ifaxity/vite-plugin-istanbul">vite-plugin-istanbul</a></td></tr><tr><td>rollup</td><td><a href="https://github.com/artberri/rollup-plugin-istanbul">rollup-plugin-istanbul</a></td></tr><tr><td>swc</td><td><a href="https://github.com/kwonoj/swc-plugin-coverage-instrument">swc-plugin-coverage-instrument</a> (experimental)</td></tr><tr><td>esbuild</td><td><a href="https://www.npmjs.com/package/esbuild-plugin-istanbul">esbuild-plugin-instanbul</a></td></tr></tbody></table>

Once enabled, you'd be able to see `window.__coverage__` object in your browser's console when opening your webapp. Don't hesitate to contact Currents Support if you need help with instrumenting your code.

### Playwright Fixtures for Code Coverage

`@currents/playwright` provides a set of [Playwright fixtures](https://playwright.dev/docs/test-fixtures) that simplify extraction and collection of coverage reports.

{% hint style="info" %}
It is a good practice to [extend](https://playwright.dev/docs/api/class-test#test-extend) the default Playwright `test` method, for example to enable [Page Object Model](https://playwright.dev/docs/pom), [sharing a state](https://playwright.dev/docs/test-fixtures#worker-scoped-fixtures) between multiple tests etc. See [Playwright Fixtures](/resources/reporters/currents-playwright/playwright-fixtures) for more information.
{% endhint %}

{% code title="base.ts" overflow="wrap" %}

```ts
   import {
     CurrentsFixtures,
     CurrentsWorkerFixtures,
     fixtures,
   } from "@currents/playwright";
   import { test as base } from "@playwright/test";
   
   export const test = base.extend<CurrentsFixtures, CurrentsWorkerFixtures>({
     ...fixtures.baseFixtures,
     ...fixtures.coverageFixtures,
   });
```

{% endcode %}

If you are using custom fixtures, please refer to [Combining Currents fixtures with existing custom fixtures](/resources/reporters/currents-playwright/playwright-fixtures#combine-currents-fixtures-with-existing-custom-fixtures) to ensure they are set up correctly.

### Update tests to use new test method

Import and use the extended `test` for every test case to enable automatic collection of coverage reports

```ts
import { expect } from "@playwright/test";
import { test } from "./base.ts";
```

After completing this step and running the tests, Currents reporter will automatically merge and upload for post-processing the coverage reports. There's no need to run explicit upload commands.

### NextJS + Babel Example

We will be using the [example GitHub repository](https://github.com/currents-dev/currents-examples/tree/main/playwright/code-coverage/instrumented-coverage) to configure code coverage reporting for NextJS + babel.

Install `babel-plugin-istanbul`

```sh
npm i -D babel-plugin-istanbul
```

Update (or create) `babel.config.js`

{% code title="babel.config.js" %}

```js
module.exports = {
  presets: ["next/babel"],
  plugins: ["istanbul"],
};
```

{% endcode %}

After completing this step, your app's code is instrumented. Running `npm run dev` and opening your browser will activate the underlying code coverage methods and you'll see coverage information in `window.__coverage__` object.

<figure><img src="/files/ULUmYNtZjZuaGbqj7s4W" alt=""><figcaption><p>Exploring window.__coverage__ object</p></figcaption></figure>

Note that Playwright tests use the extended `test.extend` command with Currents coverage fixtures. Running Playwright tests `npm run test` will activate a pre-configured Currents reporter and will send the code coverage information together with the rest of the results:

<figure><img src="/files/FSV1MICSeVae1jT2ZkfH" alt=""><figcaption></figcaption></figure>


# Code Coverage for Cypress

Learn how to setup Cypress to start reporting code coverage results

### Code Coverage for Cypress

{% hint style="info" %}
TL;DR

See a working [example GitHub repository](https://github.com/currents-dev/cypress-cloud/tree/main/examples/coverage)

* Install `cypress-cloud` version `1.9.5+`
* Install and configure Cypress Code coverage plugin as described [here](https://docs.cypress.io/guides/tooling/code-coverage)
* Run `cypress-cloud` with `--experimental-coverage-recording` CLI flag enabled
  {% endhint %}

Enabling code coverage for Cypress involves the following steps:

* Instrumenting the code and generating the coverage report (done by `cypress` runner together with Istanbul or any other coverage tool)
* Uploading the report to Currents for processing (done by `cypress-cloud` package)

#### Instrumenting the code

Instrumenting the code and generating reports is well described in the detailed [guide](https://docs.cypress.io/guides/tooling/code-coverage).

In short:

* Install and configure the official [@cypress/code-coverage](https://www.npmjs.com/package/@cypress/code-coverage) plugin together with the `@cypress/code-coverage/support` support file (the plugin is developed and maintained by the Cypress.io team)
* Add [code instrumentation](https://github.com/cypress-io/code-coverage#instrument-your-application) - for example, by using `@cypress/code-coverage/use-babelrc` for on-the-fly instrumentation

#### Uploading the reports to Currents

* If you haven’t yet, [install `cypress-cloud`](https://github.com/currents-dev/cypress-cloud#setup); make sure to add `cypress-cloud/plugin` **after** `@cypress/code-coverage`
* **Optional:** provide custom location for generated reports:
  * `cypress-cloud` expects to find the coverage reports at their default location at `<projectRoot>/.nyc_output/out.json`
  * **Y**ou can provide a custom location by setting `env.coverageFile` in `cypress.config.{jt}s`

**Example `cypress.config.ts` file**

```tsx
// cypress.config.ts
import coveragePlugin from "@cypress/code-coverage/task";
import coverageInstrumenter from "@cypress/code-coverage/use-babelrc";

import { cloudPlugin } from "cypress-cloud/plugin";

import { defineConfig } from "cypress";

export default defineConfig({
  e2e: {
    async setupNodeEvents(on, config) {
      // enable on-the-file instrumentation
      on("file:preprocessor", coverageInstrumenter);
      // enable coverage plugin to generate a report
      const tempConfig = coveragePlugin(on, config);
      // enable cypress-cloud plugin
      return await cloudPlugin(on, tempConfig);
    },
    baseUrl: "<http://localhost:8888>",
    supportFile: "cypress/support/e2e.js",
    specPattern: "cypress/**/*.cy.js",
    env: {
      // @cypress/code-coverage config
      // exclude test files from the reports
      codeCoverage: {
        exclude: ["cypress/**/*.*"],
      },
      // ⭐️ instruct cypress-cloud on the location of the generated report
      coverageFile: "./.nyc_output/out.json",
    },
  },
});
```

**Example Cypress `support.ts` file**

```tsx
import "@cypress/code-coverage/support";
import "cypress-cloud/support";
```

#### Run `cypress-cloud` with coverage enabled

Running `cypress-cloud` with `--experimental-coverage-recording` flag will activate the collection of the coverage reports and send them to Currents for processing.

The script will discover the reports at the configured location `./.nyc_output/out.json` by default, or an explicit location defined in `env.coverageFile` of `cypress.config.{jt}s`

Example:

{% code overflow="wrap" %}

```bash
npx cypress-cloud run --parallel --record --key <record_key> --ci-build-id <ci-build-id>  --experimental-coverage-recording
```

{% endcode %}


# Currents Actions

Automate workflows by triggering actions based on flexible rules and conditions

The Currents Actions Engine enables the implementation of custom workflows for testing-related activities. For example, you can conditionally and temporarily skip or quarantine a test.

Writing and running tests locally or in CI is typically just one step in a more comprehensive workflow. Such a workflow can include multiple stages, such as:

* Creating a test;
* Assigning a person or team as the "owner";
* Running the test in "evaluation" mode to measure its performance and stability;
* Alerting the team when test performance (e.g., flakiness, duration, or failure rate) degrades.

It is often necessary to tweak test behavior temporarily in an ad-hoc manner. For instance:

* skipping a flaky test to unblock a CI pipeline,
* opening a ticket to investigate a flakiness, and later creating another ticket to "unskip" the test,
* dynamically add a tag,
* send an alert if a test becomes flaky.

Another example is the intelligent selection of tests to run. For instance, only high-impact tests are run on each commit, while nightly jobs or commits to the main branch run the full test suite. The list of high-impact tests is dynamically defined based on test performance or other criteria (e.g., age, tags). This list might include new, flaky, and frequently failing tests, while omitting stable tests that rarely fail. This approach accelerates software delivery and conserves CI resources without compromising quality.

Today, teams often rely on in-house solutions and conventions to implement such workflows.

Currents Actions, combined with detailed reporting, integrations with third-party tools, test result histories, and observability metrics, unlocks these scenarios using a flexible set of rules and actions - all powered by the Currents platform as the source of truth, accessible to the entire team.


# Setting up Currents Actions

Setting up Current Actions for your Playwright Project

### Requirements

* Only available for Playwright
* Requires `@currents/playwright` v1.9.0+

### Overview

Setting up the Currents Actions consists of 3 steps:

1. Setting up the project
2. Configuring Playwright fixtures
3. Updating the tests code

{% hint style="info" %}
Check out the [example GitHub repository](https://github.com/currents-dev/currents-examples/tree/main/playwright/currents-actions).
{% endhint %}

### Setting up the Currents Reporter

Install and configure Currents reporter following [Quick Start](/getting-started/your-first-playwright-run) guide.

### Add Playwright Fixtures

`@currents/playwright` provides a [Playwright fixture](https://playwright.dev/docs/test-fixtures) that must be installed to enable Currents fixtures.

{% hint style="info" %}
It is a good practice to [extend](https://playwright.dev/docs/api/class-test#test-extend) the default Playwright `test` method, for example to enable [Page Object Model](https://playwright.dev/docs/pom), [sharing a state](https://playwright.dev/docs/test-fixtures#worker-scoped-fixtures) between multiple tests etc. See [Playwright Fixtures](/resources/reporters/currents-playwright/playwright-fixtures) for more information.
{% endhint %}

{% code title="base.ts" %}

```typescript
 import {
   CurrentsFixtures,
   CurrentsWorkerFixtures,
   fixtures,
 } from "@currents/playwright";
 import { test as base } from "@playwright/test";
 
 export const test = base.extend<CurrentsFixtures, CurrentsWorkerFixtures>({
   ...fixtures.baseFixtures,
   ...fixtures.actionFixtures,
 });
```

{% endcode %}

### Update Tests

Import and use the extended `test` for every test case to enable the rules engine for that test.

```typescript
import { expect } from "@playwright/test";
import { test } from "./base.ts";
```

### Optional: conditionally enable fixtures only on CI

After extending the `test` method, many Currents fixtures are enabled by default. If you wish to only conditionally enable them (such as only in CI) you can use the `currentsFixturesEnabled` property in your `playwright.config.ts` file.

{% code title="playwright.config.ts" %}

```typescript
// ...
use: {
  ...
  currentsFixturesEnabled: !!process.env.CI,
},
```

{% endcode %}


# Using Currents Actions

Create and Manage Currents Actions, trace action applications and outcomes

{% hint style="info" %}

* Users with **Admin** role can create and modify actions.
* Users with **Actions admin** role can create and modify actions
* Users with **Member** role can browse actions in read-only mode.
  {% endhint %}

Access the Actions Management view via **Menu > Manage Project > Actions** to browse, create and modify actions.

### Action State

An action can be in one of the following states:

* Active - the action is active and it will apply based on its conditions;
* Expired - the action has expired and isn't applicable anymore;
* Disabled - the action was disabled by a user.

By default only **Active** actions are visible, change the visibility filter to see additional items.

<figure><img src="/files/hcrsvXH6gQLi2hc4kpgq" alt=""><figcaption><p>Actions Management View</p></figcaption></figure>

### Creating a new Action

Click **Create Action** to open action creation modal. Enter the action details:

* **Name** - human readable name
* **Description** - verbose explanation of the action intent
* **Expiration date and time** - the action will be marked as Expired and will not apply after the specified date
* **Condition** - set of conditions (filters) that a test must satisfy to activate an action. Refer to [Conditions](/guides/currents-actions/reference/conditions) reference documentation
* **Actions** - set of actions that will apply if a test matches the conditions. Refer [Actions](/guides/currents-actions/reference/actions) reference documentation

<figure><img src="/files/tup4AKPl83TelMn0XhAh" alt=""><figcaption><p>Action Creation Form</p></figcaption></figure>

Users with Admin role can **Disable** or **Edit** an action after its creation.

<figure><img src="/files/qfa4jljXLUcLhle5mQ7w" alt=""><figcaption><p>Action Edit History</p></figcaption></figure>

### Action Creation Shortcut

When browsing test results you can create new actions using the inline Create Action shortcut. Clicking one of the predefined actions will open action creation form pre-populated with the current test details.

<figure><img src="/files/03S7Fl2AETesEKVTmGwM" alt=""><figcaption><p>Using inline action creation shortcut</p></figcaption></figure>

### Action Traceability

If a test was affected by an action, it will display Actions Engine trace. Clicking on a trace item takes users to the associated Action definition.

<figure><img src="/files/IEMvOQqpfsZgRUV4WQXP" alt=""><figcaption></figcaption></figure>


# Affected Tests

Track what tests have been affected by Actions

The **Affected Tests** tab is part of the project **Actions** area in Currents. It helps teams see which tests were touched by actions (such as skip, quarantine, or tag rules) over a recent period, and jump from there into the relevant runs, test views, or action definitions.

### Opening the tab

1. Open the project in Currents.
2. Go to **Manage Project** -> **Actions**.

<figure><img src="/files/g37QvG632Eox1D8Nr1BA" alt=""><figcaption></figcaption></figure>

***

### What the screen shows at a glance

From top to bottom:

1. **Search** — narrow the list by words in the test title, spec file path, or action name.
2. **Filters** — limit by action status, action type, and how far back in time to look.
3. **Affected tests —** List of the affected tests with its executions by the actions using the filters set.

<figure><img src="/files/DtMmuFzemqj4pxeU0GCd" alt=""><figcaption></figcaption></figure>

***

### Specific action affected tests

When a specific action is selected, a list of affected tests with its executions will show up at the bottom of the panel.

<figure><img src="/files/HaWwV59UQlh2WgACOxvt" alt=""><figcaption></figcaption></figure>

***

### Filters

#### Action Status

The **Action Status** setting filters results based on the current state of related actions, allowing you to view only those that are active, disabled, expired, or archived. By default, results are shown for active actions when the tab is first opened.

#### Action Type

The **Action Type** setting filters results based on the kind of actions performed. It allows you to limit results to specific categories such as skip actions, quarantine actions, or tag actions, depending on what you want to focus on.

{% hint style="info" %}
**Look back** is separate from **Reset Filters**: resetting does not change the selected look back period.
{% endhint %}

***

### List header

When there are results, a short line above the list shows how many affected tests are shown (for example a range on long lists) and offers **Sorted by last seen**. That control flips between **newest first** and **oldest first** based on when the test was last seen in the selected window.

***

### Each test row (before expanding)

| Part             | What it means                                                              |
| ---------------- | -------------------------------------------------------------------------- |
| Arrow            | Expands or collapses run-level detail for that test.                       |
| **Title**        | Name of the test.                                                          |
| **Spec file**    | Name of the spec (smaller text under the title).                           |
| **Last seen**    | How long ago matching activity last occurred, within the look back window. |
| **N runs**       | How many runs in that window are associated with this test for this view.  |
| **Badges**       | Types of actions that applied (Skip, Quarantine, Tag), for quick scanning. |
| **Action names** | Links to open each action’s page to read or change the rule.               |

If many different actions apply to the same test, the row may show the first two and an **and N more** link. Choosing it reveals the rest; **show less** hides the extra lines again.

Choosing an **action name** opens that action in the "Actions" tab.

**Expired**, **Disabled**, or an **expires** time may appear next to an action when that status applies. When an active action is close to expiring, the expiry hint may be highlighted.

***

### Expanded row: executions

After expanding a test, Currents loads a short list of **executions** (recent runs where that test ran and the actions applied).

| Part              | What it means                                                                                                       |
| ----------------- | ------------------------------------------------------------------------------------------------------------------- |
| **Run** + link    | Opens the **run** in Currents. The link text is often the **commit message**; if not, it may show a run identifier. |
| **Open test**     | Opens the **test** view for that run (instance and test).                                                           |
| Badges            | Action types that applied on that execution.                                                                        |
| Action name links | Same as in the collapsed row—open the action definition for that project.                                           |
| Time              | When that execution occurred, shown as a relative time.                                                             |


# Reference

Currents Actions - condition, operations and actions reference documentation

See the conditions and actions that are available as part of Currents Actions


# Conditions

Reference documentation of Conditions that are available for Currents Actions

An Actions can have one or more condition. You can use `AND` or `OR` combinator for multiple conditions.

### Fields

#### File

Test filename path, for example `path/to/file.spec.ts`.

| Field Type          | `string`                                                                                                                                                                                                                                              |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[] \| RegexPattern[]`                                                                                                                                                                                                                |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#one-to-many-operators">#one-to-many-operators</a></p>                                                                                                       |
| Supported Actions   | <p><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions</a><br><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions</a></p> |

#### Test Title

Test title, for example in test definition `test("should open landing page")` it is `should open landing page`.

| Field Type          | `string`                                                                                                                                                                                                                                              |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[] \| RegexPattern[]`                                                                                                                                                                                                                |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#one-to-many-operators">#one-to-many-operators</a></p>                                                                                                       |
| Supported Actions   | <p><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions</a><br><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions</a></p> |

#### Test Title Path

Full title path as an array including named `describe` statements. See [testInfo.titlePath](https://playwright.dev/docs/api/class-testinfo#test-info-title-path). To match the following example:

```json
[
    "auth.spec.ts", // e.g. spec file name
    "Auth Controller", // e.g. test describe
    "Should login with correct credentials" // e.g. test title
]
```

Use a string list: <i class="fa-box">:box:</i>`auth.spec.ts` <i class="fa-box">:box:</i>`Auth Controller` <i class="fa-box">:box:</i>`Should login with correct credentials`

| Field Type          | `string[]`                                                                                                                                                                                                                                            |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[] \| RegexPattern[]`                                                                                                                                                                                                                |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#many-to-many-operators">#many-to-many-operators</a></p>                                                                                                     |
| Supported Actions   | <p><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions</a><br><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions</a></p> |

#### Test ID

Playwright [test id](https://playwright.dev/docs/api/class-testinfo#test-info-test-id), matching the test case id in the [Reporter API](https://playwright.dev/docs/api/class-reporter).

| Field Type          | `string`                                                                                                                                                                                                                                              |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[]`                                                                                                                                                                                                                                  |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#one-to-many-operators">#one-to-many-operators</a></p>                                                                                                       |
| Supported Actions   | <p><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions</a><br><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions</a></p> |

#### Tags

Test tag list. For example, if a test has the following list of tags `['a', 'b']`, each value in the list will be evaluated separately.

| Field Type          | `string[]`                                                                                                                                                                                                                                            |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[]`                                                                                                                                                                                                                                  |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#many-to-many-operators">#many-to-many-operators</a></p>                                                                                                     |
| Supported Actions   | <p><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions</a><br><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions</a></p> |

#### Project

Playwright project name as defined in your `playwright.config.ts`.

| Field Type          | `string`                                                                                                                                                                                                                                              |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[] \| RegexPattern[]`                                                                                                                                                                                                                |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#one-to-many-operators">#one-to-many-operators</a></p>                                                                                                       |
| Supported Actions   | <p><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions</a><br><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions</a></p> |

#### Error Message

{% hint style="info" %}
Added in `@currents/playwright@1.14.0`
{% endhint %}

Used to match a list field (eg Test Title Path) against one or more values.

Error message thrown during the test.

| Field Type          | `string`                                                                                                                                        |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[] \| RegexPattern[]`                                                                                                          |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#one-to-many-operators">#one-to-many-operators</a></p> |
| Supported Actions   | [Actions](/guides/currents-actions/reference/actions#post-test-actions)                                                                         |

#### Git Author Email

Git commit author email. See [Commit Information](/dashboard/runs/commit-information) to explore how Currents collects git commit information.

| Field Type          | `string`                                                                                                                                                                                                                                              |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[] \| RegexPattern[]`                                                                                                                                                                                                                |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#one-to-many-operators">#one-to-many-operators</a></p>                                                                                                       |
| Supported Actions   | <p><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions</a><br><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions</a></p> |

#### Git Author Branch

Git commit author name. See [Commit Information](/dashboard/runs/commit-information) to explore how Currents collects git commit information.

| Field Type          | `string`                                                                                                                                                                                                                                              |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[] \| RegexPattern[]`                                                                                                                                                                                                                |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#one-to-many-operators">#one-to-many-operators</a></p>                                                                                                       |
| Supported Actions   | <p><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions</a><br><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions</a></p> |

#### Git Branch

Git commit branch name. See [Commit Information](/dashboard/runs/commit-information) to explore how Currents collects git commit information.

| Field Type          | `string`                                                                                                                                                                                                                                              |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[] \| RegexPattern[]`                                                                                                                                                                                                                |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#one-to-many-operators">#one-to-many-operators</a></p>                                                                                                       |
| Supported Actions   | <p><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions</a><br><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions</a></p> |

#### Git Message

Git commit message. See [Commit Information](/dashboard/runs/commit-information) to explore how Currents collects git commit information.

| Field Type          | `string`                                                                                                                                                                                                                                              |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[] \| RegexPattern[]`                                                                                                                                                                                                                |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#one-to-many-operators">#one-to-many-operators</a></p>                                                                                                       |
| Supported Actions   | <p><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions</a><br><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions</a></p> |

#### Git Remote Origin

Git remote origin URL. See [Commit Information](/dashboard/runs/commit-information) to explore how Currents collects git commit information.

| Field Type          | `string`                                                                                                                                                                                                                                              |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Value Type          | `string \| string[] \| RegexPattern[]`                                                                                                                                                                                                                |
| Supported Operators | <p><a data-mention href="#basic-operators">#basic-operators</a><br><a data-mention href="#one-to-many-operators">#one-to-many-operators</a></p>                                                                                                       |
| Supported Actions   | <p><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#pre-test-actions</a><br><a data-mention href="/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions">/pages/I7xyGaEHXe2s0lQYITNB#post-test-actions</a></p> |

### Operators

#### Basic operators

<table data-full-width="false"><thead><tr><th>Operator</th><th>Description</th></tr></thead><tbody><tr><td><code>is</code></td><td>value is equal or <code>RegexPattern</code> matches</td></tr><tr><td><code>is not</code></td><td>value is different or <code>RegexPattern</code> does not match</td></tr><tr><td><code>is any</code></td><td>field returns <code>true</code> for JS expression <code>!!value === true</code></td></tr><tr><td><code>is empty</code></td><td>field returns <code>false</code> for JS expression <code>!!value === true</code></td></tr></tbody></table>

#### One to Many operators

Used to match a single value field (eg Test Title), against a list of values.

<table data-full-width="false"><thead><tr><th>Operator</th><th>Description</th></tr></thead><tbody><tr><td><code>in</code></td><td>one of the values from the list matches</td></tr><tr><td><code>not in</code></td><td>none of the values in the list match</td></tr></tbody></table>

#### Many to Many operators

{% hint style="info" %}
Added in `@currents/playwright@1.10.0`
{% endhint %}

Used to match a list field (eg Test Title Path) against one or more values.

<table data-full-width="false"><thead><tr><th>Operator</th><th>Description</th></tr></thead><tbody><tr><td><code>includes</code></td><td>all of the values in the list can be found in the field</td></tr><tr><td><code>includes some</code></td><td>at least one of the values in the list can be found in the field</td></tr><tr><td><code>missing</code></td><td>all of the values in the list are missing from the field</td></tr><tr><td><code>missing any</code></td><td>any of the values in the list is missing from the field</td></tr></tbody></table>

### Examples

<table><thead><tr><th>Field</th><th width="139">Operator</th><th width="136">Value</th><th>Description</th></tr></thead><tbody><tr><td>Test Id</td><td>is</td><td>1234</td><td>id is exact match</td></tr><tr><td>Git Branch</td><td>not in</td><td>main,stable</td><td>no matches</td></tr><tr><td>Tags</td><td>includes</td><td>featureA</td><td>tag matches</td></tr><tr><td>Tags</td><td>includes some</td><td>featA,featB</td><td>at least one tag matches</td></tr><tr><td>Error Message</td><td>is</td><td>Int(er|ra)net Error:</td><td>Errror Message matches the RegexPattern</td></tr></tbody></table>


# Actions

Reference documentation for actions that apply as part for Currents Actions Engine

### Available Actions

The following actions are supported by the Currents Actions Engine.

#### Pre-Test Actions

Actions that run in the client immediately **before** test execution.

<table><thead><tr><th width="188">Action</th><th width="434">Description</th><th>Min Version</th></tr></thead><tbody><tr><td>skip</td><td>Do not run the test at all, same as <code>test.skip().</code></td><td>v1.9.0</td></tr></tbody></table>

{% hint style="info" %}
Pre-Test Actions are applied using a [Custom Fixture](/resources/reporters/currents-playwright/playwright-fixtures#actionsfixtures) that runs the Currents Actions Engine before each of your tests.
{% endhint %}

#### Post-Test Actions

Actions that run in the client **after** test execution, but before reporting the results to Currents.

<table><thead><tr><th width="188">Action</th><th width="434">Description</th><th>Min Version</th></tr></thead><tbody><tr><td>quarantine</td><td>Run the test, but ignore the failures; the results will be sent over to Currents, test status will be <code>skipped</code>.</td><td>v1.9.0</td></tr><tr><td>add tag</td><td>Add tags to the test result. Only affects the current test execution attempt.</td><td>v1.15.0</td></tr></tbody></table>

{% hint style="info" %}
Post-Test Actions can end up evaluated in two places: as a [Custom Fixture](/resources/reporters/currents-playwright/playwright-fixtures#actionsfixtures) that runs after each of your tests, and as a [Custom Reporter](/resources/reporters/currents-playwright) that catches scenarios where the fixture wasn't run, such as errors or timeouts in test teardown.
{% endhint %}

### Limitations

Errors that occur in [Playwright's `beforeAll`](https://playwright.dev/docs/api/class-test#test-before-all) hook are not supported even if the corresponding test has the `skip` or `quarantine` action, resulting in tests still being reported as failed. Actions fixture runs after the `beforeAll` hook, and is skipped by Playwright if the hook fails. We are looking at solutions to resolve this in a future release.\
\
Errors that occur in other [Custom Fixtures](https://playwright.dev/docs/test-fixtures#creating-a-fixture) may prevent the action from being applied if the failure happens before the Currents Action fixture is loaded. To ensure the action is applied in such cases, the Currents fixture should be loaded before other fixtures. See [Playwright Fixtures](/resources/reporters/currents-playwright/playwright-fixtures#combine-currents-fixtures-with-existing-custom-fixtures)

The behaviour of [#post-test-actions](#post-test-actions "mention") can differ slightly depending on whether the failure was in the test body, or in a fixture/hook.

* quarantined in the **per-test fixture** → can mark attempt as skipped early, avoiding retries
* failures in **after hooks/teardown** → may only be quarantined at reporter stage, so retries may already be in progress

#### **Quota calculation:**

* The quarantine option will run the test, but it will be counted only if the result is a pass.
* The skip option does not count toward the test quota.


# Lifecycle Notifications

Configure and receive action lifecycle notifications

Action lifecycle notifications inform teams when actions are created, disabled, re-enabled, archived, expired or approaching expiration. Currents delivers these notifications to Slack, email, or both.

This provides visibility into changes and upcoming expirations without requiring visiting the dashboard. Teams receive timely updates, allowing them to respond before a forgotten quarantine leads to unexpected test failures.

Notification settings are configured entirely in the dashboard. The REST API can create and manage actions, but notification routing is configured per project in the **Action > Settings** page.

<figure><img src="/files/h2gfDKcWijJOF6PwFmtV" alt=""><figcaption><p>Navigate to Action Settings</p></figcaption></figure>

<figure><img src="/files/Uf03nDuzNzIdUbvLmKKP" alt=""><figcaption><p>Actions Settings > Notifications Page</p></figcaption></figure>

### Configuration and Delivery

#### Slack

Enabling Slack notifications requires two steps:

1. **Connect Slack to the organization** following the [Slack App](/resources/integrations/slack/slack-app#installation).

{% hint style="info" %}
A **Currents organization administrator** must connect, re-authenticate, or disconnect the integration. A **Slack administrator** must authorize the app; the exact required Slack role depends on whether the account uses a single workspace or Enterprise Grid.
{% endhint %}

<figure><img src="/files/p1h7vbPEDK7do6GSVV2j" alt=""><figcaption><p>Missing Slack App installation</p></figcaption></figure>

2. **Enable Slack notifications** in the Action Settings page:

* select a channel
* choose the events

Connecting Slack under Integrations alone does not enable notifications — they must be configured on this page.

<figure><img src="/files/RLJImOnVFByYzoVro8mG" alt=""><figcaption><p>Slack channel configuration</p></figcaption></figure>

Once Slack is connected, anyone with **Actions Admin** access can configure the channel and events. If the Slack option is unavailable, a Currents organization administrator must complete the Integrations setup first.

#### Email

Email is configured on the same page. Slack and email are independent — either or both can be enabled.

<figure><img src="/files/ThquX6pBkKiMzj2gbLHe" alt=""><figcaption><p>Email channel configuration</p></figcaption></figure>

Recipients include:

* **Action creator** — always listed, but mail is sent only when the creator value is a valid email address.
* **Organization administrators** and **action administrators** — optional.
* **Additional emails** — up to ten extra addresses.

{% hint style="warning" %}
**Action creator notice**

When an action is created via the REST API, the creator is stored as the API key label, which is not an email address and does not receive creator mail. For API-driven workflows, add additional emails or enable admin recipients.
{% endhint %}

{% hint style="info" %}
**Notification attribution**

Every notification displays the original creator of the action. For disable, re-enable, and archive events, the notification also identifies who performed the action — the signed-in user (dashboard) or the API key label (REST API). Expiring and expired notifications are system-triggered and display only the original creator.
{% endhint %}

<figure><img src="/files/w5mZ6r16vPS6tGlplmzs" alt=""><figcaption><p>Slack notification example</p></figcaption></figure>

<figure><img src="/files/MJvykH8X3kLyhAYDEd1L" alt=""><figcaption><p>Email notification example</p></figcaption></figure>

### Available Events

Each event can be enabled or disabled separately for Slack and email.

| Event                 | What triggers it                                                                                       |
| --------------------- | ------------------------------------------------------------------------------------------------------ |
| **Action created**    | A new action is created.                                                                               |
| **Action disabled**   | An action is manually disabled while it has not yet expired.                                           |
| **Action re-enabled** | A disabled action is re-enabled while it has not yet expired.                                          |
| **Action archived**   | An action is archived (soft-deleted) via the REST API.                                                 |
| **Action expiring**   | An active action will expire within the next 12 hours.                                                 |
| **Action expired**    | An action's expiration time passed within the last 12 hours (older expirations do not trigger alerts). |

### Important Notes

**Expiring** and **expired** notifications both use a 12-hour window. Expiring looks ahead — the expiration falls within the next 12 hours. Expired looks back — the expiration occurred within the last 12 hours.

If an expiration is set or changed very close to the actual moment — within that same 12-hour window — Currents may skip the expiring or expired notification to avoid redundant alerts.

Additional edge cases:

* **Already expired, then disabled** — no "action disabled" notification is sent.
* **Re-enabled while still expired** — no "action re-enabled" notification is sent. This event applies only when the action is not expired at the time it is re-enabled.
* **Bulk changes** — each qualifying action receives its own notification. There is no combined digest for batch operations.

<br>


# Playwright Component Testing

Using Currents with Playwright Component testing

Run [Playwright Component testing](https://playwright.dev/docs/test-components) and report the results to [Currents](https://currents.dev/playwright)

{% hint style="info" %}
**Note November 2023:** Playwright support for Component testing is still experimental
{% endhint %}

Please refer to the example integration of Playwright Component testing with Currents:

{% embed url="<https://github.com/currents-dev/currents-examples/tree/main/playwright/component-testing>" %}

The project contains two simple component tests:

* `src/App.spec.jsx` - a passing test
* `src/AppFailing.spec.jsx` - an intentionally failing test

The results will be sent to Currents for more effective troubleshooting, screenshots, playwright traces and collecting performance metrics:

<figure><img src="/files/vRzwrEKHjGFOjsWGTt73" alt=""><figcaption><p>Example of collecting Playwright Component test results</p></figcaption></figure>


# Playwright Visual Testing

Integrating Playwright Visual Comparison tools with Currents - including Argos, Percy and Applitools.

### Native Playwright Visual Comparison

Playwright has a built-in support for [Visual Comparisons](https://playwright.dev/docs/test-snapshots), allowing generation of screenshots and failing a test in case reference screenshots differ from the actual ones.

Here's an example of a test that includes visual comparison:

```typescript
test('example test', async ({ page }) => { 
  await page.goto('https://playwright.dev'); 
  await expect(page).toHaveScreenshot({ maxDiffPixels: 100 });}
);
```

Currents automatically detects tests with visual comparison enabled and shows a dedicated widget for the relevant tests:

{% embed url="<https://www.loom.com/share/3554b321e8a8409c9e37a4181b9bab1a?hideEmbedTopBar=true>" %}
Current Visual Comparison Widget for Playwright Tests
{% endembed %}

### Playwright Visual Testing with Argos

While Native Playwright Visual Comparison is a good start as a basic tool, a more advanced and dedicated visual testing solution can greatly improve the effectiveness of your testing suite. Our friends at [Argos](https://argos-ci.com/) offer a comprehensive, open-source (and loved) visual testing platform that takes care of the difficult parts of visual testing:

* stabilization: prevent visual testing flakiness by preventing font and styling changes
* test across various resolutions: ensuring every detail is captured without missing a thing
* pull request comments and status checks

Argos is 100% compatible with Playwright Sharding and Currents Reporting + Orchestration, allowing effective and painless CI setup, continuous reporting, debugging with supercharged visual testing.

#### Argos + Currents Reporter

Argos and Currents natively support Playwright Sharding for parallel CI executions - follow [the setup instructions](https://argos-ci.com/docs/quickstart/playwright) and configure both reporters to see the visual testing artifacts reported to Argos and the rest of test results reported to Currents.

<details>

<summary>Playwright configuration</summary>

```typescript
// playwright.config.ts
import { currentsReporter } from "@currents/playwright";
import { devices, PlaywrightTestConfig } from "@playwright/test";

const config: PlaywrightTestConfig = {
// ...
  reporter: [
    currentsReporter(), // explicitly activate Currents Reporter
    [
      // See https://argos-ci.com/docs/quickstart/playwright
      "@argos-ci/playwright/reporter",
      {
        uploadToArgos: true, 
      },
    ],
  ],
  use: {
    actionTimeout: 0,
    trace: "retain-on-failure-and-retries",
    video: "retain-on-failure",
    screenshot: "only-on-failure",
  },
// ...
}
```

</details>

<details>

<summary>GitHub Actions Workflow</summary>

```yaml
strategy:
  fail-fast: false
  matrix:
  shard: [1, 2, 3] # run 3 parallel containers
# ...
- name: Currents Sharding + Argos
  working-directory: ./argos
  env:
    ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }} 
    CURRENTS_PROJECT_ID: ${{ vars.CURRENTS_PROJECT_ID }}
    CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
  run: | # start playwright
    npx playwright test --shard=${{ matrix.shard }}/${{ strategy.job-total }}
```

</details>

#### Argos + Currents Orchestration

Using Argos with [Orchestration Setup](/guides/ci-optimization/playwright-orchestration) requires an additional step - notifying Argos after run's completion. This is necessary because Currents Orchestration can have an arbitrary number of CI machines participating in an execution and the allocation of tests to CI machines is dynamic.

{% hint style="info" %}
Requires @currents/playwright 1.6.0+
{% endhint %}

<figure><img src="/files/Bq7AikyGD4ADyX5G7oqc" alt="Currents Orchestration onFinish callback finalizes Parallel Argos build"><figcaption><p>Currents Orchestration onFinish callback finalizes Parallel Argos build</p></figcaption></figure>

See the [example repository](https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/github-actions/argos) which showcases using GitHub Actions with 3 parallel containers + Currents Orchestration + Argos.

<details>

<summary><a href="https://github.com/currents-dev/currents-examples/tree/main/playwright/ci/github-actions/argos/playwright.config.ts">Playwright Configuration</a></summary>

```typescript
// playwright.config.ts
import { currentsReporter } from "@currents/playwright";
import { devices, PlaywrightTestConfig } from "@playwright/test";

const config: PlaywrightTestConfig = {
// ...
  reporter: [
    currentsReporter(), // explicitly activate Currents Reporter
    [
      // See https://argos-ci.com/docs/quickstart/playwright
      "@argos-ci/playwright/reporter",
      {
        uploadToArgos: true, 
      },
    ],
  ],
  use: {
    actionTimeout: 0,
    trace: "retain-on-failure-and-retries",
    video: "retain-on-failure",
    screenshot: "only-on-failure",
  },
// ...
}
```

</details>

<details>

<summary><a href="https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/github-actions/argos/argos-example.yml">GitHub Actions Workflow</a></summary>

```yaml
strategy:
      fail-fast: false
      matrix:
        shard: [1, 2, 3] # run 3 parallel containers
# ...
- name: Orchestrated PW + Argos
  working-directory: ./argos
  env:
    ARGOS_PARALLEL: 1
    ARGOS_PARALLEL_TOTAL: -1 # important to set to -1 to enable "finalize" call.
    ARGOS_TOKEN: ${{ secrets.ARGOS_TOKEN }} 
    CURRENTS_PROJECT_ID: ${{ vars.CURRENTS_PROJECT_ID }}
    CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
  run: | # start Currents Orchestration
    npx pwc-p 
```

</details>

<details>

<summary><a href="https://github.com/currents-dev/currents-examples/blob/main/playwright/ci/github-actions/argos/currents.config.ts">Currents Configuration</a></summary>

{% code overflow="wrap" %}

```typescript
// currents.config.ts

import type { CurrentsConfig, OrchestrationStatus } from "@currents/playwright";
import { $ } from "execa";

// OrchestrationStatus has the latest status reported by Currents API - it contains data from all the machines participating in a run
async function onFinish(status: OrchestrationStatus) {
  // run `argos finalize` after all machines 
  if (status.specs.completed === status.specs.overall) {
    try {
      const finalize = await $`npx argos finalize`;
      console.log(finalize.stderr);
    } catch (e) {
      console.error(e);
    }
    return;
  }
}

const config: CurrentsConfig = {
  recordKey: assertEnvVariable("CURRENTS_RECORD_KEY"),
  projectId: assertEnvVariable("CURRENTS_PROJECT_ID"),
  ciBuildId: `${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT}`,
  orchestration: {
    skipReporterInjection: true, // mandatory for integration with Argos
    onFinish, // mandatory step for finalizing Argos Build
  },
};

export default config;


function assertEnvVariable(name: string) {
  if (!process.env[name]) {
    throw new Error(`Missing environment variable ${name}`);
  }
  return process.env[name];
}
```

{% endcode %}

* set `orchestration.skipReporterInjection` to `true`
* note the use of `onFinish` lifecycle hook - the corresponding function will run and receive `OrchestrationStatus` object that can be used to determine run's completion

</details>

### Applitools, Percy and other visual testing tools

You can use the same concept to send a "finalize" command to other visual testing tools like Applitools and Percy.

* Applitools - refer to [Closing the Batch](https://applitools.com/docs/eyes/concepts/test-execution/parallel-test-suites#step-3-closing-the-batch) section the Parallel Test Suites guide
* Percy - refer to `percy build:finalize` step in [Percy documentation](https://www.browserstack.com/docs/percy/integrate/parallel-test-suites)


# Playwright Annotations

Using Playwright Annotations to enhance reporting to Currents dashboard

{% hint style="info" %}
Requires `@currents/playwright` 1.5.0+
{% endhint %}

[Playwright Annotations](https://playwright.dev/docs/test-annotations) is a flexible way to add additional information about tests, like:

* ownership information
* metadata
* links to external resources (Jira ticket, GitHub issue)
* notes

Together with [Playwright Tags](/guides/playwright-tags) it allows augmenting your testing suite with metadata for easier managing, better reporting and improved integrations.

You can add an annotation to a test by:

* adding `annotations` object to `test` definition or
* calling `testInfo.annotations.push`

For example:

```typescript
test("annotated test", {
    annotation: {
      type: "issue",
      description: "https://github.com/microsoft/playwright/issues/23180",
    },
}, async ({ page }, testInfo) => {
  testInfo.annotations.push({
    type: "note",
    description: "This is a note",
  });

  testInfo.annotations.push({
    type: "jira",
    description: "https://jira.company.io/ticket/JIRA-123",
  });

  testInfo.annotations.push({
    type: "owner",
    description: "johnsmith",
  });
});
```

Currents shows the annotations for the test:

<figure><img src="/files/EMKUy5eaMGKeVzVZDhZe" alt=""><figcaption><p>Playwright annotations in Currents</p></figcaption></figure>

## Limitations

Currents applies the following rules when parsing annotations:

* types: `skip, fixme, fail, slow` are reserved by Playwright
* `32` max distinct annotations per test, extra annotations will be removed (sorted by the order of appearance)
* `type` field is limited to `256` characters, the values are trimmed and truncated to the max length
* `description` field is limited to `2048` characters, the values are trimmed and truncated to the max length
* If `type` is empty after trimming, the annotation is ignored

## Source and Deduplication

Annotations can originate from test case definition or at runtime from test execution attempt.

* Currents deduplicates annotations with exactly the same type, description and source.
* Currents removes attempt-level annotation if there's an equivalent test-case annotation

## Annotation: Test Owner

While Currents displays all the annotations related to a test, some annotation have a special meaning, for example - test owner.

To designate an owner of a test, add annotation with `type: owner`, for example:

```
testInfo.annotations.push({
  type: "owner",
  description: "johnsmith",
});
```

The value will appear in various areas of the dashboard so that your team can quickly identify the who owns the test.

<figure><img src="/files/392E1fGOMKqdzCkmsHrn" alt=""><figcaption><p>Showing test owner using annotations in Currents</p></figcaption></figure>

## Annotation: Slack Notifications

The documentation migrated to [Slack App](/resources/integrations/slack/slack-app#annotation-based-mentions)

## Annotation: Custom Metrics

{% hint style="info" %}
Custom metric is an experimental feature. We are gathering feedback to refine and improve it.
{% endhint %}

#### Recording Custom Metrics

Annotation of type `currents:metric` allows tracking arbitrary metrics associated with your tests, for example:

* page performance
* accessibility score
* memory consumption
* network response timing

Use annotation `type` of `currents:metric` and a serialized JSON object in `description` to define a metric. For example:

{% code overflow="wrap" %}

```typescript
{
  type: "currents:metric",
  description: JSON.stringify({
    "name": "memory_usage", 
    "value": 540.3, 
    "type": "float",
    "unit": "mb"
  }),
}
```

{% endcode %}

The JSON string must contain `name` and `value`. And optionally can contain `type` and `unit` .

<table><thead><tr><th width="146.32421875">Parameter</th><th width="106.8671875">Type</th><th>Description</th></tr></thead><tbody><tr><td>name<mark style="color:red;">*</mark></td><td>string</td><td>The name of the metric you want to track.</td></tr><tr><td>value<mark style="color:red;">*</mark></td><td>number</td><td>The current value of the metric you want to track.</td></tr><tr><td>type</td><td>enum</td><td>The value type. Values: <code>float</code>, <code>integer</code>. Default: <code>float</code></td></tr><tr><td>unit</td><td>enum</td><td>The unit to show in the dashboard. Values: <code>none</code>, <code>ms</code>, <code>s</code>, <code>%</code>, <code>b</code> , <code>kb</code> , <code>mb</code> , <code>gb</code> Default: <code>none</code></td></tr></tbody></table>

For example, the following test captures page load time as a custom metric metrics:

```typescript
test("performance test example", async ({ page }) => {
  await page.goto(`https://example.com`);
  const [performanceTiming] = await page.evaluate(() => {
    const [timing] = performance.getEntriesByType(
      "navigation"
    ) as PerformanceNavigationTiming[];
    return [timing];
  });
  // Get the start to load event end time
  const startToLoadEventEnd =
    performanceTiming.loadEventEnd - performanceTiming.startTime;
    
  // Add the custom metric to the annotations
  test
    .info()
    .annotations.push({
      type: "currents:metric",
      description: JSON.stringify({
        name: "page-performance",
        value: startToLoadEventEnd,
        type: "float",
        unit: "ms",
      }),
    });
});
```

#### Browsing Custom Metrics

The custom metrics are available in [Test Results](/dashboard/analytics/test-results) chart. Use "Custom Metric" control to browse the available metrics and aggregation functions.

<div data-with-frame="true"><figure><img src="/files/KeW9Rb0VuXbro5BlTbiH" alt=""><figcaption><p>Custom metric selection</p></figcaption></figure></div>


# Playwright Tags

How to tag Playwright executions in Currents

{% hint style="info" %}
**Note**

* Run-level tagging is available in [@currents/playwright](/resources/reporters/currents-playwright) version **0.7.0+**
* Project-level and test-level tagging is available in [@currents/playwright](/resources/reporters/currents-playwright) version **0.10.0+**
  {% endhint %}

{% hint style="info" %}
A tag is limited to 128 characters
{% endhint %}

Using tags is a common technique for better classifying recorded test results and getting relevant insights about the test suite. Here are several examples of how software teams use tags:

* manage ownership - e.g. use the team name as a tag
* categorize product features - e.g. tagging `onboarding` flow tests
* manage tests lifecycle - e.g. tag newly introduced tests as `ustable`

The tags are available for producing meaningful reports, exploring metrics, narrowing down Slack notifications, filtering the results, API responses and more.

<figure><img src="/files/C4R4l6chzjfxQfCjk2fb" alt=""><figcaption><p>Example of using Tags for narrowing down Flakiness chart in Currents Dashboard</p></figcaption></figure>

### Playwright Tags

{% hint style="info" %}
[@currents/playwright](/resources/reporters/currents-playwright) version **0.10.0+** is required for test title tags
{% endhint %}

#### Test title tags

Currents parses the test titles and recognizes the conventional [Playwright Tags](https://playwright.dev/docs/test-annotations#tag-tests) that appear in test definitions. For example, recording the results of the following tests to Currents:

```typescript
test('Test login page @tagA', async ({ page }) => {
  // ...
});

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

...will create a run with tags: **`tagA`** and **`tagB`**

<figure><img src="/files/FXIjkwlKMzk9U18q4VQK" alt=""><figcaption><p>Example of Currents run created with tags @fast and @slow</p></figcaption></figure>

#### Test group tags

Tagging a test group (`test.describe`) will "apply" the tag to every included individual test, as well as to the created run. For example, given the following test definition:

```typescript
test.describe("test group @run", () => { // 👈🏻 note the test group tag

  test('Test login page @tagA', async ({ page }) => {
    // ...
  });
  test('Test full report @tagB', async ({ page }) => {
    // ...
  });
})
```

Currents will assign the following tags to the created items:

<table><thead><tr><th>Item</th><th>Tags</th></tr></thead><tbody><tr><td>Run</td><td><code>run</code>, <code>tagA</code>, <code>tagB</code></td></tr><tr><td><pre><code>Test login page @tagA
</code></pre></td><td><code>run</code>, <code>tagA</code></td></tr><tr><td><pre><code>Test full report @tagB
</code></pre></td><td><code>run</code>, <code>tagB</code></td></tr></tbody></table>

<figure><img src="/files/qHSlUoQDoqhPLMMS4dmp" alt=""><figcaption><p>Example of a run created with various tags when tagging a test group</p></figcaption></figure>

#### Tags with `--grep` applied

If certain tags are excluded from the execution, for example by using `--grep` CLI option, only the included tests (and their tags) will be used for tagging.

```
$ npx playwright test --grep @coverage
```

<figure><img src="/files/L1HlljTRFQ6yUy3UIqv3" alt=""><figcaption><p>Applying tags when certain tests are excluded using --grep CLI option</p></figcaption></figure>

#### Removing tags from test titles

It is often desired to ignore the tags included in the test title to have a consistent view of the test history or preserve the metrics.

For example, let's say you have a test named `Test login page @slow` , eventually, you add another tag and the test title becomes `Test login page @slow @login`. However, adding the tag will change the test name - as a result, the history of previous executions and metrics will be lost.

To remove the tags from the recorded test titles, add `--pwc-remove-title-tags` CLI option or `removeTitleTags` reporter configuration. Activating the removal will strip the tags from test titles (including test group names) when recording to Currents dashboard.

In the example above, `Test login page @slow` and `Test login page @slow @login` will be recorded as `Test login page` and tags `slow` + `login` will be attached to the test recording.

#### Disabling parsing test title tags

You can disable parsing test title tags altogether by adding `--pwc-disable-title-tags` CLI option. See [@currents/playwright](/resources/reporters/currents-playwright) for additional configuration options, available in versions `0.11.0+` .

### Run-level Tags

{% hint style="info" %}
[@currents/playwright](/resources/reporters/currents-playwright) version **0.7.0+** is required to use run-level tags
{% endhint %}

In addition to encoding tags in test titles, you can explicitly tag the whole run (or a playwright project). There are multiple ways to explicitly tag a run.

#### Tagging a run using `pwc` CLI option

If you're using `pwc` executable script to run the tests, use `--tag` CLI option:

```
npx pwc --tag tagA,tagB --tag tagC
```

You can provide a comma-separated list of tags, provide multiple `--tag` options, or use both.

#### Tagging a run using Reporter configuration

You can tag playwright execution by providing a list of `tag` values to Currents Reporter in your `playwright.config.ts` file. For example:

```typescript
import { currentsReporter } from '@currents/playwright';

// ...
reporter: [
  currentsReporter({
    ciBuildId: process.env.CURRENTS_CI_BUILD_ID,
    recordKey: process.env.CURRENTS_RECORD_KEY,
    projectId: process.env.CURRENTS_PROJECT_ID,
    tag: ["runTagA", "runTagB"],
  }),
  /* other reporters, if exist, e.g.:
  ["html"]
  */
]
```

#### Tagging a run using `CURRENTS_TAG` environment variable

You can tag playwright execution by setting the `CURRENTS_TAG` environment variable value to a comma-separated list of tags, for example, with [@currents/playwright](/resources/reporters/currents-playwright) reporter configured:

```
CURRENTS_TAG=tagA,tagB npx playwright run ...
```

#### Precedence of configuration options

If there are multiple definitions of run-level tags, Currents will pick the tags as follows:

* Use comma-separated tags of `CURRENTS_TAG` environment variable, if provided; otherwise
* Use `--tag` CLI option values, if provided; otherwise
* Use reporter configuration values, if provided; otherwise
* add no run tags

### Project-level Tags

{% hint style="info" %}
[@currents/playwright](/resources/reporters/currents-playwright) version **0.10.0+** is required for project-level tags
{% endhint %}

You can tag Playwright projects by using the **`metadata.pwc.tags`** field in a project's configuration. Tags defined here are attached to every test recording, spec file, and group that belongs to that project, and they bubble up to the run level as well.

For example, given the following Playwright configuration with two browser projects:

```typescript
// playwright.config.ts

// ...
{
   projects: [
      {
        name: "Desktop Chrome",
        metadata: {
          pwc: {
            tags: ["project:chrome"], // 👈🏻 project-level tags
          },
        },
        use: {
          ...devices["Desktop Chrome"],
        },
      },
      {
        name: "Desktop Firefox",
        metadata: {
          pwc: {
            tags: ["project:firefox"], // 👈🏻 project-level tags
          },
        },
        use: {
          ...devices["Desktop Firefox"],
        },
      },
  ]
}
```

Currents will create a run tagged with `project:chrome`, `project:firefox`, plus all tags extracted from individual tests.

<figure><img src="/files/1plFZg6FtIUZJogqzKCA" alt=""><figcaption><p>Example of a run with project-level tags <code>project:chrome</code> and <code>project:firefox</code></p></figcaption></figure>

{% hint style="info" %}
The `project:{name}` format shown above (e.g. `project:chrome`, `project:firefox`) is a naming convention, not an automatic feature. Currents does not auto-generate tags from project names — you define whatever tag values make sense for your team in `metadata.pwc.tags`. Using a `project:` prefix can make project-level tags easier to distinguish from test-title tags or run-level tags when filtering results in the dashboard.
{% endhint %}

### How Tags are Applied

Currents stores the recorded results as Runs, Groups, Spec Files and Tests. The items are available in the dashboard and also in [API](https://docs.currents.dev/api/) responses.

* Run - is a high-level abstraction that represents a CI execution of a test suite
* Group - is a subset of recorded tests - representing a playwright project
* Spec File - a recorded execution of tests in a file
* Test Recording - a recorded execution of a test case

Each of the items can have multiple tags attached, and tagging a particular item can affect the tags of another item. When applying tags, Currents follows the rules below:

* Apply explicit run-level and project-level tags "downwards" to all the included items
* Apply individual test tags "upwards" to spec files, projects and runs

The table below shows the details of how the tags are applied:

<table><thead><tr><th width="225">Item</th><th>Tags Applied</th></tr></thead><tbody><tr><td>Run</td><td><ul><li>Own run-level tags</li><li>Tags of all the included projects</li><li>Tags of all the included test cases</li></ul></td></tr><tr><td>Group/Project</td><td><ul><li>Run-level tags</li><li>Own project-level tags</li><li>Tags of all the included test cases</li></ul></td></tr><tr><td>Spec File Recording</td><td><ul><li>Run-level tags</li><li>Project-level tags</li><li>Tags of all the included test cases</li></ul></td></tr><tr><td>Test Case Recording</td><td><ul><li>Run-level tags</li><li>Project-level tags</li><li>Own test title tags</li></ul></td></tr></tbody></table>

For example, given the following tests:

```typescript
test('Test login A @tagA', async ({ page }) => {
  // ...
});
test('Test login B @tagB', async ({ page }) => {
  // ...
});
```

And adding a run-level tag `runTag01` using the command: `pwc ... --tag runTag01` will result in the following tags:

<figure><img src="/files/fl3LoZhtnEH5EEDu0l8b" alt=""><figcaption><p>Application of tags example</p></figcaption></figure>

<table><thead><tr><th>Item</th><th>Applied Tags</th></tr></thead><tbody><tr><td>Run</td><td><code>runTag01</code>, <code>tagA</code>, <code>tagB</code></td></tr><tr><td><pre><code>Test login A
</code></pre></td><td><code>runTag01, tagA</code></td></tr><tr><td><pre><code>Test login B
</code></pre></td><td><code>runTag01, tagB</code></td></tr></tbody></table>


# Environments

How to label and filter Currents runs by environment (e.g. staging, production)

{% hint style="info" %}
**Availability**

* Setting an environment is available in [@currents/playwright](/resources/reporters/currents-playwright) version **2.1.0+**.
* Filtering by environment in the Dashboard ([Runs](/dashboard/runs) + [Analytics](/dashboard/analytics)) and the REST [API](https://docs.currents.dev/api/) is available for all projects.
  {% endhint %}

An **environment** is a label that describes *where* or *under which conditions* a test run was executed — for example `staging`, `production`, `preview`, or a CI matrix dimension such as a target region or device pool. Attaching an environment lets you compare and filter results across deployment targets without mixing them into the same metrics.

Common uses:

* Separate **staging** vs **production** smoke runs in the same project.
* Compare stability of the same suite across regions (e.g. `us-east`, `eu-west`).
* Slice [Analytics](/dashboard/analytics) (run status, duration, flakiness, test results) by deployment target.

<figure><img src="/files/vnUhaAKp5FCpevxmlzH4" alt=""><figcaption><p>Run with multiple group-level environments: production, staging </p></figcaption></figure>

## Environments vs. Tags

Both classify runs, but they serve different purposes:

|             | Environment                                 | [Tags](/guides/playwright-tags)                     |
| ----------- | ------------------------------------------- | --------------------------------------------------- |
| Cardinality | One value per run or per Playwright project | Many values per run/group/test                      |
| Intent      | *Where* the tests ran (deployment target)   | Arbitrary classification (feature, team, lifecycle) |
| Source      | Reporter config / project metadata          | Test titles, project metadata, run config           |

A run can still end up with **multiple environments** when different Playwright projects within the same run set different values — see [How environments aggregate to a run](#how-environments-aggregate-to-a-run) below.

## Setting the environment

The environment is a **run-level** value, with an optional **per-project** override. It can be provided through any of the standard [configuration sources](/resources/reporters/currents-playwright/configuration).

### `currents.config.ts`

```typescript
import type { CurrentsConfig } from "@currents/playwright";

const config: CurrentsConfig = {
  recordKey: process.env.CURRENTS_RECORD_KEY ?? "",
  projectId: process.env.CURRENTS_PROJECT_ID ?? "",
  environment: process.env.DEPLOY_ENV ?? "staging",
};

export default config;
```

### `CURRENTS_ENVIRONMENT` environment variable

```bash
CURRENTS_ENVIRONMENT=production npx playwright test
```

### `--pwc-environment` CLI option

Supported by `pwc`, `pwc-p discover`, and `pwc-p run`:

```bash
npx pwc --pwc-environment staging
```

### Inline reporter option

```typescript
// playwright.config.ts
import { currentsReporter } from "@currents/playwright";

export default defineConfig({
  reporter: [
    currentsReporter({
      recordKey: process.env.CURRENTS_RECORD_KEY,
      projectId: process.env.CURRENTS_PROJECT_ID,
      environment: "staging",
    }),
  ],
});
```

### Per-project override

Set `metadata.pwc.environment` on a Playwright project to override the run-level environment for that project only:

```typescript
// playwright.config.ts
export default defineConfig({
  projects: [
    {
      name: "chromium",
      metadata: { pwc: { environment: "staging" } }, // 👈 per-project
      use: { ...devices["Desktop Chrome"] },
    },
    {
      name: "firefox",
      metadata: { pwc: { environment: "production" } }, // 👈 per-project
      use: { ...devices["Desktop Firefox"] },
    },
  ],
});
```

### Precedence of configuration options

When the environment is defined in more than one place, Currents resolves the value as follows (highest priority first):

* **Per-project** `projects[].metadata.pwc.environment`, if set for the project;&#x20;
* Otherwise the run-level value:
  * `CURRENTS_ENVIRONMENT` environment variable, if provided; otherwise
  * `--pwc-environment` CLI option, if provided; otherwise
  * `environment` from the inline reporter options in `playwright.config.ts`; otherwise
  * `environment` from `currents.config.ts`; otherwise
  * no environment is attached.

## How environments aggregate to a run

The environment is resolved **per Playwright project** and attached to the corresponding group when results are reported. At the run level, Currents collects the distinct environments from all groups into a list.

For the per-project example above, the resulting run is associated with **both** `staging` and `production`, and shows up when filtering by either value:

| Item             | Environment             |
| ---------------- | ----------------------- |
| Run              | `staging`, `production` |
| Group `chromium` | `staging`               |
| Group `firefox`  | `production`            |

If every project shares the same value (or you only set a run-level value), the run is associated with that single environment.

## Filtering in the Dashboard

Once runs carry an environment, an **Environment** filter is available in the [Runs](/dashboard/runs) and across [Analytics](/dashboard/analytics). Selecting one or more environments narrows every metric on the page to runs that ran in those environments.

## Filtering via the REST API

Both the runs and insights endpoints accept an `environments[]` query parameter (repeat it to pass multiple values). Runs that match **any** of the supplied environments are returned.

See the [API](https://docs.currents.dev/api/) reference for the full list of query parameters.


# Troubleshooting

Troubleshooting Playwright integration with Currents

If you are experiencing issues with using `@currents/playwright`, enable debug mode to collect more information about the failure and submit a support request via our support channels.

{% hint style="info" %} <mark style="color:yellow;">**TL;DR share the following information**</mark>

Collect environment information

* Package Versions
* Currents Run ID or Dashboard URL associated with the issue
* Screenshots or video recordings if applicable
* Full error message, including the stack trace, if available
* Full and relevant CI execution logs with sensitive information redacted
* CI pipeline configuration
  * The exact commands used during the execution
  * Relevant configuration of the CI setup stages

\
Collect and share the debug logs

* `npx pwc --pwc-debug=full ...` OR
* `npx pwc-p --pwc-debug=remote ...` OR
* `DEBUG=currents* playwright test ...`
  {% endhint %}

### 1. Collecting Environment Information

Please collect the following information to help us effectively debug the problem:

* The associated dashboard Run URL
* Screenshots if applicable
* Your setup method and configuration files
* The exact command used to run playwright
* Environment information (use the command below)

Use the following command to print information about your CI environment

```bash
npx envinfo --system --binaries --browsers --npmPackages --duplicates --npmGlobalPackages
```

### 2. Activate Debug Mode

{% hint style="warning" %}
Capture and share the **full** debug log - that will help the support person identify the root cause faster
{% endhint %}

`@currents/playwright` simplifies collecting the debug information by automatically uploading the logs to Currents.

To enable uploading the debug logs:

* For `pwc` command-line executable run `pwc --pwc-debug=full` OR
* For `pwc-p` run `pwc-p --pwc-debug=full` OR
* Set environment variable `DEBUG=currents* playwright test...`

`--pwc-debug` enables uploading the debug logs to our servers (see [pwc-p run](/resources/reporters/currents-playwright/pwc-p/pwc-p-run#debugging--output) documentation):

* `remote` uploads the debug logs to Currents servers;
* `full` prints the logs to stdout and also upload them to Currents.

For example:

{% tabs %}
{% tab title="pwc" %}

```bash
npx pwc --pwc-debug=full ...
```

{% endtab %}

{% tab title="pwc-p" %}

```
npx pwc-p --pwc-debug=full ...
```

{% endtab %}

{% tab title="Environment variable" %}

```
# on Linux
CURRENTS_PROJECT_ID=PROJECT_ID \ // the projectId from https://app.currents.dev
CURRENTS_RECORD_KEY=RECORD_KEY \ // the record key from https://app.currents.dev
CURRENTS_CI_BUILD_ID=hello-currents \ // a unique CI build ID
CURRENTS_DEBUG=full \
npx playwright test

# on Windows
## - set the environment variables first
cmd /V /C ^
set CURRENTS_DEBUG=full ^
set CURRENTS_PROJECT_ID=project_id&& ^
set CURRENTS_RECORD_KEY=record_key&& ^
set CURRENTS_CI_BUILD_ID=unique_build_id

## - the run the command
npx playwright test ...
```

{% endtab %}
{% endtabs %}

When enabled, the debug logs will be uploaded to Currents servers and a confirmation message will be shown after the run's completion, for example:

<figure><img src="/files/lfHPtXok0ixHX6nx8vSL" alt=""><figcaption><p>Remote debug logs notification example</p></figcaption></figure>

## CI Link Issues

### Problem: CI link is missing or incorrect in the dashboard

Currents displays a link to the CI job/run where the tests were executed. If this link is missing or incorrect:

**Possible causes:**

1. **Auto-detection failed** — Your CI provider environment variables are not available in the test environment (e.g., inside a Docker container, custom runner, or self-hosted CI)
2. **Custom CI system** — Your CI provider is not automatically recognized by Currents
3. **URL override needed** — You need to manually specify the CI URL

**Solution:**

Set the `CURRENTS_CI_URL` environment variable to provide the correct CI job/run URL:

```bash
# GitHub Actions example
export CURRENTS_CI_URL="https://github.com/my-org/my-repo/actions/runs/$GITHUB_RUN_ID"

# GitLab CI example
export CURRENTS_CI_URL="$CI_JOB_URL"

# Jenkins example
export CURRENTS_CI_URL="$BUILD_URL"

# Custom CI system
export CURRENTS_CI_URL="https://ci.mycompany.com/builds/run-123"
```

For more details on `CURRENTS_CI_URL`, see [Configuration](/resources/reporters/currents-playwright/configuration).


# Projects


# Projects Summary view

Customize how you visualize projects on the Projects page

Currents enables you to create multiple projects to better organize your test pipeline. Each project consolidates test runs and their associated metrics, identified by unique IDs that seamlessly integrate with your CI environment. Leverage features to easily visualize, configure, and archive each project.

Customize project settings within the default Projects Summary view by adjusting the lookback period and applying the following filters to suit your preferences.

* **Dates**: Filter project data for up to the last 30 days.
* **Tags:** Filter [Tags](/guides/playwright-tags) associated with the test runs in your projects.
* **Author**: Use this filter to see projects based on contributions from specific team members, which can be useful for performance reviews or tracking individual contributions.
* **Branches**: Filter projects based on the branches within your version control system.

Once you’ve configured the view, save the settings to maintain your customized view for future sessions.

{% embed url="<https://www.loom.com/share/aca843df76464339a2d8201ac9aa0676?hideEmbedTopBar=true&hide_title=true>" %}
Customizable Project Summary View
{% endembed %}


# Project Settings

Fine-tune your project settings

After creating a project, you can modify its settings by navigating to **Manage Project > Settings** on the left menu.

Below are the settings available and their descriptions:

* **Project ID**: This ID is immutable and cannot be edited, but you can copy the Project ID to include it in your Continuous Integration (CI) settings.
* **Project Name**: It can be edited at any time to reflect the nature or stage of your project.
* **Time Out Minutes**: The duration (in minutes) after which a run will timeout if it hasn't been completed. Adjust this setting based on your tests' complexity and expected duration to avoid premature terminations or unnecessary waiting times. Read more on [Run Timeouts](/dashboard/runs/run-timeouts).
* **Default Branch Name**: The name of the branch that will be used as a reference when presenting [Analytics](/dashboard/analytics). E.g:
  * The change in coverage is measured compared to the default branch.
  * Skipped tests report is measured based on the results from the default branch.
  * Increase in runs duration is counted from the default branch only.
* **Enable** [**Fail Fast Strategy**](/guides/ci-optimization/fail-fast-strategy): configure the project to stop a test run when the first test failure is detected. It provides faster feedback during testing cycles, saving time and resources by halting runs that are likely to fail.
* **Run Title Source**
  * Auto Mode: use GitHub Pull Request title if available, otherwise use commit message
  * Commit Message: always use commit message
* **Parallel Execution Strategy**: It defines how Currents prioritizes and executes test spec files when running tests in `--parallel` mode, either based on Failure rate or Expected duration. For detailed information, refer to the [Load Balancing documentation](https://chatgpt.com).

Through the Project Settings, you can also delete or archive the project. Deleting a project permanently removes it and all associated data, and this action cannot be undone, so proceed with caution. If you need this project data in the future, opt for the [archiving feature](/dashboard/projects/archive-and-unarchive-projects), which allows you to recover the project later.


# Archive and Unarchive Projects

Feature to better manage and visualize projects

Archiving projects on the Currents Dashboard allows you to temporarily set aside projects while retaining access to essential data and test results associated with those projects.

On the organization's main page on Currents Dashboard, you can view and manage all the projects associated with your organization. This feature is crucial when you need to manage a large number of projects within your organization, some of which may not be actively in use for a while.

{% embed url="<https://www.loom.com/share/9854b4b5abb54e01b4ca50d4d43322f6?hideEmbedTopBar=true&hide_title=true>" %}
Archiving a Project on Currents
{% endembed %}

Archiving and unarchiving projects is a way to keep your workspace organized and decluttered by moving less active projects out of sight while still being able to access and work on them when necessary. It ensures you can focus on what's currently in progress and easily find and manage older or less active projects when needed.


# Runs


# Run Details

Run details and metadata - git, environment, status

## Run Status

A run can have the following status:

* <mark style="color:orange;">**Running**</mark> - the default state for newly created runs
* <mark style="color:red;">Failing</mark> - a run still hasn't reported all the results and has 1 or more failed tests
* <mark style="color:red;">**Failed**</mark> - a run has reported all the results and has 1 or more failed tests
* <mark style="color:blue;">**Passed**</mark> - a run has reported all the results and has 0 failed tests.

In addition, an interrupted run can be in one of the following completion states:

* **👤 Cancelled** - a run was cancelled. See [Cancelling Runs](/dashboard/runs/cancel-run) for details.
* **⚡️ Cancelled** - a run was cancelled due to the [Fail Fast](/guides/ci-optimization/fail-fast-strategy) strategy. See
* **Timeout** - a run exceeded the timeout threshold for the project. See [Run Timeouts](/dashboard/runs/run-timeouts)for details.

## Run Title

Currents uses the following data for displayed run title:

* Pull Request title if the run is associated with a PR
* Git Commit Message if `.git` is available
* `No title` placeholder otherwise

You can override Run Title by setting `COMMIT_INFO_MESSAGE` environment variable. See [Commit Information](/dashboard/runs/commit-information).

<figure><img src="/files/vqPtYjXcLQ7cQY46V2FJ" alt=""><figcaption><p>Run details example</p></figcaption></figure>

Currents collects additional information about the CI environment:

| Field                | Description                                                                                                                                            |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Duration             | Run duration                                                                                                                                           |
| Progress             | Completed / overall spec files progress                                                                                                                |
| Started at           | Run start timestamp                                                                                                                                    |
| Branch               | Git branch name (or HEAD for Pull Requests)                                                                                                            |
| Commit Message + SHA | Git commit details                                                                                                                                     |
| Browser / Project    | Cypress tests browser or Playwright Project                                                                                                            |
| Author               | Git commit author                                                                                                                                      |
| CI Build ID          | [CI Build ID](/guides/parallelization-guide/ci-build-id)                                                                                               |
| CI Provider Link     | Auto-detected or custom CI job/run URL. Set `CURRENTS_CI_URL` to override. See [Configuration](/resources/reporters/currents-playwright/configuration) |




---

[Next Page](/llms-full.txt/1)

