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!