1. Protractor global variables:
a. browser: Eg. browser.get()
b. element : Eg. element(by.model('yourName'))
c. by : Eg. element(by.model('yourName'))
d. protractor: Eg. protractor.Key
2.element() vs element.all()
Single element:
element( by.binding('appName') );
Collection of elements:
element.all( by.css('[ng-click="openPage()"]') ).get(2).click();
3. by.binding:
In your application:
<span ng-bind="myModel"></span>
<!-- or -->
<span>{{myModel}}</span>
In your test:
element( by.binding('myModel') );
4. by.model:
In your application:
<input ng-model="myModel" />
In your test:
element( by.model('myModel') );
5. by.repeater:
a. In your application
<ul>
<li ng-repeat="user in users">
<span>{{user.name}}</span>
</li>
</ul>
b. In your test
element( by.repeater('user in users').row(0).column('name') );
6. by.css:
a. In your application
<button ng-click="sendMail()">Send mail!</button
b. In your test
element( by.css('[ng-click="sendMail()"]') );
7.Few more
a. by.select()
b. by.partialButtonText()
c. elementArrayFinder.each()
Full list of available methods
http://www.protractortest.org/#/api
8.Promises based
All Protractor methods are "asynchronous" and return promises.
// Example of getText() promise
element( by.model('zipcode') ).getText()
.then(function(val) {
var num = val.substring(0, 4);
var isNum = !isNaN(num);
expect( isNum ).toBeTruthy();
});
9. Simple Page objects
var AngularHomepage = function() {
this.nameInput = element(by.model('yourName'));
this.greeting = element(by.binding('yourName'));
this.get = function() {
browser.get('http://www.angularjs.org');
};
this.setName = function(name) {
this.nameInput.sendKeys(name);
};
};
10.Node.JS exports and require
a. Your Page Object file
var AngularHomepage = function() {
this.nameInput = element(by.model('yourName'));
this.greeting = element(by.binding('yourName'));
// ...
};
module.exports = AngularHomepage;
b. Your Test file
var AngularHomepage = require('./homepage.po.js');
describe('HomePage Tests', function() {
var angularHomepage = new AngularHomepage();
angularHomepage.nameInput.sendKeys('Rafael');
//...
});
11.Separate your tests in various test suites
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
capabilities: { 'browserName': 'chrome' },
suites: {
homepage: 'tests/e2e/homepage/**/*Spec.js',
search: ['tests/e2e/contact_search/**/*Spec.js']
},
jasmineNodeOpts: { showColors: true }
};
Running specific suite of tests
protractor protractor.conf.js --suite homepage
12.Enable multiCapabilities
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
multiCapabilities: [
{
'browserName' : 'chrome'
},
{
'browserName' : 'firefox'
}
],
specs: ['example-spec.js'],
jasmineNodeOpts: {
showColors: true
}
};
13.Using onPrepare
a. Set window size before starting the tests
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
capabilities: {
'browserName': 'chrome'
},
onPrepare: function() {
browser.driver.manage().window().setSize(1600, 800);
},
jasmineNodeOpts: {
showColors: true
}
};
b.Export xml results of your Automated Suites
First, install jasmine-reporters:
>>npm install jasmine-reporters
And to keep xml results in Timestamp directories, install mkdirp package:
>>npm install mkdirp
c.//config.js
exports.config = {
onPrepare: function() {
var folderName = (new Date()).toString().split(' ').splice(1, 4).join(' ');
var mkdirp = require('mkdirp');
var newFolder = "./reports/" + folderName;
require('jasmine-reporters');
mkdirp(newFolder, function(err) {
if (err) {
console.error(err);
} else {
jasmine.getEnv().addReporter(new jasmine.JUnitXmlReporter(newFolder, true, true));
}
});
},
};
14.Using params
Your config.js
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
capabilities: { 'browserName': 'chrome' },
// This can be changed via the command line as:
// --params.login.user 'ngrocks'
params: {
login: {
user: 'protractor-br',
password: '#ng123#'
}
},
jasmineNodeOpts: { showColors: true }
};
Your test:
describe('login page', function() {
var params = browser.params;
it('should login successfully', function() {
element( by.model('username') ).sendKeys( params.login.user );
element( by.model('password') ).sendKeys( params.login.password );
element( by.css('[ng-click="login()"]') ).click();
expect( element(by.binding('username') ).getText() ).toEqual( params.login.user );
});
});
15.Using jasmineNodeOpts
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
capabilities: { 'browserName': 'chrome' },
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000,
isVerbose: true,
includeStackTrace: true
}
};
16.Protractor waits for Angular to finish its work
Though you can tell it not to be that smart about your non-Angular app:
beforeEach(function() {
return browser.ignoreSynchronization = true;
});
works for Non anguler based apps too
In your config.js
onPrepare: function() {
global.isAngularSite = function(flag) {
browser.ignoreSynchronization = !flag;
};
}
In your test
beforeEach(function() {
isAngularSite(false); // isAngularSite(true), if it's an Angular app!
});