genkio / blog

Stay hungry stay foolish
https://slashbit.github.io/blog/
0 stars 1 forks source link

End-to-end testing with Protractor #135

Open genkio opened 7 years ago

genkio commented 7 years ago

Getting Started

Install dependencies

$ npm install -g protractor
$ npm install --save-dev gulp-angular-protractor
$ webdriver-manager update

Create protractor.conf.js file with minimal default configuration

// An example configuration file.
// https://raw.github.com/angular/protractor/master/example/conf.js
exports.config = {
  // webdriver-start can start on default port 4444
  seleniumAddress: 'http://localhost:4444/wd/hub',

  // Capabilities to be passed to the webdriver instance.
  capabilities: {
    'browserName': 'chrome'
  },

  // Options to be passed to Jasmine-node.
  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000
  },

  // The params object will be passed directly to the Protractor instance,
  // and can be accessed from your test as browser.params. It is an arbitrary
  // object and can contain anything you may need in your test.
  params: { }
};

Add gulp task

gulp.task('test', function(callback) {
  gulp
    .src('tests/e2e/*_spec.js')
    .pipe(gulpProtractorAngular({
        'configFile': 'protractor.conf.js',
        'debug': false,
        'autoStartStopServer': true
    })).on('error', function(e) {
        console.log(e);
    }).on('end', callback);
});

The first test

// tests/e2e/hello_spec.js
'use strict';

describe('hello test', function() {
  it('should work', function() {
    browser.get('http://www.angularjs.org');
    element(by.model('yourName')).sendKeys('Keibay');
    var greeting = element(by.binding('yourName'));

    expect(greeting.getText()).toEqual('Hello Keibay!');
  });
});
$ gulp test

Page Objects

A page object is an object-oriented class that serves as an interface to a page of your AUT.

How to define it

// tests/e2e/pages/LoginPage.js
class LoginPage {
  constructor() {
    this.emailInput = element(by.model('user.email'));
    this.passInput = element(by.model('user.password'));
  }
  get() {
    browser.get(`http://localhost:3000/`);
  }
  setEmail(email) {
    this.emailInput.sendKeys(email);
  }
  setPass(pass=browser.params.user.password) {
    this.passInput.sendKeys(pass);
  }
  login() {
    element(by.buttonText('Login')).click();
  }
}

module.exports = LoginPage;

How to use it

// tests/e2e/auth_spec.js
const LoginPage = require('./pages/LoginPage');

describe('authentication', ()=> {
  it('should log user in', ()=> {
    let loginPage = new LoginPage();
    loginPage.setEmail(vars.user.randomEmail);
    loginPage.setPass();
    loginPage.login();
  })
});

In Action

Work with $timeout (makes protractor not wait for Angular promises)

browser.ignoreSynchronization = true;
browser.get(url);
// do something
browser.ignoreSynchronization = false;

Find elements

// by css
element(by.css('#agree')).click();
// by css (ng-click)
element(by.css('[ng-click="act()"]'));
// by ng-model
element(by.model('detail.price'))
// get attribute via promise
element(by.id('someId'))
  .getAttribute('href')
  .then((url)=> {
    expect(typeof url).toBe('string');
  });
// by repeater
element(by.exactRepeater('row in rows'));

Assertions

expect(elem).isPresent()).toBeTruthy();

Delete cookies

browser.driver.manage().deleteAllCookies();

Slow things down

browser.sleep(5000);

Send keys

// upon element
selectedElement.sendKeys(1, protractor.Key.ENTER, protractor.Key.ESCAPE);
// without element selected
browser.actions().sendKeys(protractor.Key.ENTER).perform();

Upload image

Upload feature powered by angular-file-upload


let imageToUpload = '../../app/assets/images/sample.png';
let absolutePath = path.resolve(__dirname, imageToUpload);

element(by.css('input[type="file"]')).sendKeys(absolutePath);



More Sources
---

[Practical End-to-End Testing with Protractor](http://www.ng-newsletter.com/posts/practical-protractor.html)
[Protractor for AngularJS](http://ramonvictor.github.io/protractor/slides/#/)
[angular-eonasdan-datetimepicker](https://github.com/atais/angular-eonasdan-datetimepicker/tree/master/tests)