Testing
With
Protractor
Who Am I?
- Daniela Green
- Automation Developer @Wix
- danielagr@wix.com
Gonna Talk About...
- What is Protractor ??
- The frameworks inside Protractor
- How to use Protractor
- Protractor debugging tools
What Is Protractor?
- An end-to-end test framework for AngularJS applications
- A wrapper on top of WebDriverJS to control browsers
- A Node.js program
Protractor
- Framework to simulate user interaction with the browser
- Written by Julie Ralph -Software Engineer in Test at Google, Lead developer for Protractor
- First version release in 2013
- Public Github project
- https://github.com/angular/protractor
@juliemr is very active
Deep Diving Into
Protractor
System Structure
WebDriverJS
- WebDriver refers to the language bindings and the implementation of the browser control code
- WebDriverJS has an important difference from other languages - it is asynchronous
But Why Do I Care?
Webdriver
VS
WebdriverJS
Java
Javascript
JAVA
driver.get(p1);
driver.click(E1);
Javascript
driver.get(p1).then(function(){
driver.click(E1);
}
The Way To Deal With That:
-
Control Flow
- no Sleep
- no Wait
- no Promises
Control Flow
- Managing entirely asynchronous API (WebdriverJS)
- Queue of pending promises
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 are executed yet. The browser.get method is in the front of the control flow queue, and the name.getText() call is at the back.
The value of name.getText() at Point A is an unresolved promise object.
driver.get("http://www.google.com").
then(function() {
return driver.findElement(By.name("q"));
}).
then(function(q) {
return q.sendKeys("webdriver");
}).
then(function() {
return driver.findElement(By.name("btnG"));
}).
then(function(btnG) {
return btnG.click();
}).
then(function() {
return driver.getTitle();
}).
then(function(title) {
assertEquals("webdriver - Google Search", title);
});
Avoid doing this:
Easy To Catch Elements In the DOM
Protractor Global Variables
- element
- by
- browser
element, by
- element (by.css('#search'))
- element(by.model('name'))
by.model
In your test
In your application
element(by.model("myModel"));
<input ng-model="myModel" />
by.repeater
In your test
In your application
element( by.repeater('user in users'));
<ul>
<li ng-repeat="user in users" class="a">
<li ng-repeat="user in users" class="b">
</li>
</ul>
browser
- browser.get(url)
- browser.switchTo().iframe(indexOrName)
- browser.wait(1000)
expect is adapted to Promises:
expect(name.getText()).toEqual('Jane Doe');
Instead of this:
name.getText().then(function (name) {
expect(name).toEqual('jane Doe')
})
Do this:
element(by.css('#searchBtn')) === $('#searchBtn')
Use the '$' Symbol, It's equal
Jasmine
- Jasmine is a testing framework for javascript
- Protractor uses Jasmine for its test syntax
- describe, it, expect, toBe...
describe(‘A suite’, function() {
it(‘contains spec with an expectation’, function() {
expect(true).toBe(true);
});
});
Test Structure
Let See How It Really Works!
Installing Protractor
(via Node Package Manager)
npm
- Node Package Manager
- Manage dependencies for an application
npm
Example - install Protractor
https://www.npmjs.com/package/protractor
In Terminal:
Example - Install Protractor
In our project:
- Creates 'Protractor' package in node-modules
Example - Install Protractor
Running Tests
- conf.js
- spec.js
conf.js
- How to connect to selenium
- Tells specs location
- Browser options
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
specs: ['angularPage-spec.js'],
capabilities: {
browserName: 'chrome',
'chromeOptions': {
'loggingPrefs': {
'browser': 'ALL'
}
}
};
spec.js
- The tests
How to run?
protractor someConfFile.js
In the terminal:
Command
calc
Protractor
+
Non-Angular Apps
- Switching from ng-app pages to non ng-apps pages
- Ignoring the protractor synchronisation (control flow)
Testing with non-ng pages
How the ???? do we deal with it?
Ignoring The Angular Synchronisation!
browser.ignoreSynchronization = true;
HOW?
- Page objects
- Tests specs
Best Practices
Page Objects
settings form:
settings.js
Page object file
Page test file
function HomePage(url) {
this.url = url;
this.nameInput = element(by.model('yourName'));
}
HomePage.prototype.get = function() {
browser.get(this.url);
}
HomePage.prototype.setName = function(name) {
this.nameInput.sendKeys(name);
}
module.exports = HomePage;
var HomePage = require('../HomePage.js');
describe('HomePage Tests', function() {
var homePage = new HomePage('https://angularjs.org');
it('should verify homePage loads', function() {
homePage.get();
//...
}
}
Debugging Tools
- browser.pause()
- in your test code:
- browser.debugger()
- in the terminal:
- elementExplorer.js
protractor debug conf.js
browser.pause();
debugging using elementexplorer.js:
- Start your webDriver server:
webdriver-manager start
2. Run the elementexplorer (project root) :
elem
.../protractor-example/node_modules/protractor/bin(master)$ ./elementexplorer.js someUrl
So... Lets sum it up:
- Protractor and its frameworks (selenium, jasmine)
- Advantages using the protractor (control flow, special Angular attributes..)
- How to install protractor + run tests
- debugging tools
Thank You!
Protractor
By danielagreen
Protractor
- 1,868