You have unlimited access as a PRO member
You are receiving a free preview of 3 lessons
Your free preview as expired - please upgrade to PRO
Contents
Recent Posts
- Object Oriented Programming With TypeScript
- Angular Elements Advanced Techniques
- TypeScript - the Basics
- The Real State of JavaScript 2018
- Cloud Scheduler for Firebase Functions
- Testing Firestore Security Rules With the Emulator
- How to Use Git and Github
- Infinite Virtual Scroll With the Angular CDK
- Build a Group Chat With Firestore
- Async Await Pro Tips
Cypress.io - Angular End-to-End Testing Tutorial
Episode 117 written by Jeff DelaneyHealth Check: This lesson was last reviewed on and tested with these packages:
- Cypress v3
- Angular v6
Find an issue? Let's fix it
Source code for Cypress.io - Angular End-to-End Testing Tutorial on Github
When you start a new Angular CLI app it generates some end-to-end testing files for Protractor, but do actually use them? For most, the answer is no. This is a shame because end-to-end testing can be transformative for the app development process. In my experience, test-driven development is far more efficient at reducing bugs than strong-typing or using a redux-style state management library. All of these things can help, but e2e testing is unmatched in its ability to catch poor UX implementations and automate tedious UI edge-case tinkering.
Cypress.io will literally change your life as a developer - it’s that good. First of all, it’s easy to setup and learn. You can start writing meaningful tests with minimal effort or learning curves to get over. Each line of code is expressive, for instance, cy.get('button').click()
is all you might need to ensure some button exists on a page. Second, it will catch user-experience issues much faster than you will manually - plus it gives you the ability to time travel directly to the problem area. Third, it’s free, so it’s really a no-brainer to give this a few hours of your time.
Initial Setup
At this point, I’ll assume you have an existing app - naturally my app is built with Angular 6 and Firebase.
npm install cypress --save-dev |
Update the package.json
scripts to run Cypress for E2E tests as an alternative to Protractor.
{ |
Now you can run the following commands to complete the setup.
ng serve |
Adding Types and/or TypeScript
It is possible to setup Cypress with TypeScript with some extra config, but I find the benefits of doing so marginal. The API is very intuitive even with vanilla JS and we can use the typings without needing to transpile TS.
The easiest way to add types is to just import them into a plain JS file, for example in cypress/integration/hello.spec.js
:
/// <reference types="cypress" /> |
Now you have most of the the benefits of TS in JS.
Controlling the Viewport Size
It is a good idea to test your UI on various device sizes. You can change the viewport size on individual specs with cy.viewport(...)
or set global defaults in the cypress.json file.
{ |
The Most Basic Spec
Let’s start with a basic test suite that looks for for an h1
tag on the home page. You should be able to read this code and understand what’s going on.
|
Important Commands
Here’s a quick breakdown of the cy
commands we’ll use in this lesson. This is a very, very small sample of what Cypress offers, so checkout the API docs.
You can select things with:
contains
- Contains will look for matching text, super convenient for finding links and buttons.get
- Works just like the$
operator in jQuery. You pass it a selector, such as a CSS class, id, or element name and it returns that element from the DOM.url
- grabs the URL from the browser
Then test those things with:
should
- Allows you to make an assertion based on an element you’ve selected.and
- works just likeshould
, but is chained to add multiple assertions.
Testing the Firebase User Auth Process with Cypress
If using Firebase, I recommend setting up your tests to run in a dedicated testing project. Cypress is just like a real user, so your specs will read/write live data.
User auth is often the single most important aspect of end-to-end testing. Let’s take a look at how we might validate our email/password auth flow.
Random Text Fixtures
We need a fake user to sign up for the app. Let’s install the chance.js library (or Faker if you prefer) to randomly generate the dummy data on the fly.
npm i --save-dev chance @types/chance |
Then import Chance into your project for access to an unlimited amount of random data.
import Chance from 'chance'; |
Filling out Forms with Cypress
Best practice: When selecting elements, try to use the component selector name or an attribute that is unlikely to change, such as input[name=foo]
. Using CSS classes or ids will make your tests brittle because it’s common for developers to change their names.
A user can sign-up for our app by clicking around elements in the UI - let’s make sure we wired up our UI elements properly.
The type
method can be chained to a form input to type into it. An added bonus is that the spec will fail your form cannot be typed into, so you get implicit testing without having to think about anything.
it('signs up a new user', () => { |
Creating Resuable Code in Cypress
There’s a good chance that will want to have a logged in user in multiple different test suites. Cypress allows you to override or create new commands on the cy
namespace. Let’s create a login command in the cypress/support/commands.js
file:
Cypress.Commands.add('login', (email, pass) => { |
This command is now available to use in any spec and will result in a logged-in user for this session.
it('can do logged-in user stuff', () => { |
The End
Cypress has changed the way I think about end-to-end testing in Angular. I used to dread it, now I love it. Good e2e specs can be a huge time-saver on complex apps and will prevent regressions that cost you new users and/or revenue.