End-to-end tests for AngularJS and Angular 5 — Intro

Anton Larichev
3 min readDec 11, 2017

Sooner or later, in any company, regardless of its size, it becomes important to deploy only fully tested applications in production. To save human resources on manual testing of the whole application, it is necessary to focus on unit testing, which ensures the correct operation of each component separately. But if you want to test the whole application — e2e (end-to-end) tests are an answer.

There are tons of testing frameworks: Nightwatch, CasperJS, Protractor. I personally recommend Protractor for Angular and AngularJS. In this article, I will cover basic principles of e2e test code writing that will make your code easy to read and maintain. But only you can decide to fallow them or not.

Here we will use TypeScript instead of JavaScript. It has a lot of advantages:

  • Strongly typed
  • Autocomplete in VSCode and many other IDE
  • It implements many concepts of OOP (inheritance, polymorphism, encapsulation …)
  • TypeScript is a superset of JavaScript that is compiled into JavaScript, so any JavaScript code will run in the TypeScript environment.

Let get to work!


The structure of the test folders should coincide with the structure of the site (or be approximate to it). For example, if you have a blog that has post list and post page with structure /blog, /blog/post/1, then a folder with a test for the post page has to be in the blog’s test folder.

Test file types

For convenient work your code should be separated by code blocks with different types:

  • *.spec.ts — test description for pages or components
  • *.page.ts — describe all objects on page and function to interact with them.
  • *.object.ts — describe a separate object that is repeated on several pages and functions to work with it.

This structure makes it easy to maintain tests. Even if you change the layout, you just need to change bindings on page.ts or object.ts and your tests will work.

Element selectors

Use this priority of functions to select elements on the page:

  • by.model or by.binding
  • by.id
  • by.class
  • by.css

Never use XPath, because, you will ruin test with the slightest change of page structure. And try not to select element by text. Who knows, when it may changes.

Complex components

If you have any complex component that used on different pages (for example shop item), you can describe it like this:

After select card list you can access card elements with the help of locator() function:

Functions in *.page.ts and *.object.ts

It is good practice to move all interaction function that has more than one line of code from specs to *.page.ts and *.object.ts. That makes the code more readable:

In these files, we are describing not only elements but methods to interact with them.

Function names

Name function in camelCase. It has to be easy to understand what function is doing or returning from its name. For example, if it returns boolean use “is” prefix:

For each function, it is necessary to set augments and return types. This way compiler will check types error even before you build your app and show them in IDE:

Shared components

If your app or website has shared components on different pages, you have to make shared tests in your test app. For this, create “Shared” folder in your project and put the component folder with *.spec.ts inside it. Then in your page test just import component description

or even run a test:

Core functions

Sometimes you have to use the same function in different specs, like getFirstVisible(), that shows first visible element in an array. These functions you should put in the separate file (utils.spec).

In the next article, we will create a test project, configure web pack build and write our first e2e tests.

Translated from: https://alariblog.com/blogpost/e2e-test



Anton Larichev

IT Director in car selling company. In love with TypeScript, NodeJS and Angular.