UI testing ensures that your application’s interface behaves as expected for users across different scenarios. Cypress offers a fast, reliable, and developer-friendly way to run UI tests directly in the browser, making it easier to catch and debug visual and functional issues early in the development cycle.
This article explains how to run UI tests in Cypress, from setting up your test environment to writing and executing test cases.
What is Cypress?
Cypress is an end-to-end testing framework built for modern web applications. It allows developers and QA engineers to write and run tests directly in the browser. It offers real-time reloading, powerful debugging tools, and a simple API for interacting with web elements.
Unlike traditional Selenium-based tools, Cypress runs in the same run loop as the application, giving it better access to the DOM and network requests, which leads to faster and more reliable test execution.
Cypress Architecture
Cypress has a unique architecture that sets it apart from traditional testing tools like Selenium. Instead of running outside the browser and communicating over a network, Cypress executes directly inside the browser alongside your application.
Here’s a breakdown of its architecture:
1. Test Runner (Runs Inside the Browser)
The Cypress Test Runner injects test code directly into the browser where your application is running. This allows the test runner to access the DOM, local storage, cookies, and other browser APIs natively. Because tests run in the same event loop as the application, the test runner ensures faster and more stable execution compared to traditional testing tools.
2. Node.js Backend (Runs Outside the Browser)
While the tests run inside the browser, Cypress also runs a Node.js server in the background. This handles tasks that browsers cannot, such as:
- Reading and writing files such as screenshots, videos, and fixtures
- Managing network requests
- Communicating with the operating system
3. Browser Automation Layer
Cypress uses a custom browser automation layer, not WebDriver, to control the browser and simulate real user interactions like clicks, typing, and scrolling.
4. App and Test Execution in the Same Context
Unlike Selenium, which drives browsers remotely, Cypress runs the test code in the same context as your application. This makes it easier to:
- Access and assert application state
- Wait for elements without needing explicit waits
- Debug using browser dev tools
5. Dashboard (Optional)
Cypress also offers a Dashboard Service that provides insights into test runs, including logs, screenshots, and videos. This is especially useful when tests run in CI pipelines.
How to Perform Cypress End-to-End UI Testing
End-to-end (E2E) UI testing ensures that your entire application flow works as expected from the user’s perspective. Cypress makes it easy to simulate real user interactions in the browser and validate UI behavior across pages and components.
To get started, set up your development environment with the following prerequisites.
Install Node.js
- Go to the Node.js download page
- Select your operating system and download Node.js (LTS version recommended)
- Install the Node.js binaries
Install Visual Studio Code (Optional but Recommended)
- Go to the Visual Studio Code download page
- Download and install the editor
Step 1: Create an empty directory (ex:cypress-e2e)
Create an empty folder that helps to install and configure cypress
Step 2: Launch Open Empty directory and Launch Terminal
- Launch the VSCode app installed as a prerequisite
- Open the newly created folder from File Menu
- Navigate to the Terminal menu
- Click on the New Terminal
Step 3: Install Cypress
The Cypress installation command installs all required dependencies. To install Cypress use the below command
npm install cypress
Cypress automatically creates the package.json folder in your project root folder during the installation.
Step 4: Open the Cypress
Cypress needs to perform initial settings, you need to enter the open command to start the cypress window.
npx cypress open
Note: Cypress may throw the verification failed error, entering the open command again should resolve the issue.
Step 5: Choose the options on the Cypress window
Once you enter the open command, the Cypress window will be launched and choose the configuration.
- Choose the Testing Type: When you run the open command, the Cypress window opens. Choose the testing type. In our case, it is end-to-end testing.
- Configuration Files: The configuration files window pops up, review them and Click continue. Cypress creates the configuration settings after this step.
- Choose a Browser: Next, You need to choose the desired browser from the available options. For the demo purpose let’s choose Chrome and click Start e2e Testing in Chrome
- The Cypress test runner window opens up, click create new empty spec.
- Enter the desired spec name, and click on Create Spec
- Enter the name as demo.cy.js
- The example spec will be created click Okay, run the spec.
The demo tests start running. At this point, your project directory tree looks as shown below.
Understanding the Cypress directory and files
- e2e folder: Contains Cypress end-to-end specs
- fixtures folder: Any data which can be used inside the specs can be placed here
- support folder: Helper functions, utilities, any reusable code, and custom commands can be placed here.
- support/e2e.js: Great place to put the global configuration and reusable code
- support/commands.js: In this file, you can create custom commands or override existing commands
- cypress.config.js: This file contains run time configurations such as baseURL, reporter, videos, screenshot options, etc.
- package.json: This file tracks all installed dependencies and allows you to create a custom commands shortcut
Step 6: Create a sample test
You have given demo.cy.js as an example spec name, which is already created as part of Cypress setup. Let’s modify the demo.cy.js with actual use cases.
Let’s consider the scenario
- Navigate to Browserstack home and verify home page is loaded successfully
- Click on the Pricing menu, and verify if all the product names are listed.
Below is the cypress test spec for the above scenario
//demo.cy.js describe('Browserstack Demo', () => { beforeEach(() => { cy.viewport(1280, 1000) }) it('should verify home page', () => { cy.visit('https://browserstack.com') cy.get('#logo').should('be.visible') cy.title().should('eq','Most Reliable App & Cross Browser Testing Platform | BrowserStack') }) it('should verify Pricing page', () => { cy.get('a[title="Pricing"]').first().click(); cy.get('a[data-item-id="live"]').should('contain.text','Live') cy.get('a[data-item-id="automate"]').should('contain.text','Automate') cy.get('a[data-item-id="percy"]').should('contain.text','Percy') cy.get('a[data-item-id="app-live"]').should('contain.text','App Live') cy.get('a[data-item-id="app-automate"]').should('contain.text','App Automate') }) })
Home page verification
- cy.visit() Navigates to the BrowserStack home page
- cy.get() is chained with assertions should() to verify the visibility of the logo
- cy.title() is chained with the assertion (should) to verify the title is correct
Pricing menu verification
The click action is performed using cy.get().click() on the pricing menu
Once it is landed on the pricing menu, all respective locators text are asserted to verify the product listing on the pricing menu.
Step 7: Execute the test case
Cypress allows execution through the command line or using the Cypress window(UI)
Execute cypress UI tests using cypress window
- Enter the command npx cypress open
- Navigate to the Test runner window
- Click on demo.cy.js to start execution
Cypress test execution using command line
Use the below command to execute Cypress UI tests in the command line
npx cypress run --spec cypress/e2e/demo.cy.js
Read More: Cypress End to End Testing: Tutorial
How Run Cypress Component UI Testing
Component UI testing involves testing individual UI components’ visual and interactive behavior during development. This allows for faster feedback and delivery. Unlike end-to-end testing, component UI testing is performed in isolation on single components.
Cypress supports component UI testing from version 10 and above, and it works with major frameworks such as React, Vue, and Angular.
To get started, you need to set up your development environment with the required tools.
Install Node.js
- Go to the Node.js download page
- Select your operating system and download Node.js (LTS version recommended)
- Install the Node.js binaries
Install Visual Studio Code (Optional but Recommended)
- Go to the Visual Studio Code download page
- Download and install the editor
Step 1: Create a New Folder and Open it in VS Code
Start by setting up a dedicated folder for your component UI tests. This keeps your test files organized and separate from other projects.
- Create a new folder for component testing (for example, cypress-component-demo)
- Open the folder in VS Code using the File menu > Open Folder
Step 2: Clone the Simple react App
As components need to be present locally, you need to create a sample react app and components
Note: if you are already having the component created in your development framework you can use the same.
On the VSCode terminal enter the below command
npm create vite@latest my-awesome-app -- --template react
Step 3: Install the dependencies
Switch to folder my-awesome-app and enter the below command to install the dependencies.
npm install
The above command clones the simple react app that can be used for component testing.
Step 4: Install the Cypress
Install Cypress using the below command
npm install cypress -D
Step 5: Configure Cypress for component testing
- Open Cypress
npx cypress open
- Choose Component testing from the Cypress window
- The Project Setup window automatically detects the Framework and builder so click Next.
- Next, Cypress verifies all required dev dependencies are present. Click Continue
- Based on the installed framework and dependencies Cypress creates the configuration file. Review them, and clicks Continue.
- Choose the browser: You can choose any browser, for simplicity choose Chrome and click Start Component Testing in Chrome.
At this point, the test runner shows up. Do not do anything, simply close the Cypress window.
The Project Structure looks as below
Step 6: Create a simple component
Navigate to my-awesome-app/src and create a file with DemoComponent.jsx
Create a simple component with a greetings message
import { useState } from 'react' export default function Demo({ greetings = 'Good Morning' }) { const [greetingMessage] = useState(greetings) return ( <div> <div id='message'> Hello Browserstack! {greetingMessage} </div> </div> ) }
In the above code, the default greeting message is Hello Browserstack! Good Morning,
However, the demo function accepts optional parameter greeting messages you can pass it like Good Evening, etc.
Let’s test this using Cypress
Step 7: Create Cypress Component Test
Navigate to Cypress directory and create a directory with the name component.
Create a file inside the cypress/component folder and name it as DemoComponent.cy.jsx
Let’s create two test case
- Verify the default welcome message
- Verify the message by sending the parameter “Good Evening”
import Demo from '../../src/DemoComponent' describe('Demo Component', () => { it('Default Message', () => { cy.mount(<Demo/>) cy.get('#message').should('have.text','Hello Browserstack! Good Morning') }) it('Good Evening Message', () => { cy.mount(<Demo greetings='Good Evening'/>) cy.get('#message').should('have.text','Hello Browserstack! Good Evening') }) })
The above code, cy.mount() mounts your component
cy.get() is used for getting the locator on the browser and assertion is used for verifying the text
Step 8: Execute the Cypress component tests
- Open the Cypress window using
npx cypress open
- Navigate to the Cypress test runner window
- Choose the DemoComponent.cy.jsx and execute the test
You can also use the Cypress command line tool to execute the test
npx cypress run --component
The above command executes component tests in headless mode and the results will be shown in command line.
Cypress Tips and Tricks
Make the most of Cypress for UI testing with these practical tips and tricks to write cleaner, faster, and more reliable tests:
1. Use data-* Attributes for Selectors
Avoid flaky tests by using stable selectors like data-cy, data-test, or data-testid instead of class or ID selectors that may change with styling.
<button data-cy="submit-btn">Submit</button>
2. Leverage cy.intercept() for Network Control
Stub or monitor API requests using cy.intercept() to simulate backend behavior and speed up test execution.
cy.intercept('GET', '/api/users', { fixture: 'users.json' }).as('getUsers');
3. Use beforeEach() to Reduce Repetition
Place repeated setup steps inside beforeEach() to avoid duplicating code across tests. This keeps your test suite clean and easier to maintain.
beforeEach(() => { cy.visit('/login'); });
4. Add Custom Commands for Reusability
Use Cypress.Commands.add() in cypress/support/commands.js to define reusable actions. This helps you write cleaner tests by moving repeated steps into a single, easy-to-use command.
Cypress.Commands.add('login', (email, password) => { cy.get('#email').type(email); cy.get('#password').type(password); cy.get('form').submit(); });
5. Use .should() Assertions Wisely
Chain assertions to verify element states clearly and avoid unnecessary waits. Chaining assertions makes tests easier to read and avoids unnecessary retries or delays, leading to faster and more stable tests.
cy.get('.alert').should('be.visible').and('contain', 'Success');
6. Avoid Hard Waits (cy.wait)
Instead of the hard-coded cy. wait (), use dynamic waits like cy.get().should() or aliases to wait for requests or elements. Instead, use dynamic waits like cy.get().should() or network aliases to wait for elements or requests to complete only when necessary, improving both test speed and stability.
7. Run Tests in Headless Mode for CI
Use cypress run –headless to execute tests without launching a visible browser. This speeds up execution, reduces resource usage, and fits seamlessly into CI pipelines where no UI is needed.
Run End-to-End UI Tests on BrowserStack
BrowserStack is a real device cloud testing platform that lets you run your Cypress end-to-end UI tests on a wide range of actual browsers and operating systems without managing your own infrastructure. Here’s why you’d choose BrowserStack for E2E testing with Cypress:
- Access to real environments: Test on hundreds of real desktop and mobile browsers, including multiple versions of Chrome, Firefox, Safari, and Edge hosted in the cloud.
- Parallel test: Run tests across multiple browser and OS combinations at the same time to reduce test execution time and speed up release cycles.
- CI/CD integration: Connect BrowserStack to CI/CD tools like GitHub Actions, Jenkins, or GitLab so that each commit automatically triggers cross-browser tests.
- Test debugging: Get screenshots, video recordings, console logs, and network info for every test to quickly identify and resolve UI issues.
Here’s how to use BrowserStack to run end-to-end UI tests.
1. Install BrowserStack using the below command
npm install -g browserstack-cypress-cli
2. Create a browserstack.json file using the below command
browserstack-cypress init
3. Open the browserstack.json file
- Add the username and access_key
- Specify the cypress.conf.js file path
4. Execute the Cypress tests on BrowserStack
browserstack-cypress run
Conclusion
Cypress enables teams to catch UI issues early and deliver consistent user experiences by offering real-time reloading, automatic waits, and a developer-friendly API. These features make it easier to build, test, and maintain reliable front-end workflows throughout the development lifecycle.
To further enhance your testing, running Cypress tests on BrowserStack allows you to validate UI behavior on real devices and browsers without maintaining any infrastructure. This ensures your application works seamlessly across different platforms, improves test coverage, and supports faster, more confident releases.