> For the complete documentation index, see [llms.txt](https://web-dev-guide.wishtack.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://web-dev-guide.wishtack.io/testing/end-to-end-testing.md).

# End to End Testing

By definition, unit-tests **don't test interactions between modules** and some side-effects.

The whole application **must also be tested automatically**.

## Protractor

Protractor is an e2e *(end-to-end)* testing framework developed by the AngularJS team.

It can test AngularJS or Angular web applications but also **non-AngularJS web applications**.

Protractor uses the Selenium webdriver to communicate with browsers and control them.

Protractor tests are written in **JavaScript&#x20;*****(or TypeScript)*****&#x20;with Jasmine**.

```javascript
describe('angularjs homepage todo list', () => {

    it('should add a todo', () => {
    
        browser.get('https://angularjs.org');

        /* Add an element. */
        element(by.model('todoList.todoText')).sendKeys('write first protractor test');
        element(by.css('[value="add"]')).click();

        /* Check todo list content. */
        const todoList = element.all(by.repeater('todo in todoList.todos'));
        expect(todoList.count()).toEqual(1);
        expect(todoList.get(0).getText()).toEqual('write first protractor test');

    });

});
```

{% hint style="success" %}
**Page objects:**

Factorize each view's *(or page)* logic in a dedicated and **reusable class** *(separation of concerns)*.
{% endhint %}

```javascript
import { PageTodo } from './pages/page-todo';

describe('angularjs homepage todo list', () => {

    it('should add a todo', () => {

        const pageTodo = new PageTodo();
    
        browser.get(pageTodo.pageUrl());

        /* Add an element. */
        pageTodo.addTodo({title: 'write first protractor test'});

        /* Check todo list content. */
        const todoElementList = pageTodo.todoElementList();

        expect(todoElementList.count()).toEqual(1);
        expect(todoElementList.get(0).getText()).toEqual('write first protractor test');

    });

});
```

## Cross-Browser & Cross-Device Test Automation with Browserstack

Browserstack is a cloud service with a large set of remotely controllable devices and browsers.

With Browserstack, you can run your Protractor tests on mobile and desktop.

<https://www.browserstack.com>

{% embed url="<https://www.browserstack.com>" %}

Browserstack records logs, captures screenshots and records testing videos.

{% hint style="info" %}
Apps can also be tested manually on Browserstack.
{% endhint %}

{% hint style="info" %}
You can open a tunnel with Browserstack to test locally hosted applications.
{% endhint %}

## Cypress

Cypress is another JavaScript End to End Testing Framework.

{% hint style="warning" %}
It doesn't use Selenium so it's not cross-browser.
{% endhint %}

With Cypress, it is easier to have a Test-Driven Development approach as tests can be re-run automatically on every change without having to respawn a browser.

<https://www.cypress.io/>

{% embed url="<https://www.cypress.io/>" %}

## Takeaways

### Cross-Browser & Cross-Device E2E Testing Automation Blog Post

<https://blog.wishtack.com/2015/05/07/cross-browser-testing-test-automation-with-protractor-and-browserstack/>

{% embed url="<https://blog.wishtack.com/2015/05/07/cross-browser-testing-test-automation-with-protractor-and-browserstack/>" %}

### Boilerplate to run your first protractor tests

<https://github.com/wishtack/wt-protractor-boilerplate>

{% embed url="<https://github.com/wishtack/wt-protractor-boilerplate>" %}

### Useful modules

<https://github.com/wishtack/wt-protractor-runner>

{% embed url="<https://github.com/wishtack/wt-protractor-runner>" %}

<https://github.com/wishtack/wt-protractor-utils>

{% embed url="<https://github.com/wishtack/wt-protractor-utils>" %}
