AngularJS : E2E Testing : Protractor

[Fuente: https://github.com/angular/protractor]

Protractor Build Status

Protractor is an end-to-end test framework for AngularJS applications. Protractor is a Node.js program built on top of WebDriverJS. Protractor runs tests against your application running in a real browser, interacting with it as a user would.

Test Like a User

Protractor is built on top of WebDriverJS, which uses native events and browser-specific drivers to interact with your application as a user would.

For AngularJS Apps

Protractor supports Angular-specific locator strategies, which allows you to test Angular-specific elements without any setup effort on your part.

Automatic Waiting

You no longer need to add waits and sleeps to your test. Protractor can automatically execute the next step in your test the moment the webpage finishes pending tasks, so you don’t have to worry about waiting for your test and webpage to sync.

Protractor vs Angular Scenario Runner

The new, preferred end-to-end testing framework is called Protractor. Unlike the Angular scenario runner, Protractor is built on Selenium’s WebDriver, which is an API, written as extensions, for controlling browsers.

WebDriver has extensions for all sorts of different browsers, including the most popular. We gain speed and stability in our tests by developing against true web browsers.

Luckily, Protractor is built atop the Jasmine framework, so we don’t need to learn a new framework in order to use it. We can also install it as a standalone test runner or embed it in our tests as a library.

Use Protractor in a non-AngularJS app

you only need to access the webdriver instance by using browser.driver:

browser.driver.find(by.css('[data-ptor="submit-btn"]'));		

Getting Started

The Protractor documentation for users is located in the protractor/docs folder.

To get set up and running quickly:

Once you are familiar with the tutorial, you’re ready to move on. To modify your environment, see the Protractor Setup docs. To start writing tests, see the Protractor Tests docs.

To better understand how Protractor works with the Selenium WebDriver and Selenium Sever see the reference materials.

Choosing a Framework

Protractor supports three behavior driven development (BDD) test frameworks: Jasmine, Mocha, and Cucumber. These frameworks are based on JavaScript and Node.js and provide the syntax, scaffolding, and reporting tools you will use to write and manage your tests.

Prerequisites

Protractor is a Node.js program. To run, you will need to have Node.js installed. You will download Protractor package using npm, which comes with Node.js. Check the version of Node.js you have by running node --version. It should be greater than v0.10.0.

By default, Protractor uses the Jasmine test framework for its testing interface. This tutorial assumes some familiarity with Jasmine.

This tutorial will set up a test using a local standalone Selenium Server to control browsers. You will need to have theJava Development Kit (JDK) installed to run the standalone Selenium Server. Check this by running java -version from the command line.

Setup

Use npm to install Protractor globally with:

npm install -g protractor

This will install two command line tools, protractor and webdriver-manager. Try running protractor --version to make sure it’s working.

The webdriver-manager is a helper tool to easily get an instance of a Selenium Server running. Use it to download the necessary binaries with:

webdriver-manager update

Now start up a server with:

webdriver-manager start

This will start up a Selenium Server and will output a bunch of info logs. Your Protractor test will send requests to this server to control a local browser. You can see information about the status of the server at http://localhost:4444/wd/hub.

Write a test

Open a new command line or terminal window and create a clean folder for testing.

Protractor needs two files to run, a spec file and a configuration file.

Let’s start with a simple test that navigates to the todo list example in the AngularJS website and adds a new todo item to the list.

Copy the following into todo-spec.js:

describe('angularjs homepage todo list', function() {
  it('should add a todo', function() {
    browser.get('http://www.angularjs.org');

    element(by.model('todoText')).sendKeys('write a protractor test');
    element(by.css('[value="add"]')).click();

    var todoList = element.all(by.repeater('todo in todos'));
    expect(todoList.count()).toEqual(3);
    expect(todoList.get(2).getText()).toEqual('write a protractor test');
  });
});

The describe and it syntax is from the Jasmine frameworkbrowser is a global created by Protractor, which is used for browser-level commands such as navigation with browser.get.

Configuration

Now create the configuration file. Copy the following into conf.js:

exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',
  specs: ['todo-spec.js']
};

This configuration tells Protractor where your test files (specs) are, and where to talk to your Selenium Server (seleniumAddress). It will use the defaults for all other configuration. Chrome is the default browser.

Run the test

Now run the test with:

protractor conf.js

You should see a Chrome browser window open up and navigate to the todo list in the AngularJS page, then close itself (this should be very fast!). The test output should be 1 test, 2 assertions, 0 failures. Congratulations, you’ve run your first Protractor test!

Learn More

Learn more with the Tutorial.

The WebDriver Control Flow

The WebDriverJS API is based on promises, which are managed by a control flow and adapted for Jasmine. A short summary about how Protractor interacts with the control flow is presented below.

Promises and the Control Flow

WebDriverJS (and thus, Protractor) APIs are entirely asynchronous. All functions return promises.

WebDriverJS maintains a queue of pending promises, called the control flow, to keep execution organized. For example, consider this test:

  it('should find an element by text input model', function() {
    browser.get('app/index.html#/form');

    var username = element(by.model('username'));
    username.clear();
    username.sendKeys('Jane Doe');

    var name = element(by.binding('username'));

    expect(name.getText()).toEqual('Jane Doe');

    // Point A
  });

At Point A, none of the tasks have executed yet. The browser.get call is at the front of the control flow queue, and thename.getText() call is at the back. The value of name.getText() at point A is an unresolved promise object.

Protractor Adaptations

Protractor adapts Jasmine so that each spec automatically waits until the control flow is empty before exiting. This means you don’t need to worry about calling runs() and waitsFor() blocks.

Jasmine expectations are also adapted to understand promises. That’s why this line works – the code actually adds an expectation task to the control flow, which will run after the other tasks:

  expect(name.getText()).toEqual('Jane Doe');

Migrating Existing Test Scripts (from Angular Scenario Runner)

ptor = protractor instance

browser().navigateTo(url)

ptor.get(url)

browser().location().url()

ptor.getCurrentUrl()

binding(name)

ptor.findElement(protractor.By.binding(‘{{status}}’)).getText()

input(name).enter(value)

ptor.findElement(protractor.By.input(“user”)).sendKeys(value)

input(name).check()

ptor.findElement(protractor.By.input(“user”)).click();

input(name).select(value)

See Select below.

input(name).val()

ptor.findElement(protractor.By.input(“user”)).getText()

repeater(selector, label).count()

ptor.findElements(protractor.By.repeater(“cat in pets”)).length()

repeater(selector, label).row(index)

ptor.findElements(protractor.By.repeater(“cat in pets”)).row(index)

repeater(selector, label).column(binding)

ptor.findElements(protractor.By.repeater(“cat in pets”)).row(index)..column(binding)

select(name).option(value)

ptor.findElement(protractor.By.id(‘selectId’).click();

ptor.findElement(protractor.By.css(‘option [value=”0”]’’).click();

select(name).options(value1, value2…)

ptor.findElement(protractor.By.id(‘selectId’).click();

ptor.findElement(protractor.By.css(‘option [value=”0”]’’).click();

ptor.findElement(protractor.By.css(‘option [value=”2”]’’).click();

ptor.findElement(protractor.By.css(‘option [value=”4”]’’).click();

element(selector, label)

See WebElement Methods Mentioned Earlier

Plugins de Gulp útiles