> For the complete documentation index, see [llms.txt](https://argos-ci.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://argos-ci.com/docs/sdks-reference/cypress.md).

# Cypress

Boost your visual testing capabilities by combining Argos with your [Cypress](https://www.cypress.io/) tests.

While Cypress inherently provides screenshot functionality, the Argos Cypress integration enhances this by:

* Ensuring all images are fully loaded.
* Ensuring all fonts are rendered.
* Confirming the absence of any `aria-busy` (loading) elements on the page.
* Concealing scrollbars.
* Obscuring text cursors or carets.
* Providing CSS utilities to simplify content hiding.
* Gives you visility on test failures.

### Get started

Please refer to our [Quickstart guide](/docs/quickstart/cypress-quickstart.md) to get started with Argos and Cypress.

### Set a Preview URL

Argos displays the URL of the page when a screenshot is taken, helping you understand the screenshot’s context in the Argos UI. If you run tests locally and deploy your pull requests (PRs) to a preview URL, you can link the two by setting the `ARGOS_PREVIEW_URL` environment variable or configuring the `previewUrl` option in the Cypress configuration.

#### Example Configuration

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

```ts
const { defineConfig } = require("cypress");
const { registerArgosTask } = require("@argos-ci/cypress/task");

module.exports = defineConfig({
  e2e: {
    async setupNodeEvents(on, config) {
      registerArgosTask(on, config, {
        uploadToArgos: !!process.env.CI,
        previewUrl: {
          baseUrl: "https://my-site.com", // Use a dynamic value here for different environments if needed.
        },
      });
    },
  },
});
```

{% endcode %}

### Setup individual Cypress events

Cypress only supports one handler per event. If you need to set up other handlers for the same event, you can call the individual functions provided by the SDK.

{% code title="" %}

```ts
const { defineConfig } = require("cypress");
const {
  argosAfterScreenshot,
  argosAfterRun,
} = require("@argos-ci/cypress/task");

module.exports = defineConfig({
  // setupNodeEvents can be defined in either
  // the e2e or component configuration
  e2e: {
    async setupNodeEvents(on, config) {
      const argosConfig = {
        uploadToArgos: !!process.env.CI,
      };

      on("after:screenshot", async (details) => {
        // Your custom logic...

        return argosAfterScreenshot(config, details, argosConfig);
      });

      on("after:run", async (results) => {
        // Your custom logic...

        return argosAfterRun(config, results, argosConfig);
      });
    },
  },
});
```

{% endcode %}

### API Overview

#### cy.argosScreenshot(\[name]\[, options])

* `name`: Unique name for the screenshot.
* `options`: Explore [cy.screenshot command options](https://docs.cypress.io/api/commands/screenshot) for details.
* `options.element`: Use an ElementHandle or string selector to capture a specific element's screenshot.
* `options.viewports`: Define specific viewports for capturing screenshots. More on [viewports configuration](/docs/learn/how-to-guides/visual-coverage/responsive-viewports.md).
* `options.argosCSS`: Specific CSS applied during the screenshot process. More on [injecting CSS](/docs/learn/how-to-guides/visual-coverage/injecting-css.md)
* `options.threshold`: Sensitivity threshold between 0 and 1. The higher the threshold, the less sensitive the diff will be. Default to `0.5`.
* `options.stabilize`: Wait for the UI to stabilize before taking the screenshot. Set to `false` to disable stabilization. Pass an object to customize the stabilization. Default to `true`.
* `options.stabilize.disableSpellCheck`: Disable spell check before taking the screenshot. Default to `true`.
* `options.stabilize.fontAntialiasing`: Force font antialiasing. Default to `true`.
* `options.stabilize.hideCarets`: Hide text carets before taking the screenshot. Default to `true`.
* `options.stabilize.hideScrollbars`: Hide scrollbars before taking the screenshot. Default to `true`.
* `options.stabilize.loadImageSrcset`: Force the loading of images with `srcset` attributes when the viewport changes. Default to `true`.
* `options.stabilize.roundImageSize`: Round image sizes to the nearest integer. Default to `true`.
* `options.stabilize.stabilizeSticky`: Stabilize sticky and fixed elements by switching to `position: absolute`. Default to `true`.
* `options.stabilize.waitForAriaBusy`: Wait for the `aria-busy` attribute to be removed from the document. Default to `true`.
* `options.stabilize.waitForFonts`: Wait for fonts to be loaded. Default to `true`.
* `options.stabilize.waitForImages`: Wait for images to be loaded. Default to `true`.
* `options.tag`: Tag or array of tags to attach to the screenshot for filtering in Argos.

### Helper Attributes for Visual Testing

For tailored visual testing, the `data-visual-test` attributes provide control over how elements appear in Argos screenshots. This can be especially useful for obscuring or modifying elements with dynamic content, like dates.

* `[data-visual-test="transparent"]`: Renders the element transparent (`visiblity: hidden`).
* `[data-visual-test="removed"]`: Removes the element from view (`display: none`).
* `[data-visual-test="blackout"]`: Masks the element with a blackout effect.
* `[data-visual-test-no-radius]`: Strips the border radius from the element.

**Example: Using a helper attribute to hide a div from the captured screenshot:**

```html
<div id="clock" data-visual-test="transparent">...</div>
```

#### registerArgosTask(on, config\[, options])

* `on`: Cypress plugin events.
* `config`: Cypress config.
* `options`: All [upload parameters](https://js-sdk-reference.argos-ci.com/interfaces/UploadParameters.html).
* `options.uploadToArgos`: Upload results and create a build on Argos, `true` by default.

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

```ts
const { defineConfig } = require("cypress");
const { registerArgosTask } = require("@argos-ci/cypress/task");

module.exports = defineConfig({
  // setupNodeEvents can be defined in either
  // the e2e or component configuration
  e2e: {
    async setupNodeEvents(on, config) {
      registerArgosTask(on, config, {
        uploadToArgos: !!process.env.CI,
      });

      // include any other plugin code...
    },
  },
});
```

{% endcode %}

#### argosAfterScreenshot(config, details\[, options])

Cypress "after:screenshot" event handler.

* `config`: Cypress config.
* `details`: Screenshot details provided by Cypress.
* `options`: All [upload parameters](https://js-sdk-reference.argos-ci.com/interfaces/UploadParameters.html).
* `options.uploadToArgos`: Upload results and create a build on Argos, `true` by default.

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

```ts
const { defineConfig } = require("cypress");
const { argosAfterScreenshot } = require("@argos-ci/cypress/task");

module.exports = defineConfig({
  // setupNodeEvents can be defined in either
  // the e2e or component configuration
  e2e: {
    async setupNodeEvents(on, config) {
      on("after:screenshot", async (details) => {
        // Your custom logic...

        return argosAfterScreenshot(config, details, {
          uploadToArgos: !!process.env.CI,
        });
      });

      // include any other plugin code...
    },
  },
});
```

{% endcode %}

#### argosAfterRun(config, results\[, options])

Cypress "after:run" event handler.

* `config`: Cypress config.
* `results`: Run results provided by Cypress.
* `options`: All [upload parameters](https://js-sdk-reference.argos-ci.com/interfaces/UploadParameters.html).
* `options.uploadToArgos`: Upload results and create a build on Argos, `true` by default.

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

```ts
const { defineConfig } = require("cypress");
const { argosAfterRun } = require("@argos-ci/cypress/task");

module.exports = defineConfig({
  // setupNodeEvents can be defined in either
  // the e2e or component configuration
  e2e: {
    async setupNodeEvents(on, config) {
      on("after:run", async (results) => {
        // Your custom logic...

        await argosAfterRun(config, results, {
          uploadToArgos: !!process.env.CI,
        });
      });

      // include any other plugin code...
    },
  },
});
```

{% endcode %}

### Troubleshooting

#### Error while importing `@argos-ci/cypress/task` in `cypress.config.ts`

To address the `ts(1479)` error when importing `@argos-ci/cypress/task` in your `cypress.config.ts`, you have two main strategies:

{% stepper %}
{% step %}

### Update your `tsconfig.json`

Set `moduleResolution` to `"Bundler"`. This method leverages TypeScript's support for newer module resolution strategies, aligning with Node.js's `exports` feature used by Argos to distribute optimized SDKs.
{% endstep %}

{% step %}

### Suppress the error in `cypress.config.ts`

Add the line `// @ts-expect-error moduleResolution` right above the import statement. This tells TypeScript to expect an error at this line and ignore it, offering a quick workaround without adjusting your project's module resolution strategy.
{% endstep %}
{% endstepper %}

The first option is a more comprehensive solution, dealing with the TypeScript bug through adopting the new `moduleResolution: "Bundler"` setting, which is designed for such cases. The second option is simpler and quicker but bypasses the issue rather than solving it at its core.

#### Viewports option not working

When running Cypress in headless mode, the [Cypress.viewport](https://docs.cypress.io/api/commands/viewport) command (used internally by `@argos-ci/cypress`) may not behave as expected. This is because headless browsers don’t render a visible viewport, which can result in incorrect or inconsistent screenshots.

To ensure a consistent viewport size, configure it via `setupNodeEvents` in your `cypress.config.js`. This approach sets the viewport before the browser launches, avoiding visual regressions.

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

```ts
import { defineConfig } from "cypress";

export default defineConfig({
  // setupNodeEvents can be defined in either
  // the e2e or component configuration
  e2e: {
    setupNodeEvents(on, config) {
      on("before:browser:launch", (browser, launchOptions) => {
        if (browser.name === "chrome" && browser.isHeadless) {
          // fullPage screenshot size is 1400x1200 on non-retina screens
          // and 2800x2400 on retina screens
          launchOptions.args.push("--window-size=1400,1200");

          // force screen to be non-retina (1400x1200 size)
          launchOptions.args.push("--force-device-scale-factor=1");

          // force screen to be retina (2800x2400 size)
          // launchOptions.args.push('--force-device-scale-factor=2')
        }

        if (browser.name === "electron" && browser.isHeadless) {
          // fullPage screenshot size is 1400x1200
          launchOptions.preferences.width = 1400;
          launchOptions.preferences.height = 1200;
        }

        if (browser.name === "firefox" && browser.isHeadless) {
          // menubars take up height on the screen
          // so fullPage screenshot size is 1400x1126
          launchOptions.args.push("--width=1400");
          launchOptions.args.push("--height=1200");
        }

        return launchOptions;
      });
    },
  },
});
```

{% endcode %}

Reference: [Cypress Docs – Set screen size when running headless](https://docs.cypress.io/api/node-events/browser-launch-api#Set-screen-size-when-running-headless)

### Additional Resources

* [Quickstart with Argos + Cypress](/docs/quickstart/cypress-quickstart.md)
* [Example of Argos + Cypress](https://github.com/argos-ci/argos-javascript/tree/main/examples/cypress)
* [@argos-ci/cypress on GitHub](https://github.com/argos-ci/argos-javascript/tree/main/packages/cypress)
* [@argos-ci/cypress on npm](https://www.npmjs.com/package/@argos-ci/cypress)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://argos-ci.com/docs/sdks-reference/cypress.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
