Cypress E2E Angular Testing: Advanced Tutorial

Build and run reliable Cypress E2E tests for Angular apps. Run tests on real devices and browsers with BrowserStack Automate.

Get Started free
Cypress E2E Angular Testing Advanced Tutorial
Home Guide Cypress E2E Angular Testing: Advanced Tutorial

Cypress E2E Angular Testing: Advanced Tutorial

Testing is a critical part of Angular development. It ensures that apps behave as expected across real user journeys. End-to-end (E2E) testing helps validate that all components work together correctly.

Overview

What is Cypress E2E Angular Testing?

Cypress E2E Angular testing involves using the Cypress framework to simulate and verify real user interactions in an Angular application from start to finish.

Why is it important?

Cypress E2E Angular Testing helps catch bugs before users do and ensures application stability across different workflows and environments.

Writing E2E tests in Cypress for Angular Applications

  1. Use describe() and it() blocks to define test suites and cases
  2. Visit routes with cy.visit() and interact using commands like cy.get()
  3. Target elements using reliable selectors like data-cy
  4. Include meaningful assertions to verify expected outcomes
  5. Keep tests independent and reflect real user behavior

This article covers how to write effective Cypress E2E tests for Angular apps, including form testing, advanced workflows, and the importance of running tests across real browsers.

What is Cypress E2E Angular Testing?

Cypress E2E (end-to-end) testing for Angular involves using the Cypress testing framework to simulate real user interactions across the entire Angular application, from loading the app to performing workflows like form submissions or navigation.

It verifies how all components, services, and routes work together in a real browser environment.

Key goals include:

  • Ensuring critical user journeys behave as expected
  • Catching integration issues across the frontend stack
  • Validating app behavior across different browsers or screen sizes

Benefits of using Cypress E2E Angular Testing

Cypress is a fast, modern testing framework that aligns well with Angular’s reactive architecture and testing needs. It simplifies writing reliable E2E tests that simulate real user interactions.

Key benefits include:

  • Real-time debugging: Run tests in the browser with time-travel, live reloading, and built-in dev tools.
  • Fast and stable execution: No WebDriver dependency means fewer flakes and faster feedback.
  • Simplified setup: Built-in assertions, auto-waiting, and mock support reduce boilerplate.
  • Angular-friendly: Handles async operations, routing, and DOM updates with ease.
  • Developer-centric experience: Clean syntax, detailed error messages, and interactive UI.
  • CI/CD compatibility: Easily integrates into pipelines with support for parallelization.

Cypress Architecture and Directory Structure

To incorporate Cypress into a current Angular CLI project, simply use the Cypress Angular Schematic.

Launch this shell program in the folder containing your Angular project:

ng add @cypress/schematic

Important tasks accomplished by this command include:

  • To package.json, add Cypress and auxiliary npm packages.
  • Put the Cypress configuration file cypress.config.ts.
  • Update the angular.json configuration file to include the ng run commands.
  • A scaffold for your tests should be created in a subdirectory called cypress.
  • The installer prompts you to launch Cypress using the ng e2e program.
  •  It is safe to answer “Yes” if you are starting a fresh project without end-to-end tests.
  • Before version 12, ng e2e was used to launch Protractor in the Angular CLI.
  • If you have any legacy Protractor tests in the project and want to continue running them with ng e2e, respond “No” to the question.

Writing the First Test

There is a subdirectory named cypress in the project directory. It includes

  • All TypeScript files specifically in this directory’s tsconfig.json configuration,
  • the end-to-end tests’ directory,
  • a support directory of test-related resources such as custom commands,
  • a fixtures directory for test data.

