Migrating from Protractor to Cypress

The Angular team has announced that the support of Protractor in the Angular CLI will be discontinued and that the Protractor project itself will be abandoned.

With the upcoming Angular CLI v12 release, this means that the CLI now generates projects without the e2e configuration.

You could add Protractor back to a v12 project using:

ng generate @schematics/angular:e2e --related-app-name my-app

But all this points to an obvious task for us Angular developers: we have to migrate to an alternative.

The Angular CLI will not support another e2e solution out-of-the-box in the near future, but the amazing Angular community does offer a few options.

The biggest question left is: which e2e solution can we pick?

Cypress

Because there are a lot of options nowadays! Protractor was written for AngularJS v1, and back in the days, there were very few possible solutions. Apart from Selenium, which was a precursor, and that Protractor uses under the hood. Protractor is getting old though, not really fit to test Angular applications, and is not maintained actively (even if it is still massively used inside Google).

A few popular alternatives are possible:

I revealed our choice in the title: at Ninja Squad, we use Cypress for most (all?) of our projects. We do use Playwright sometimes for automation and the API is very nice (and is available in multiple languages).

But Cypress offers a fairly unbeatable developer experience with its UI allowing to see a snapshot of the application for each step of a test. It also comes with a wide ecosystem and a very active community.

Migrating an Angular project

We’re going to use a schematic to ease the migration:

ng add @cypress/schematic

This command:

  • adds cypress to the dependencies of your application,
  • adds a cypress directory with a dummy test
  • adds a cypress.json config file
  • updates the angular.json file.

Note that you can also manually remove protractor, ts-node and jasmine-spec-reporter as they are only used by Protractor in the CLI.

I also add the cypress files to the lint task.

You can then run the tests with the usual:

ng e2e

Note that the tests run by default with a UI and in watch mode. You can tweak the angular.json file if that’s not to your taste, or add the options manually (for example on CI):

ng e2e --headless --no-watch

A few cool tricks

On some of our projects, we use Percy to add visual diff testing. Percy offers an integration with Cypress. You just need to add some dependencies:

npm install --save-dev --save-exact @percy/cypress @percy/cli

Then add import '@percy/cypress'; to your command.ts file.

You can now use:

cy.percySnapshot('name-of-the-snapshot')

in your tests. This will take a snapshot with the specified name, upload it to the Percy platform, and compare it, pixel by pixel, with a reference (the first build you approve).

This is super easy to set up, and can run on CI once in a while to make sure you don’t have regressions.

Another cool extension is cypress-axe. Axe is an accessibility test tool and catches accessibility issues in your applications. You can also use Axe with a browser extension, but using it in automated tests is a better way to prevent regressions.

cypress-axe allows you to add accessibility checks in your e2e test suite.

npm i --save-exact --save-dev cypress-axe

Then in your tests you need to inject axe at the beginning of the test:

beforeEach(() => cy.injectAxe());

and check if there is no accessibility issue whenever needed:

cy.checkA11y();

This helped us catch quite a few issues on the projects we used it.

I hope all this will help you migrate to Cypress!



blog comments powered by Disqus