ScreenshotNeo

BlogGuides

Cypress Test Automation: A Practical Guide

Install Cypress, choose the right test layer, write independent browser tests, and run them reliably in CI with practical examples and fixes.

By the ScreenshotNeo team4 October 20267 min read

How do I get started with Cypress test automation? Install Cypress as a development dependency, choose end-to-end or component testing in its guided setup, and build a suite from independent tests that match the risks you need to cover. Use end-to-end tests for critical journeys across the application, component tests for isolated UI behavior, API tests for backend behavior, and accessibility checks as an additional layer. A passing result at one layer does not prove the whole product works.

1. Choose the right Cypress test type

Choose the narrowest layer that answers the question. Broader tests cover more integrated behavior but require more setup and infrastructure. Cypress documents end-to-end, component, API, and accessibility testing as complementary options. Cypress testing types

Type Use it for What a pass does not prove
End-to-end (E2E) Critical user journeys such as sign-in, checkout, persisted state across screens, and pre-deployment smoke checks. It does not cover every state or edge case, and it costs more to set up and maintain than focused tests.
Component Isolated UI states and interactions: forms, date pickers, validation, and design-system components. It does not show that the complete app, backend, and integrations work together.
API Backend CRUD behavior, permissions, error responses, and response contracts; it can also help set up test state. It does not verify that the UI renders or behaves correctly.
Accessibility Checks such as labels, alternative text, contrast, keyboard navigation, and focus behavior layered into a test strategy. It is an additional check, not a replacement for functional test coverage.

A balanced suite uses focused checks for fast feedback and reserves E2E coverage for journeys whose cross-layer behavior matters. Passing one category alone is not evidence that the entire product works.

2. Install Cypress and create the first test

Use the package manager already used by your project. The following npm commands install Cypress locally and open the guided setup:

npm install --save-dev cypress
npx cypress open

In the Cypress app, choose E2E or Component Testing. For component testing, the guided setup detects a UI framework and bundler and scaffolds development-server configuration. Cypress’s installation guide covers the setup flow and package-manager alternatives.

For a minimal E2E spec, create cypress/e2e/home.cy.js (the default spec pattern includes JavaScript, JSX, TypeScript, and TSX files) and add a test for a real, observable outcome:

describe('home page', () => {
  it('shows the primary page heading', () => {
    cy.visit('/');
    cy.get('h1').should('be.visible');
  });
});

Use an application-specific, stable selector when practical. A semantic query such as a role, label, or visible text often describes user-facing behavior better than a selector tied to layout or styling.

3. Configure and run end-to-end tests

Set baseUrl so Cypress resolves relative visits against the running application. In a JavaScript configuration file, for example cypress.config.js:

const { defineConfig } = require('cypress');

module.exports = defineConfig({
  e2e: {
    baseUrl: 'http://localhost:3000',
  },
});

Start the app in one terminal and run Cypress in another:

npm run dev
# In a second terminal:
npx cypress open

For headless execution, use:

npx cypress run

Once baseUrl is configured, cy.visit('/') targets the local app. Cypress describes testing against a local development server as the usual development workflow. See Best Practices and Testing Your App.

4. Keep tests independent and maintainable

Cypress enables E2E test isolation by default and cleans browser state between tests. Write each test so it can run by itself; do not rely on cookies, local storage, navigation, or server-side data left by a preceding test. Put deliberate setup in each test or a shared setup hook, and make the setup repeatable.

  • Assert on user-visible outcomes, not only that a command completed.
  • Use stable selectors and avoid coupling tests to incidental layout details.
  • Prepare data in a known state and account for cleanup or unique test records.
  • Keep a failing test runnable on its own while diagnosing it.
  • Check the configured specPattern if Cypress does not discover a spec. The default E2E pattern is cypress/e2e/**/*.cy.{js,jsx,ts,tsx}; component specs may live beside components.

See Writing and Organizing Tests for isolation and organization guidance.

5. Run Cypress reliably in CI

A reliable CI sequence installs dependencies, starts the application, waits until it responds, and then runs Cypress. Starting the server and immediately invoking tests can race with app startup; an arbitrary fixed sleep can also be too short or waste time. Use the readiness mechanism supported by your CI setup or project tooling.

