ScreenshotNeo

BlogHow-to

How to Deploy and Schedule Cypress Tests in the Cloud

Build, trigger, schedule, parallelize, and troubleshoot Cypress tests in cloud CI with practical GitHub Actions examples and Cypress Cloud guidance.

By the ScreenshotNeo team29 September 20269 min read

How to Deploy and Schedule Cypress Tests in the Cloud

Direct answer: Put Cypress in a CI workflow that checks out your code, installs dependencies, builds and starts the application, waits for its test URL to respond, and then runs Cypress. Let the CI provider trigger that workflow on pushes, pull requests, deployments, or a cron schedule. For large suites, record the run to Cypress Cloud, start multiple CI machines, and enable parallelization so Cypress Cloud distributes spec files across workers.

The CI platform controls when a job starts. Cypress Cloud records runs and can coordinate recorded parallel runs; it is not a universal scheduler for every CI workflow. This distinction matters when you design nightly checks, post-deployment tests, and cost controls.

1. Choose the trigger and target environment

Start by deciding what should cause a run and which application instance it should test.

A CI provider starts the workflow; Cypress runs in the prepared environment and Cypress Cloud records or distributes the run.
A CI provider starts the workflow; Cypress runs in the prepared environment and Cypress Cloud records or distributes the run.
Trigger Best use Typical target Trade-off
Push Fast feedback while branches change Ephemeral preview or local CI server Can consume many runner minutes
Pull request Regression gate before merge Preview environment or CI-started app Requires stable secrets and test data
Deployment event Verify a release after it is deployed Staging or production URL Workflow must obtain the correct deployment URL
Schedule Nightly, hourly, or weekday regression checks Stable staging environment Scheduled events can be delayed under provider load

GitHub Actions scheduled workflows use POSIX cron. They run from the default branch, default to UTC, support an IANA timezone, and have a shortest interval of five minutes. GitHub warns that busy periods can delay scheduled events or drop queued jobs; choosing a minute other than 00 can reduce contention. Treat a cron expression as a request to start a run, not a precise execution guarantee. See the GitHub workflow events documentation.

For deployment-triggered checks, GitHub’s deployment event can start a workflow, but your pipeline still needs to pass or discover the environment URL and deployment context. Cypress documents both pre-deployment and post-deployment patterns in its CI overview.

2. Build, start, and wait for the application

A reliable Cypress job has an explicit application lifecycle:

  1. Check out the exact commit under test.
  2. Install the lockfile’s dependencies.
  3. Build the application when the test target requires a production build.
  4. Start the preview or server on a known port.
  5. Wait until a health or application URL responds.
  6. Run Cypress against that URL.

Keep environment-specific values, test accounts, and API tokens in your CI provider’s secret store. Use the project’s real build and start commands; the example below is a shape to adapt, not a universal application configuration.

Minimal scheduled GitHub Actions workflow

name: Cypress scheduled tests

on:
  schedule:
    - cron: '17 5 * * 1-5' # 05:17 UTC, Monday through Friday
  workflow_dispatch:

jobs:
  cypress:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v7

      - name: Run Cypress
        uses: cypress-io/github-action@v7
        with:
          build: npm run build
          start: npm start
          wait-on: http://localhost:3000
          wait-on-timeout: 120

The official Cypress GitHub Actions guide recommends the latest major action tag (currently shown as v7 in the referenced documentation) or pinning a specific release tag when you want to control updates. Confirm the current runner and action versions before publishing a workflow. Read the Cypress GitHub Actions guide for caching, artifacts, browser images, and matrix examples.

Run against an already deployed URL

name: Cypress after deployment

on:
  deployment:

jobs:
  e2e:
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v7
      - run: npm ci
      - run: npx cypress run --config baseUrl="$CYPRESS_BASE_URL"
        env:
          CYPRESS_BASE_URL: ${{ vars.STAGING_URL }}
          CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}

Replace vars.STAGING_URL with the value your deployment system actually publishes. A generic Cypress job does not automatically know which URL a deployment created. For a local server, prefer the action’s build, start, and wait-on inputs so the process remains attached to the workflow.

