How to Add a GUI to Cypress End-to-End API Tests
Cypress already includes a GUI for API tests. Run them in the Test Runner with cy.request(), inspect requests, and choose the right workflow for local debugging or CI.
Direct answer: You do not need to add a separate GUI package. Cypress’s built-in Test Runner displays API tests written with cy.request(). Open it with npx cypress open, choose the E2E testing type, and run your spec. For a visible command-line run, use npx cypress run --headed --no-exit --browser chrome.
This guide covers direct API checks in Cypress, how to inspect them in the runner, how that differs from observing application traffic, and when to use interactive, headed CLI, or headless CI runs.
1. Install Cypress and prepare an E2E spec
If Cypress is already installed in your project, continue to the spec. Otherwise, install it as a development dependency using your package manager:
npm install --save-dev cypress
Open Cypress once to complete its project setup and create or select the E2E testing configuration:
npx cypress open
Cypress’s API guide treats direct API tests as E2E tests. You can set e2e.baseUrl in your Cypress configuration to use relative URLs; it is optional, since cy.request() also accepts a full URL. See the Cypress API testing guide for current setup and examples.
2. Write a runnable API test
For example, create cypress/e2e/api.cy.js. This spec calls a public endpoint and checks the response. Replace the example URL and assertions with an endpoint and contract that your project owns or is authorized to test.
describe('API checks', () => {
it('gets a response and checks its status and body', () => {
cy.request('https://jsonplaceholder.typicode.com/posts/1').then((response) => {
expect(response.status).to.equal(200)
expect(response.body).to.have.property('id', 1)
expect(response.headers).to.have.property('content-type')
expect(response.duration).to.be.lessThan(5000)
})
})
})
The duration assertion is an example threshold, not a performance guarantee. Choose a limit that makes sense for your endpoint and test environment, or omit it if latency is not part of the contract you are checking.
With a configured E2E base URL, requests can use a relative path:
cy.request('/api/health')
Without one, pass the full URL:
cy.request('https://api.example.com/health')
cy.request() returns a response you can inspect, including its status, body, headers, and timing. Cypress retries assertions chained after the request according to its command behavior; it does not turn a failing endpoint into a passing check. Use explicit assertions for the contract you need to protect.
3. Run the test in Cypress’s GUI
- Start the interactive Test Runner with
npx cypress open. - Choose E2E Testing if prompted.
- Select a browser and launch the runner.
- Choose the API spec you created. Cypress runs the spec in the Test Runner.
- Inspect the Command Log. Select a request command to view its method, status, URL, and request and response details.
An application page does not have to be open for a direct cy.request() test to be useful. The runner shows test steps and lets you inspect request results as the test executes.
4. Choose the right Cypress workflow
| Goal | Command | What to expect |
|---|---|---|
| Author and debug interactively | npx cypress open |
Opens the interactive, headed Test Runner. Select and run a spec, then inspect its Command Log. |
| Reproduce a CLI or CI run visibly | npx cypress run --headed --no-exit --browser chrome |
--headed shows the browser. --no-exit keeps Cypress open after a spec so you can inspect the run. |
| Run in CI | npx cypress run |
Runs headlessly by default, which suits environments without a display. |
Use cypress open while writing or debugging a test. Use the headed CLI form when you need to reproduce the command-line run with a visible browser, such as investigating a difference between headed and headless behavior. Headed execution is not required for API tests.
5. Know whether you need cy.request() or cy.intercept()
These commands answer different questions:
cy.request()makes an HTTP request directly from the test. Use it to check an API response or prepare test data.cy.intercept()observes, waits on, or stubs requests made by the application. Use it when the behavior under test is the application’s network traffic.
For example, if a page makes a request when it loads, you can register an intercept and wait for the application to issue it:
cy.intercept('GET', '/api/profile').as('getProfile')
cy.visit('/')
cy.wait('@getProfile').its('response.statusCode').should('equal', 200)
Here, cy.visit() starts the application flow and cy.intercept() watches that flow. A direct cy.request() would make a separate request from the test instead.
6. Screenshots, video, and post-run inspection
- During
cypress run, Cypress automatically captures screenshots when a test fails. - Failure screenshots are not automatically captured during
cypress open. - Video recording is disabled by default. When enabled, Cypress records a video per spec during
cypress run, not duringcypress open.
Do not expect an automatic video from an interactive open-mode run. For current artifact settings, see Cypress’s screenshots and videos guide.
7. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The runner does not list the API spec | The spec is outside the configured E2E spec pattern, or the project is not configured for E2E tests. | Check the project’s Cypress E2E configuration and place the file in the configured spec folder, commonly cypress/e2e. |
| A relative request URL fails | No E2E baseUrl is configured, or the path is not relative to the expected host. |
Set e2e.baseUrl or pass the endpoint’s full URL to cy.request(). |
| The test fails on a non-2xx response | The endpoint returned an error, or the test expects a successful response when an error is intentional. | Check the endpoint, environment, credentials, and response. If testing an error response intentionally, configure the request’s failure behavior and assert the expected status explicitly using the current cy.request() options. |
| The browser is not visible during a CLI run | cypress run is headless by default. |
Use --headed and specify an installed browser, for example --headed --browser chrome. |
| Cypress exits before you can inspect the CLI run | The run ended normally and the process closed. | Add --no-exit to keep Cypress open after the spec. |
| An intercept never receives the expected request | The application did not make a matching request, or the intercept was registered too late or uses the wrong method or URL pattern. | Register cy.intercept() before the action that triggers the request, then check the method and matching URL. Use cy.request() only if you intend the test itself to call the endpoint. |
| A request works locally but fails in CI | The CI environment may have different network access, secrets, base URL, or service readiness. | Confirm CI variables and endpoint reachability, avoid relying on local-only services, and ensure the API is ready before the test runs. |
8. Performance, reliability, and cost
Direct API checks can provide feedback on backend contract changes and can make setup or teardown faster than navigating forms. Cypress describes these as reasons to add API checks alongside UI tests; actual time depends on your endpoints and environment. Keep checks focused, avoid unnecessary repeated setup requests, and use the same environment assumptions in local and CI runs.
For reliability, assert the response properties that define success for your application rather than relying only on a status code. Keep credentials in environment-specific configuration, and avoid putting secrets into committed specs or logs. Distinguish a direct API check from an application-flow test so the failure points are clear.
Cypress is software you add to your project; this workflow does not require a separate GUI package. The supplied research does not establish a specific Cypress price or a performance benchmark, so check Cypress’s current official materials for any plan-dependent services you choose to use.
9. Or skip the browser setup
If your goal is to capture a website screenshot for a test or workflow, ScreenshotNeo is a website screenshot API and MCP server. A single GET request returns a PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API docs for request options.
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}`);
- Cookie banners and consent prompts, newsletter popups, and chat widgets are removed before capture; each cleanup step can be turned off.
- Bot checks and CAPTCHAs, blank pages, failed loads, timeouts, and cache hits are never billed. Responses identify the page verdict and billing status in headers.
- An MCP server gives AI agents tools to take screenshots, inspect page information, and capture PDFs.
- The free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots.
Sign up for 1,000 free screenshots a month, with no card required.
10. Frequently asked questions
Do Cypress API tests need a browser page?
No. A test using cy.request() can call and check an API without first visiting an application page. The Test Runner still displays the test and its commands.
Can I use the Cypress GUI for API tests in CI?
CI commonly runs cypress run headlessly. The interactive GUI is useful for local authoring and debugging; headed CLI runs are available when a visible browser is useful and the environment supports one.
Does cy.request() test the same thing as the application’s network call?
No. It sends a request directly from the test. Use cy.intercept() to observe, wait for, or stub traffic generated by the application.
Will open mode save a failure screenshot or video automatically?
Failure screenshots are automatic during cypress run, not cypress open. Video is off by default and, when enabled, is recorded during run mode.