# Install dependencies and Cypress using the repository's lockfile workflow.
npm ci

# Start the app and wait for its readiness using your CI's server-wait mechanism.
# Then run the suite:
npx cypress run

Keep any Cypress recording key in the CI secret store and expose it to the job as an environment variable or supported CLI key. Do not commit credentials. Cypress notes that its record key is not read from cypress.env.json or the configuration env block. See the Continuous Integration Overview.

Retries: signal, not a repair

Retries default to zero and can be configured separately for interactive and run modes. For example, this configuration allows two retries in CI runs and none in interactive mode:

const { defineConfig } = require('cypress');

module.exports = defineConfig({
  retries: {
    runMode: 2,
    openMode: 0,
  },
});

A test that passes only after a retry is intermittent. Use the failure evidence to find timing races, unstable test data, environment differences, or external dependencies; do not let retry success conceal a brittle test. See Test Retries.

6. Troubleshooting common failures

Symptom Likely cause What to check or change
cy.visit('/') cannot reach the page The app is not running, the host or port is wrong, or baseUrl does not match. Start the app, visit its local address directly, and align baseUrl with the actual host and port.
Tests fail in CI but pass locally at startup The test command runs before the app is ready. Add a readiness check and start the server before cypress run; do not rely on a guessed fixed delay.
A test passes alone but fails in the suite It depends on shared browser state, test order, or data left by another test. Run the test independently, reset or uniquely create its data, and remove order-dependent assumptions.
Cypress does not show a spec The file is outside the configured spec pattern or has an unexpected extension. Check specPattern, file location, and the selected testing type.
A retry makes a failing test pass The test is intermittent because of timing, data, environment, or network variation. Inspect the failed attempt and fix the root cause; keep retries limited and intentional.
Recorded CI run cannot authenticate The record key is missing, invalid, or supplied through a configuration location Cypress does not read for this purpose. Provide the key through CI secrets as an environment variable or supported CLI key, and verify the job receives it without printing it.

7. Performance, reliability, and cost decisions

Keep feedback fast by testing many isolated UI and API cases at their appropriate layers, then cover a smaller set of high-risk journeys end to end. E2E tests need a running application and any required services or data, so their infrastructure and maintenance needs are higher. Cypress’s reviewed documentation does not provide a universal run-time benchmark; actual duration depends on the application, suite, and CI environment.

Retries can increase the time a suite spends on intermittent failures and can obscure reliability problems if treated as a fix. Start with zero retries, investigate instability, and add a small retry count only where it helps surface evidence during diagnosis. Plan CI capacity around the suite and environment you actually run; no single test-layer mix or runtime fits every project.

8. Screenshot checks for visual investigations

Cypress tests can establish behavior such as navigation, validation, and visible content. When investigating a page’s rendered appearance, a screenshot can help make the state inspectable. For a quick capture of a public page, ScreenshotNeo is a website screenshot API and MCP server made by Yorker Media. Its request accepts a URL and returns a PNG, JPEG, WebP, or PDF; see the ScreenshotNeo site and API documentation.

Or skip the browser setup

Make a screenshot with one GET request. Replace the example URL with the page you want to inspect. The API key is available from your account.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

Consult the ScreenshotNeo docs for request options and response details. Cookie banners are accepted like a visitor and removed along with 60+ known consent platforms, newsletter popups, and chat widgets before the shot; each step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. AI agents can use its MCP server tools take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots. Sign up for 1,000 free screenshots a month, with no card.

9. Frequently asked questions

Do I need to replace unit tests with Cypress?

No. Use the layer that directly answers the question, and combine focused checks with E2E coverage for important cross-application workflows.

Should every test be end to end?

No. E2E tests need more setup and infrastructure. Use them for critical journeys; use component and API tests for narrower behavior.

Are retries enabled by default?

No. Cypress retries default to zero. Configure them deliberately and investigate intermittent failures.

Can Cypress accessibility checks replace a manual accessibility review?

No. Treat automated accessibility checks as one useful layer alongside functional tests and other accessibility evaluation.

Sources