Getting Started with Cypress for Browser Testing
Install Cypress, choose E2E or component testing, and write a useful first browser test. This guide also covers browsers, CI, troubleshooting, and screenshots.
Cypress is a browser testing tool you install in your project. For a first end-to-end (E2E) test, install Cypress as a development dependency, open its Launchpad, choose E2E testing and a browser, then write a spec that visits your app, interacts with it, and checks the result. Use component testing instead when you want to mount and test one component in isolation.
This guide walks through setup, a runnable first test, browser selection, generated files, continuous integration (CI), and common setup failures. Check Cypress’s current installation guide and system requirements before installing; supported operating systems, Node.js versions, and package-manager requirements can change.
1. Install Cypress in your project
Run one install command from your project root. Keep Cypress local to the project so team members and CI use its declared version.
# npm
npm install --save-dev cypress
# Yarn
yarn add --dev cypress
# pnpm
pnpm add --save-dev cypress
# Bun
bun add --dev cypress
Then open the Cypress app using your package manager:
# npm
npx cypress open
# Yarn
yarn cypress open
# pnpm
pnpm exec cypress open
# Bun
bunx cypress open
The first launch opens the Launchpad, which guides you through selecting E2E or component testing and creates starter configuration and support files. If your package manager blocks install lifecycle scripts, follow its current instructions to approve Cypress’s install script or install the Cypress binary explicitly. See the official install documentation for package-manager-specific details.
2. Choose E2E or component testing
| Test type | What it exercises | Good first use |
|---|---|---|
| E2E | Your running application through a real browser journey. | Sign-in, navigation, checkout, form submission, or another user workflow. |
| Component | An individual component mounted in isolation, across props and states. | A button, dialog, form field, or component with several interaction states. |
For a first browser test of an existing app, choose E2E. The Launchpad scaffolds the relevant configuration and folder structure. You can revisit the configuration later; do not customize generated files until a project need calls for it. For details about the setup flow, see Cypress’s getting-started documentation.
3. Start the application and write a meaningful test
A browser test needs an application to visit. Start your development server in one terminal and leave it running. For example, if your project defines a dev script:
npm run dev
In Cypress, create an E2E spec in the generated E2E folder, commonly cypress/e2e/. The following example assumes your app runs at http://localhost:3000 and has a page with a link named “Get started” that leads to a page showing “Welcome”. Adapt the URL and accessible names to your app:
describe('getting started journey', () => {
it('opens the guide from the home page', () => {
cy.visit('http://localhost:3000');
cy.findByRole('link', { name: 'Get started' }).click();
cy.findByRole('heading', { name: 'Welcome' }).should('be.visible');
});
});
This example uses Testing Library’s Cypress query commands for role-based selectors. Install and register the commands if you use this version of the example:
npm install --save-dev @testing-library/cypress
In the E2E support file generated by Cypress, commonly cypress/support/e2e.js, add:
import '@testing-library/cypress/add-commands';
Alternatively, use Cypress’s built-in query and assertion commands without an additional package. Give the relevant link a stable attribute such as data-cy="get-started" and write:
describe('getting started journey', () => {
it('opens the guide from the home page', () => {
cy.visit('http://localhost:3000');
cy.get('[data-cy="get-started"]').click();
cy.contains('h1', 'Welcome').should('be.visible');
});
});
The useful pattern is setup, action, assertion: visit a known page, perform the user action, and verify an outcome that demonstrates the behavior. An assertion against a constant can confirm syntax, but it does not tell you whether your application works. Cypress reruns the spec as you save changes when using the interactive app. The official first-test tutorial explains the initial workflow.
4. Run the test in the Launchpad and from the terminal
In the Launchpad, select the test type and a browser, then choose the spec to run. For repeatable local or CI runs, start the app separately and use cypress run:
# Run the E2E suite in a selected browser
npx cypress run --e2e --browser chrome
Use the package-manager equivalent if you prefer. Add a project script to make the command easy to remember:
// package.json
{
"scripts": {
"test:e2e": "cypress run --e2e --browser chrome"
}
}
npm run test:e2e
For one spec, pass its path with --spec, for example npx cypress run --e2e --browser chrome --spec "cypress/e2e/home.cy.js". Cypress supports additional CLI configuration and filtering; check the command-line reference for the options available in your installed version.
5. Select a browser deliberately
Cypress documents Chrome-family browsers and Firefox, and experimental WebKit support. Its current browser reference describes support for the latest three major versions of Chrome, Firefox, and Edge. These details can change, so confirm compatibility in the browser documentation before setting a long-lived CI matrix.
- Test the browsers your users actually rely on.
- Balance additional coverage against CI time and infrastructure cost.
- Pin or otherwise control browser versions when reproducibility matters. Cypress recommends Chrome for Testing when a pinned, reproducible Chrome binary is needed.
- Make the browser choice explicit in CI with
--browser; install that browser in the CI environment or use an official Cypress image.
The current documentation marks WebKit as experimental and Electron as deprecated. Choose a supported browser such as Chrome explicitly rather than relying on Electron as an implicit default. Verify the current compatibility notes before depending on a browser for release coverage.
6. Know the generated files
The Launchpad creates a conventional starting layout. Exact names can vary with the selected test type and project setup.
| File or folder | Typical purpose |
|---|---|
cypress.config.js or cypress.config.ts |
Project-level E2E and component testing configuration, such as the application base URL. |
cypress/e2e/ |
E2E specs that exercise browser journeys. |
cypress/fixtures/ |
Reusable static test data when a spec needs it. |
cypress/support/e2e.js |
E2E support code loaded for E2E specs, such as command registration. |
cypress/support/component.js |
Component support setup, when component testing is configured. |
Keep the defaults until there is a clear reason to change them. The configuration and support entry points can be adjusted as the project grows; see the configuration reference.
7. Run Cypress in continuous integration
A CI job needs the project dependencies, Cypress binary, application server, and the browser selected for the run. A minimal shell sequence is:
npm ci
npm run build && npm run start &
# Wait for the application to become ready using your CI's wait-for-URL step.
npx cypress run --e2e --browser chrome
The server command above is only an example: use the start command and readiness check appropriate to your framework and CI provider. Avoid starting Cypress before the app is listening, and ensure the selected browser is installed in the job environment. An official Cypress container image is another option. For browser-specific image and CI guidance, consult the Cypress CI documentation.
For reliable runs, keep dependencies and browser versions controlled, use a deterministic test environment, and make each test establish the state it needs rather than relying on a previous spec. Add browsers to the CI matrix when the coverage they add justifies the extra run time and infrastructure.
8. Capture a screenshot for visual inspection
Cypress can capture screenshots as part of browser testing. For example, add a screenshot after an assertion when you want a named artifact during an interactive run:
cy.findByRole('heading', { name: 'Welcome' }).should('be.visible');
cy.screenshot('welcome-page');
For a simple repeatable image of a public page, you can also use a dedicated website screenshot API. ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. A single request returns an image or PDF, and its options include full-page capture, element capture, browser viewport and device selection, waiting, custom CSS, and more. The API parameter names used by other screenshot services also work to ease switching. See the ScreenshotNeo site and API documentation.
Or skip the browser setup
For a screenshot of a page, call ScreenshotNeo directly. Replace the sample URL with the page you need and put your API key in the request:
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,
)
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);
In Node.js, the final two lines use Bun’s file-writing API. With Node.js, save the response using this complete variant instead:
import { writeFile } from 'node:fs/promises';
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 writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month, no card required.
9. Troubleshooting first-run problems
| Symptom | Likely cause | Fix |
|---|---|---|
| The Cypress app opens, but it cannot launch a browser. | The requested browser is missing or Cypress cannot find its binary. | Install a supported browser in the environment, select an available one in Launchpad, or set the browser path as described in the current browser documentation. |
cypress open or cypress run reports that the binary is missing. |
The package was installed but its binary download or install script did not complete, often because lifecycle scripts were blocked. | Approve the Cypress install script or use the documented binary installation command, then retry. Check the install guide for the package manager in use. |
cy.visit() fails to connect. |
The development server is stopped, still starting, or listening at a different port or host. | Start the server first, wait for its readiness, then use the exact reachable URL in the spec or configure the base URL. |
| A query finds no element. | The selector or accessible name does not match, the page has not reached the expected state, or the element is inside a frame or shadow DOM. | Inspect the rendered page and use a stable selector. Prefer a user-facing role and name when practical; synchronize on a real page condition instead of adding arbitrary sleeps. |
| The test passes locally but fails in CI. | The CI browser, environment variables, server readiness, viewport, or application data differs from local development. | Use the same explicit browser and controlled dependencies, provide required configuration and test data, and wait for the server to become ready before running Cypress. |
| WebKit behaves differently or cannot start. | WebKit support is experimental and may have environment-specific constraints. | Check current Cypress compatibility notes and use a stable supported browser for required CI coverage where needed. |
10. Performance, reliability, and cost
- Keep the first suite small. Begin with one important user journey and add coverage as the app’s critical behavior becomes clear.
- Use explicit synchronization. Wait for a meaningful visible state or application response; arbitrary delays make a test slower and less reliable.
- Choose CI browsers for coverage. Each extra browser adds execution and maintenance cost. Pin versions where reproducibility is important.
- Control your test environment. Stable test data, a ready server, and independent specs help reduce order-dependent failures.
- Plan machine and pipeline costs. Cypress runs in your local or CI environment; the exact cost depends on your chosen infrastructure and browser matrix. The research sources do not establish a universal runtime or cost figure.
- Separate tests from screenshots. A Cypress test validates application behavior. A screenshot API captures a page image or PDF; use the operation that matches the goal.
FAQ
Do I need Cypress Cloud to write my first test?
No. The setup and local commands in this guide are for installing and running Cypress in your project. Cloud run insights and other offerings are separate from the first local test.
Can Cypress test one component without opening the whole app?
Yes. Choose component testing in the Launchpad to mount an individual component in isolation, then write a component spec for its states and interactions.
Should I use a screenshot assertion as my first test?
Start by asserting the behavior the user depends on, such as navigation or a successful form result. Add screenshot capture when an image artifact helps inspect a run.
Can I use this setup with another package manager?
Yes. Cypress documents npm, Yarn, pnpm, and Bun installation paths. Use the command appropriate to the package manager already used by your project, and check its current script approval behavior.