3. Configure Cypress for CI

Put stable defaults in cypress.config.js or cypress.config.ts, then override environment-specific values in the workflow.

import { defineConfig } from 'cypress'

export default defineConfig({
  e2e: {
    baseUrl: 'http://localhost:3000',
    video: true,
    screenshotOnRunFailure: true,
    retries: {
      runMode: 2,
      openMode: 0
    }
  }
})

Useful CI choices include:

  • baseUrl: keep test URLs out of individual specs.
  • Run-mode retries: retry transient failures, but investigate tests that pass only after retries.
  • Failure screenshots and video: retain evidence for failed or scheduled runs; apply artifact retention policies appropriate to your organization.
  • Browser selection: use the same browser family and version across workers when possible.
  • Test data isolation: reset accounts and databases so repeated scheduled runs do not depend on yesterday’s state.

Use the browser and Node versions supplied by your runner deliberately. Cypress notes that browser image rollouts can temporarily create version differences on hosted runners; a consistent Cypress browser Docker image can reduce that variation on Linux.

4. Record and parallelize large suites

Cypress Cloud parallelization requires a recorded run and more than one CI machine. The CI provider provisions the machines; Cypress Cloud assigns complete spec files to available workers.

name: Cypress parallel

on:
  pull_request:
  push:
    branches: [main]

jobs:
  cypress:
    strategy:
      fail-fast: false
      matrix:
        worker: [1, 2, 3]
    runs-on: ubuntu-24.04
    steps:
      - uses: actions/checkout@v7
      - uses: cypress-io/github-action@v7
        with:
          build: npm run build
          start: npm start
          wait-on: http://localhost:3000
          record: true
          parallel: true
          group: linux-chrome
        env:
          CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }}
          # CI_BUILD_ID should be identical for all matrix jobs in one run.
          CYPRESS_CI_BUILD_ID: ${{ github.run_id }}

Use a single, stable build identifier for every worker in one logical run. Split tests into spec files that represent meaningful units; Cloud schedules whole files, not individual tests. Similar-duration specs balance better than one very large file and many tiny files. Parallel order is not guaranteed.

Cypress Cloud Smart Orchestration includes parallelization, load balancing, spec prioritization, and auto-cancellation. Re-run optimization is labeled experimental in the current overview. Start with two workers, inspect the Machines view, and add capacity only when queue time and runner cost justify it.

Recorded runs provide run views, command logs, screenshots, video replays, stack traces, and CI logs. Cypress documents an illustrative Kitchen Sink result of 1:51 serial versus 59 seconds on two machines, a 53% reduction. That is an example, not a promise for your suite; build time, browser startup, test distribution, and runner overhead determine actual results. See the test performance guide.

5. Scheduled-run design that stays reliable

Prevent overlapping jobs

Nightly runs can overlap when a previous run is slow or a scheduled event is delayed. Add a concurrency group when your policy is “keep only the newest run” or “allow one run at a time.” Choose deliberately: cancelling a run can hide a real regression, while queueing every run increases runner spend.

Use a dedicated test environment

Scheduled tests should not depend on a developer laptop or a mutable production account. Seed known data, create isolated users, and make cleanup idempotent. If the environment is unavailable, fail with a clear health-check error rather than producing dozens of misleading assertion failures.

Account for Cloud completion delay

For grouped or parallel runs, Cypress Cloud documents a Run Completion Delay of 60 seconds by default. The buffer allows slower groups to join. If your workflow knows when all groups have finished, the documented Run Completion API can provide a more explicit completion signal.

6. Performance, reliability, and cost checklist

  • Measure the whole pipeline: include dependency installation, build, browser startup, test time, artifact upload, and queue time.
  • Cache safely: cache package-manager data and reusable build output when cache keys include the lockfile and relevant build inputs.
  • Balance files: split long specs and avoid one serial bottleneck.
  • Use fewer, stronger workers: extra machines help only when enough independent spec work exists.
  • Keep environments consistent: matching Node, browser, OS image, timezone, locale, and feature flags makes failures reproducible.
  • Control scheduled frequency: run smoke checks frequently and expensive regression suites nightly or after deployments.
  • Retain useful artifacts: screenshots, videos, and logs accelerate diagnosis but consume storage.
  • Watch flaky retries: retries improve signal during transient infrastructure faults but can conceal nondeterministic tests.