The e2e directory contains the test files. Each test is a TypeScript file with the extension .cy.ts.

  • To use the npx cypress run, npx cypress open, and ng run $project-name$:cypress-open commands, you must first initiate the Angular development server with ng serve in a separate shell.
  • If the server is not accessible, Cypress will let you know by connecting to the baseUrl (http://localhost:4200).
  • The ng run $project-name$:cypress-run command launches the development server, begins the tests, and shuts down the server after the tests have finished.
  • Running “npx cypress open” will launch the test runner. In your situation, “E2E testing” should be selected as the testing method of choice.

Difference between E2E testing and Component testing

Then, after picking a browser, hit the “Start E2E Testing” button. This brings up Cypress’s main user interface, the test runner, in your browser.

Understanding E2E Testing in Angular Applications

Keeping the front-end code in alignment with the actual API endpoints and responses from the back end is significantly more difficult. Even if the front-end and the back-end share data transfer type information, inconsistencies may occur.

End-to-end testing aims to identify flaws that cannot be detected by other automated tests.

  • End-to-end testing begins with the launch of a browser, followed by visits to the application’s URL, and content reading, and makes keyboard and pointer input.
  • A common scenario involves the test subject completing and submitting an online form.

You can classify end-to-end testing frameworks as either using or not using WebDriver. Until Angular 12, Protractor was the usual framework for end-to-end testing. When developing Protractor, WebDriver served as the foundation. In Angular 12+, Protractor is no longer supported.

In freshly initiated CLI applications, no end-to-end testing infrastructure is set up by default. A mature end-to-end testing framework that does not rely on WebDriver is Cypress.

E2E testing vs Other Types of Testing

Unit tests and integration tests are quick and reliable but do not guarantee a fully functional application. End-to-end tests are sluggish and frequently fail erroneously, but they evaluate the application’s fitness.

Common E2E testing scenarios for Angular applications

Consider the scenario where evaluators must verify the availability of a Gmail account. It’s important to look at the following features:

  • Type this address into your browser’s address bar to go directly to the Gmail sign-in screen.
  • Log in with your real information.
  • Proceed to email. Look at the emails you have perused and the ones you haven’t.
  • Create a brand new message and send it off.
  • Give feedback and forward an email.
  • The Sent Items folder should be deleted. There, double-check your emails.
  • Navigate to the Spam folder. There, double-check your emails.
  • Choose “logout” to leave Gmail.

A testing environment closely matches the production environment is necessary for end-to-end tests. The entire application must be deployed, including the necessary front-end and back-end components.

Testing on real device-browser-OS combinations is crucial instead of emulators and simulators for accurate results. Utilize 3000+ browser-device combinations on the BrowserStack Real Device Cloud and evaluate end-to-end under actual user scenarios.

Automate Cypress Testing on Cloud

Writing E2E tests in Cypress for Angular Applications

End-to-end tests simulate real user behavior across the whole application. Each test typically has two main parts:

  • Interaction/Navigation: Defines how Cypress should interact with your app, like visiting pages or clicking buttons.
  • Assertion: Verifies that the application behaves as expected based on those interactions.

Cypress saves test files by default in /cypress/integration. Start by creating a new file inside that folder, such as sample.spec.ts.

In sample.spec.ts, put the following:

describe('The Home Page', () => { // (2)

it('Successfully loads', () => { // (2)

// NAVIGATION

// cypress will load '<http://localhost:4200>'. (3)

cy.visit('/');

// ASSERTION

cy.get('.highlight-card')

.children('span')

.should('have.text', 'testingApp app is running!');

});

});

There are two basic building blocks to be aware of, as is typical when writing tests:

  • describe(‘Name of block’, () => ); block: Constructs a block that compiles several linked tests into one unit.
  • it(“Descriptive term of the test,” ()=> {}”); block: The test itself.
  • Since you speak in natural language, the test’s name should make logic about the topic at hand. Using the following code as an example: it(“should open dropdown when you click on open button,” () => {} ); Use a moniker that non-developers can understand.

Previously specified “baseUrl” to be “http://localhost:4200” in cypress.json. That path will be the default for all commands that call for a URL.

They represent Cypress instructions and mean:

  • get: Retrieving one or more DOM elements using the selector.
  • children: obtain each DOM element’s offspring from a group of DOM elements.
  • should: make an assertion. The assertion is automatically attempted again until it succeeds or expires.

Note: You must first serve your application in order to try it. Launch a fresh terminal, go to the project folder, and type ng serve.

Run npx Cypress Open if you haven’t already.

Capture2

Your test is on the left, and the usual Angular project is on the right. You’ve examined the welcome remark. You will see the result in green if the test is effective.

Testing Component Interactions in Angular E2E Flows

End-to-end testing in Angular focuses on how users interact with the application’s UI, which is composed of nested, stateful components.

  • Use data-cy selectors: Add data-cy attributes to your HTML elements to make them easy to target in tests, especially in complex or reusable components.
  • Check parent-child behavior: Make sure actions in one part of the UI (like clicking a button or opening a modal) correctly affect other parts (like showing/hiding a list or loading new data).
  • Verify UI changes: Look for visible changes like validation messages, spinners, or elements being shown/hidden.
  • Scope your queries: Use .within() with cy.get() to focus on specific UI parts, especially when dealing with nested layouts or conditional components.

Examples:

  • Click Delete button and confirm the item disappears.
  • Switch tabs and check if the content changes.
  • Submit a form and look for a success message or alert.

These checks confirm that components work together as expected in real user scenarios, exactly what end-to-end tests are for.

Writing E2E tests in Cypress for Angular forms

Cypress makes it easy to test Angular forms by simulating real user actions, such as typing input, selecting options, and checking validations.

Example: Testing a Login Form (Reactive Forms)

describe('Login Form', () => {

  beforeEach(() => {

    cy.visit('/login');

  });



  it('validates and submits the form', () => {

    cy.get('[data-cy=submit]').click();

    cy.get('[data-cy=email-error]').should('contain', 'Email is required');

    cy.get('[data-cy=password-error]').should('contain', 'Password is required');



    cy.get('[data-cy=email]').type('test@example.com');

    cy.get('[data-cy=password]').type('securePass123');

    cy.get('[data-cy=submit]').click();



    cy.url().should('include', '/dashboard');

  });

});

Other Common Interactions

  • Checkbox: cy.get(‘[data-cy=terms]’).check().should(‘be.checked’);
  • Radio: cy.get(‘[data-cy=gender-female]’).check();
  • Dropdown: cy.get(‘[data-cy=country]’).select(‘Canada’);

Tips

  • Use data-cy for stable selectors.
  • Test both validation and success flows.
  • Cypress auto-waits, no need for cy.wait() in most cases.

Navigating in Angular Single Page Applications

In Angular SPAs, routing is handled by the Angular Router, which dynamically loads components without full page reloads. Cypress supports this with commands like:

  • cy.visit(): Loads the app’s entry point, typically ‘/’ or a specific route (e.g., /dashboard).
  • cy.url(): Asserts that navigation leads to the correct route after an action.
  • cy.go(‘back’ | ‘forward’): Simulates browser navigation through the Angular Router history stack.

Tip: Always ensure the Angular app is fully loaded before asserting routes. Use cy.url().should(‘include’, ‘/target-path’) to confirm successful navigation.

Handling Asynchronous Operations in Angular

Angular apps often run async tasks like HTTP calls and DOM updates using Zone.js. Cypress automatically waits for these tasks to complete before moving to the next step, making it a good fit for Angular’s async behavior.

Key points:

  • Automatic waiting: Cypress tracks DOM updates and waits for stability before continuing. No need for manual sleep or wait() in most Angular cases.
  • cy.intercept(): Use cy.intercept() to stub or wait for API calls triggered by Angular services. This helps stabilize tests and avoids flakiness.
  • Explicit waits (sparingly): Use cy.wait() only when mocking network responses or ensuring sequence timing (e.g., animations, debounce delays).

Tip: Always prefer automatic waiting and observable state verification over fixed delays to keep tests fast and reliable.

Advanced Cypress E2E Angular Testing

Take your Angular E2E testing further with these advanced strategies in Cypress:

  • Mock API calls using cy.intercept() to stub or spy on network requests for more stable, backend-independent tests. Example:
cy.intercept('GET', '/api/users', { fixture: 'users.json' })
  • Create custom Cypress commands (e.g., cy.login()) to reuse common steps like authentication or form setup.Defined in
cypress/support/commands.ts
  • Use fixtures and dynamic data to manage test inputs. Load data with cy.fixture() or generate it dynamically via setup scripts.
  • Handle authenticated routes by simulating login flows or setting tokens/cookies directly to access protected pages.
  • Debug tests effectively using cy.pause(), .log(), or .debug() along with Cypress’s built-in test runner UI.

These techniques help make your tests faster, more reliable, and easier to maintain in large Angular apps.

BrowserStack Automate Banner

Cypress Angular Testing on Real Device Cloud

Running Cypress Angular tests locally can miss browser and device-specific issues. Testing on a wide range of real browsers and devices is essential to ensure your app works smoothly across all environments.

BrowserStack Automate provides a cloud-based Selenium and Cypress testing platform with access to a real device cloud. It allows running Cypress tests in parallel at scale, with detailed logs, screenshots, and video recordings to help debug failures quickly.

Key benefits of BrowserStack Automate:

  • Test on real, up-to-date browsers and devices in real user conditions for accurate results
  • Parallel test execution for faster feedback and reduced test times
  • Comprehensive debugging tools, including logs, screenshots, and video playback
  • Early detection of browser- or device-specific issues
  • Easy integration with Cypress for seamless test automation at scale

Best Practices for Cypress E2E Angular Testing

Here’s a quick guide to best practices that make Cypress E2E testing for Angular reliable and efficient:

  • Use data-cy attributes to select elements reliably in Angular components.
  • Keep tests independent; they should run alone without relying on others.
  • Write tests that cover full user flows, not tiny, single-step checks.
  • Don’t store Cypress command results in variables—use .then() to handle values.
  • Start your Angular app before running tests; don’t launch it inside Cypress.
  • For Angular Material or UI libraries, test visible behavior, not internal code.
  • Avoid real API calls; use stubs with cy.intercept() or cy.request() instead.
  • Use Cypress for end-to-end flows; rely on Angular unit tests for internal logic.

Talk to an Expert

Conclusion

In concluding this Cypress Angular tutorial, setting up Cypress is simple. You don’t have to do any setup. The essential aspect is how quickly the test can be run and how the results can be interpreted through the user-friendly interface.

Tags
Automation Testing Cypress

Get answers on our Discord Community

Join our Discord community to connect with others! Get your questions answered and stay informed.

Join Discord Community
Discord