7. Troubleshooting common failures

Symptom Likely cause Fix
ECONNREFUSED or wait-on timeout Server failed to start, wrong port, or build exited Print server logs, verify the start command locally, and point wait-on at a health URL that returns only when dependencies are ready.
Scheduled workflow never starts on time GitHub schedule delay or dropped queued event during high load Use a non-zero minute, monitor run history, and do not depend on an exact minute for release decisions.
Cloud says machines are not joining Workers use different build IDs, record keys, groups, or project settings Share one CI build identifier and record key; verify every matrix job uses record: true and parallel: true.
One worker runs much longer Uneven spec durations or a monolithic spec Inspect the Machines view and split long specs into smaller files.
Tests pass locally but fail in CI Different browser, timezone, viewport, Node version, data, or environment variables Pin or standardize the runtime, log effective configuration, and seed deterministic test data.
Post-deployment tests hit the wrong site Deployment URL was not passed to the workflow Publish the URL as an output or variable and set Cypress baseUrl explicitly.
Parallel run reports incomplete A worker crashed or finished after the completion buffer Review CI logs, increase the completion delay when appropriate, and use the Run Completion API for a known all-workers signal.

8. Or skip the browser setup

If your workflow only needs a rendered page image for a visual check, documentation artifact, or release record, ScreenshotNeo can return a screenshot with one GET request. It accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing state.

A clean capture removes common consent and overlay elements before the image is returned.
A clean capture removes common consent and overlay elements before the image is returned.

See the ScreenshotNeo API documentation for the full option set. This call is suitable for a CI step after a deployment:

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 failed: ${res.status}`);
const bytes = Buffer.from(await res.arrayBuffer());
await require('fs').promises.writeFile('shot.webp', bytes);

Relevant capture controls include full-page shots with lazy images loaded, CSS-element capture, dark mode, device presets or custom viewports, retina scale, PDF output, custom CSS and JavaScript, clicks, selector waits, delays, network-idle waits, request and resource blocking, headers, cookies, user agents, Authorization, timezone, geolocation, transparent backgrounds, resizing, selectable cache TTLs, signed public image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, usage reporting, and an OpenAPI specification. Parameter names used by other screenshot APIs also work, which can simplify migration.

ScreenshotNeo includes an MCP server with take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. Plans include 1,000 screenshots per month free with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to add a capture step to your CI workflow.

9. Short FAQ

Does Cypress Cloud schedule nightly tests?

The CI provider schedules and starts the workflow. Cypress Cloud records runs and provides orchestration features for recorded runs, including parallelization.

Can I parallelize without recording?

Cypress Cloud parallelization requires recorded runs and multiple CI machines. A serial, unrecorded run can still execute in CI, but Cloud cannot distribute its specs.

Should scheduled tests run against production?

Use a controlled staging environment for destructive or data-heavy tests. Run production checks only when the tests are read-only, the credentials are tightly scoped, and the target is explicitly approved.

Why did adding workers not reduce total time?

The suite may have too few specs, uneven spec durations, a slow build shared by every worker, or a bottleneck outside Cypress. Inspect worker utilization and measure setup time separately from test time.

What should be pinned for reproducibility?

Pin dependency versions through the lockfile and standardize Node, Cypress, browser, runner image, timezone, locale, environment variables, and test data across workers.

Can ScreenshotNeo replace Cypress?

No. ScreenshotNeo captures rendered pages and exposes page information; Cypress remains the system for browser interaction and assertions. They can be used together in one CI pipeline.

For provider-specific syntax and current action versions, recheck the official Cypress CI documentation, parallelization guide, and Smart Orchestration overview when maintaining the workflow.