Protractor - Full Course at one place
PROTRACTOR API
Protractor is an End TO End Framework for testing Angular and Angular JS applications.
Protractor is a Node.js program built on top of WebDriverJS.
- Node.js is an Open Source/cross platform written in JavaScript to develop server side network applications.
- WebDriverJS is the official javascript implementation of selenium. Or WebDriverJS is the JavaScript binding for the Selenium WebDriver API.
=======================================================================
PROCEDURE
=======================================================================
Step 1 : Download and install node.js
https://nodejs.org/en/download/
node -v or node --version
npm -v or npm --version
Step 2 : Install Protractor
npm install -g protractor
protractor --version
Step 3 : Run command
webdriver-manager update
Step 4 : Find conf.js file at C:\Users\Administrator\AppData\Roaming\npm\node_modules\protractor\example
On cmd goto the location of this file ( Test File for us the its GoogleTest.js )
To run : protractor conf.js
Note: below in example the conf.js file is under Config folder so , the path is :
Note: below in example the conf.js file is under Config folder so , the path is :
protractor .\\Config\conf.js
=======================================================================
LOCATORS:
=======================================================================
Below the webdriver ~ driver
WebDriver ---------------------------------------Protractor Syntax
1. driver.by() -------------------------------------by
2. driver.findElement()-------------------------element(...)
3. driver.findElements()------------------------element.all(...)
4. driver.findElement(by.css("..."))----------$("...")
5. driver.findElements(by.css("..."))---------$$("...")
=======================================================================
// Types of Assertion
=======================================================================
1. jasmine.anything : It returns true if the actual value is not NULL / UNDEFINED.
2. jasmine.any: It takes a type / class name as an expected value. And on match returns TRUE.
3. jasmine.objectContaining: to check certain Key - Value pair.
4. jasmine.arrayContaining: to Check certain VALUE from Array.
1. toBe(Expected) : expect the actual value to be === to the expected value.
2. toBeNaN() / toBeNull() : expect the actual value to be NaN / Null.
3. toBeFalsy()/toBeTruthy(): expect the actual value to be FALSY/TRUTHY
4. toBeDefined()/toBeUndefined(): expect the actual value be defined /undefined.
5. toContain(expected): expect the actual value to contain a specific value.
6. toEqual(expected) / toMatch(expected): expect the actual value to CONTAIN a SPECIFIC VALUE / EQUAL to EXPECTED ( using === ) / MATCH a REGULAR EXPRESSION ( == )
7. toBeCloseTo(expected,precisionopt):
8. toBeGreaterThan(expected)/toBeLessThan(expected): expect the actual value to GREATER / LESS that the expected value
9. toBeInstanceOf(expected) : expect the actual to be an instance of the expected class.
10. toBeGreaterThanOrEqual(expected) / toBeLessThanOrEqual(expected) : Expect the actual value GREATER / LESS than EQUAL to the expected value.
11. toThrowError(expected-OPTIONAL, message-OPTIONAL): expect a function to THROW and ERROR.
describe(" suiteAnkur ",function(){
function area(radius){
let type = typeof(radius);
if(type == ("string") || type == ("undefined")){
throw `area cannot be calculated for ${type}`
}else{
return Math.PI*radius*radius;
}
};
function perimeter(radius){
let type = typeof(radius);
console.log(" the type is: ",type);
if(type == ("string") || type == "undefined")
throw `perimeter cannot be calculated for type ${type}`
else
return 2*Math.PI*radius;
}
it("Area of a circle ",function(){
expect(area(20)>0).toBeTruthy(); //Postive number output
expect(area(20)>0).not.toBeNaN(); //Postive number input and Output NOT TO BE NaN
area("strg"); //Postive number output
});
});
describe("suite",function(){
let addNewTask = element(by.model("todoList.todoText"));
let getTextFirst= element(by.xpath("//h1[@class='ng-binding']"));
let addName = element(by.model("yourName"));
let addButton = $("input[value='add']");
let getText = $$("input[type='checkbox']+span");
beforeEach(function(){
browser.get("https://angularjs.org/");
});
it("test cases 2way binding",function(){
addNewTask.sendKeys("hello world");
addButton.click();
element.all(by.cssContainingText("input[type='checkbox']+span","hello world")).count().then(function(textNumber){
console.log("The total number: ",textNumber);
expect(textNumber).toBe(1);
});
});
it("test cases 1way binding",function(){
addName.sendKeys("hello world");
getTextFirst.getText().then(function(txt){
console.log("the text are:",txt);
expect(txt).toContain("hello world");
});
});
});
=======================================================================
//SYNCHRONIZATION OF SCRIPT:
=======================================================================
- Implicit Wait:
in conf file:
exports.confif = {
onPrepare : function(){
browser.manage().timeouts().implicitlyWait(3000);
}};
- Explicit Wait :
let zebra = async function(){
let txt = await $("...").getText();
console.log(" The text is :", txt);
}
------------------------------------------------------------------------
describe("testing suite",function(){=======================================================================
let textBox = element(by.model("todoList.todoText"));
let submitButton = $("input[type='Submit']");
let txtList = $$("input[ng-model='todo.done']+span");
xit("test cases ",function(){
browser.get("https://angularjs.org/");
textBox.sendKeys("123456");
submitButton.click();
txtList.each(function(link){
link.getText().then(function(text){
console.log("The TEXT is :",text);
if(text == ("123456") ){
console.log(" the item added :",text)
}else{
console.log(" Not addedd :",text)
}
});
});
});
it("test cases two", function(){
browser.get("https://angularjs.org/");
textBox.sendKeys("123456");
submitButton.click();
txtList.each(async function(link){
let text = await link.getText();
// console.log("THE TEXT is:",text);
if(text == ("123456") ){
console.log(" the item added :",text)
}else{
console.log(" Not addedd :",text)
}
});
});
});
Project Hierarchy
=======================================================================
=======================================================================
if Angular Js Application is to automate then:
=======================================================================
browser.ignoreSynchronization = false; // optional
browser.waitForAngularEnabled(true);
browser.get('/page-containing-angular.html');
if NON Angular Js Application is to automate then:
browser.ignoreSynchronization = true; // optional
browser.waitForAngularEnabled(false);
browser.get('/page-NON-angular.html');
exports.config = {
directConnect: false,
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome'
},
// Framework to use. Jasmine is recommended.
framework: 'jasmine',
// seleniumAddress: 'http://localhost:4444/wd/hub',
// Spec patterns are relative to the current working directory when
// protractor is called.
specs: ['..//testCases//GoogleTest.js'],
// Options to be passed to Jasmine.
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
}
};
=======================================================================
Example of scripting
====================================================================
describe("Google Test Page",function(){
beforeAll(function(){
console.log("this is before ALL ...");
});
afterAll(function(){
console.log("this is after all...");
});
beforeEach(function(){
browser.waitForAngularEnabled(false);
browser.get("https://www.google.com");
browser.ignoreSynchronization = true;
console.log("This is before each...")
});
afterEach(function(){
console.log("this is after each...");
});
it('Enter Text',function(){
let firstInput = element(by.css("input[title='Search']"));
firstInput.sendKeys("Hello World");
browser.sleep(3000);
});
it('Enter Text And Click the search',function(){
let textKeyword = element(by.css("input[title='Search']"));
let btn = element(by.xpath("(//input[@name='btnK'])[2]"));
textKeyword.sendKeys("Ankur Malviya");
btn.click();
});
})
// -------EXPLICIT WAIT------- //
describe("testing suite ",function(){
var ex = protractor.ExpectedConditions;
let first = element(by.model('first'));
let second = $('input[ng-model=second] ');
var button = $('#gobutton');
it("Explicit wait test cases",function(){
browser.get("http://juliemr.github.io/protractor-demo/");
browser.wait(ex.visibilityOf(first),3000," expected FIRST element to be visible");
first.sendKeys(10);
browser.wait(ex.presenceOf(second),5000,'second should be visible');
second.sendKeys(2000);
browser.wait(ex.elementToBeClickable(button));
browser.sleep(3000);
});
});
===
=======================================================================
Handling DropDown
=======================================================================
element.all(by.options("value for (key, value) in operators")).each(function(ele){
ele.getText().then(function(txt){
console.log(" the text is :---",txt);
if(txt=="-"){
ele.click();
}
})
});
=======================================================================
Script to Automate Translate in Hindi
=======================================================================
describe("Translate Suite", function(){
var url = "https://translate.google.co.in/";
var inputText = element(by.css("div.QFw9Te textarea"));
var outputLang = element(by.css("c-wiz[class='bvzp8c DlHcnf'] div[class='ykTHSe'] input[placeholder='Search languages']"));
var outputText = element(by.xpath("//span[@jsname='W297wb']"));
var button = element(by.xpath("((//div[@class='akczyd']/div)[2]//following-sibling::button)[3]"));
var speaker = element(by.xpath("(//div[@class='BdDRKe']/div)[1]"));
it("Translate to Hindi",async function(){
browser.get(url);
inputText.sendKeys(" Hello World ");
button.click();
outputLang.sendKeys("Hindi").sendKeys(protractor.Key.ENTER);
browser.sleep(3000);
let opText = await outputText.getText();
console.log(" the text is :", opText);
speaker.click();
browser.sleep(5000);
});
});
==================================================================
TakesScreen Shots
==================================================================
>>> Import /Output first above describe:
let writeStream = require("fs")
>>>Enjoy Screenshot
let elementOne = $('hello'); // for particular element
elementOne.takeScreenshot().then(function(img){
let file = writeStream.createWriteStream("./screenShotFolder/picOne.png");file.write(new Buffer(img,"base64"));file.end();
});
browser.takeScreenshot().then(function(img){ // for full Page
let file = writeStream.createWriteStream("./screenShot/fullPage.png");file.write(new Buffer(img,"base64"));file.end();
});
let writeStream = require("fs") // this is to import all Input /output -fs module
describe(" test suite for MMT application ",function(){
var url = "https://www.makemytrip.com/";
var charterFlight = element(by.xpath("//span[@class='chNavIcon appendBottom2 chSprite chCharterFlights']"));
var roundTripRadioButton = element(by.xpath("//li[text()='Round Trip']/span"));
var fromCity = element(by.css('#fromCity'));
var toCity = element(by.css('#toCity'));
var toCitySuggestion = element(by.xpath("//p[contains(text(),'Raipur A')]"));
var searchButton = element(by.xpath("//a[text()='Search']"));
var header = element(by.css('div.cfsw'));
var flight = element(by.xpath("//li[@class='makeFlex hrtlCenter font10 makeRelative lhUser userLoggedOut']"));
fromCITY = function(city){
fromCity.sendKeys(city);
element(by.xpath("//p[contains(text(),'"+city+"')]")).click();
};
toCITY = function(city){
toCity.sendKeys(city);
element(by.xpath("//p[contains(text(),'"+city+"')]")).click();
};
it("MMT Test Case",function(){
browser.get(url);
flight.click();
charterFlight.click();
roundTripRadioButton.click();
// fromCITY("Raipur A");
// toCITY("Delhi");
//to take Header screen shot
header.takeScreenshot().then(function(img){
let file = writeStream.createWriteStream("./screenShot/header.png");
file.write(new Buffer(img,"base64"));
file.end();
});
//to take whole page screen shot
browser.takeScreenshot().then(function(img){
let file = writeStream.createWriteStream("./screenShot/FullPage.png");
file.write(new Buffer(img,"base64"));
file.end();
});
});
});
====================================================================
Handle Alert
====================================================================
When do alert occurs:
- When page load / close
- sometimes click / rightclick on Elements
- During wrong entry / saving some information
COMMANDS:
alert = browser.switchTo().alert();
alert.accept();alert.dismiss();alert.accept();alert.getText();
To get Text :
alert.getText().then(function(message){
console.log(" The alert message is :",message)
});
==================================================================
Mouse ACTION
==================================================================
Perform mouse actions:
- click()/doubleClick() clicks a mouse button
- perform() Executes an actions in sequence
- sendKeys() to Type
- keyDown() / keyUp() Performs a modifier key Down / Up
- mouseDown()/mouseUp() moves a mouse up/down * AND KEEP ON Pressed until viceversa action not performed.
- mouseMove() Move the mouse to specific location.
browser.actions().mouseDown().perform();
so there are three ways:browser.actions()
.click(uName)
.sendKeys("an")
.keyDown(protractor.Key.SHIFT)
.sendKeys("gg")
.keyUp(protractor.Key.SHIFT)
.sendKeys("aaaaaa")
.perform();
//anotherway
passWord.sendKeys("aa",protractor.Key.SHIFT,"gg",protractor.Key.NULL,"ww");
//anotherway
uName.sendKeys("ww",protractor.Key.chord(protractor.Key.SHIFT,"gg"),"aa");
describe("Test Suite Mouse Action Keyboard Actions",function(){
var url = "https://ssm.guru/demo/";
var uName = element(by.xpath("//input[@name='user']"));
var passWord = element(by.xpath("//input[@name='pass']"));
var button = element(by.xpath("//button[@type='submit' and contains(text(),'Login')]"));
it("Login",function(){
browser.get(url);
browser.actions()
.click(uName)
.sendKeys("an")
.keyDown(protractor.Key.SHIFT)
.sendKeys("gg")
.keyUp(protractor.Key.SHIFT)
.sendKeys("aaaaaa")
.perform();
//anotherway
passWord.sendKeys("aa",protractor.Key.SHIFT,"gg",protractor.Key.NULL,"ww");
//anotherway
uName.sendKeys("ww",protractor.Key.chord(protractor.Key.SHIFT,"gg"),"aa");
browser.sleep(5000);
button.click();
browser.sleep(5000);
});
});
==================================================================
Use of DATA PROVIDER
==================================================================
though its a part of JASMINE FW but we have to install explicitly by:
npm install jasmine-data-provider --save -dev
npm WARN install Usage of the `--dev` option is deprecated. Use `--include=dev` instead.
added 1 package, and audited 2 packages in 6s
found 0 vulnerabilities
1. Way to make in use oF Data Provider
let useDp = require("jasmine-data-provider");
useDp([{input1:10,input2:20},{input1:30,input2:40},{input1:50,input2:60}],function(data){
describe("testing Data Provider Test Suite",function(){
inputOne.sendKeys(data.input1);
inputTwo.sendKeys(data.input2);
});
});
2. Way to make in use oF Data Provider
var useDp = require("jasmine-data-provider");
describe("test suite",function(){
// Use of data provider
function dataProvider(){
return [
{input1:22,input2:33},
{input1:11,input2:300},
{input1:100,input2:888},
];
}
// Use DP
useDp(dataProvider,function(data){
it("test case one",function(){
inputOne.sendKeys(data.input1);
inputTwo.sendKeys(data.input2);
});
});
});
describe("test suite",function(){
// Use of data provider
function dataProvider(){
return [
{input1:22,input2:33},
{input1:11,input2:300},
{input1:100,input2:888},
];
}
// Use DP
useDp(dataProvider,function(data){
it("test case one",function(){
inputOne.sendKeys(data.input1);
inputTwo.sendKeys(data.input2);
});
});
});
3. Way to make in use oF Data Provider
1st to create a separate file :
module.exports = {
inputData: {
"set1": {input1:100,input2:200},
"set2": {input1:1001,input2:2001},
"set3": {input1:1002,input2:2002}
}
};
var useDp = require("jasmine-data-provider");
var input = require("..//dataSet/dataSet1.js");
describe("test data suite",function(){
// Use DP
useDp(input.inputData,function(data){
it("test case one",function(){
inputOne.sendKeys(data.input1);
inputTwo.sendKeys(data.input2);
});
});
});
EXAMPLES
let useDp = require("jasmine-data-provider");
let writeStream = require("fs");
useDp([{input1:10,input2:20},{input1:30,input2:40},{input1:50,input2:60}],function(data){
describe("testing Data Provider Test Suite",function(){
var url = "https://juliemr.github.io/protractor-demo/";
var inputOne = element(by.model("first"));
var inputTwo = element(by.model("second"));
var go = $("#gobutton");
var ex = protractor.ExpectedConditions;
it("test",function(){
browser.get(url);
browser.wait(ex.visibilityOf(inputOne),3000,"element should be visible");
inputOne.sendKeys(data.input1);
inputOne.takeScreenshot().then(function(img){
let file = writeStream.createWriteStream("./screenShot/inputOne.png");
file.write(new Buffer(img,"base64"));
file.end();
});
inputTwo.sendKeys(data.input2);
inputTwo.takeScreenshot().then(function(img){
let file = writeStream.createWriteStream("./screenShot/inputTwo.png");
file.write(new Buffer(img,"base64"));
file.end();
});
browser.takeScreenshot().then(function(img){
let file = writeStream.createWriteStream("./screenShot/calculator.png");
file.write(new Buffer(img,"base64"));
file.end();
});
});
});
});
//3
var useDp = require("jasmine-data-provider");
var input = require("..//dataSet/dataSet1.js");
describe("test data suite",function(){
var inputOne = element(by.model("first"));
var inputTwo = element(by.model("second"));
var go = $("#gobutton");
// Use DP
useDp(input.inputData,function(data){
it("test case one",function(){
browser.get("https://juliemr.github.io/protractor-demo/");
inputOne.sendKeys(data.input1);
inputTwo.sendKeys(data.input2);
browser.sleep(3000);
});
});
});
DATA from ARRAY:
let useDp = require("jasmine-data-provider");
describe("suite",function(){
function data() {
return [
2,
4,
5,
10
];
};
useDp(data,function(t){
it("data",function(){
console.log(`test data ${t} haina`,t);
});
});
});
==================================================================
Use of JASMINE SPEC REPORTER
==================================================================
need to import JASMINE SPEC REPORTER
npm install jasmine-spec-reporter --save -dev
PS C:\Users\ProtractorWorkspace\ProjectOne> npm install jasmine-spec-reporter --save -dev
npm WARN install Usage of the `--dev` option is deprecated. Use `--include=dev` instead.
added 2 packages, and audited 4 packages in 2s
found 0 vulnerabilities
==================================================================
Use of ALLURE REPORTS
==================================================================
TO Install package:
npm install jasmine -allure-reporter
PS C:\Users\Documents\ProtractorWorkspace\ProjectOne> npm install jasmine-allure-reporter --dev -save
npm WARN install Usage of the `--dev` option is deprecated. Use `--include=dev` instead.
up to date, audited 16 packages in 1s
found 0 vulnerabilities
let report = require("jasmine-spec-reporter").SpecReporter;
let allureReport = require("jasmine-allure-reporter");
exports.config = {
directConnect: "true",
seleniumAddress: "http://localhost:4444/wd/hub/",
capabilities: {browserName:"chrome"},
framework: "jasmine",
specs:["..//testCases/allureTest.js"],
onPrepare: function(){
browser.waitForAngularEnabled(false);
jasmine.getEnv().addReporter(new report({
displayFailureSummary: true,
displayFailuredSpec : true,
displaySuiteNumber : true,
displaySpecDuration : true,
displayPendingSpec : true
}));
jasmine.getEnv().addReporter(new allureReport({
resultDir : "allure-results"
}));
jasmine.getEnv().afterEach(function(ss){
browser.takeScreenshot().then(function(img){
allure.createAttachment("Screenshot",function(){
return new Buffer(img,"base64")},
"image/png")();
ss();
});
});
jasmine.getEnv().beforeEach(function(done){
browser.takeScreenshot().then(function(img){
allure.createAttachment("Screenshot",function(){
return new Buffer(img,"base64")
},"image/png")();
done();
});
});
}
};
==================================================================
Use of Multiple Browsers & Parallel Instances
==================================================================
exports.config = {
multiCapabilities: [
{browserName:"chrome",sharedTestFiles:"true",maxInstances:3},
{browserName:"firefox"}
],
PS C:\Users\Documents\ProtractorWorkspace\ProjectOne> protractor .\config\confAll.js
[03:44:20] I/launcher - Running 2 instances of WebDriver
.[03:44:42] I/testLogger -
------------------------------------
[03:44:42] I/testLogger - [chrome #01] PID: 1156
[chrome #01] Specs: C:\Users\Documents\ProtractorWorkspace\ProjectOne\testCases\allTest.js
[chrome #01]
[chrome #01] [03:44:20] W/driverProviders - Using driver provider directConnect, but also found extra driver provider parameter(s): seleniumAddress
[chrome #01] [03:44:20] I/direct - Using ChromeDriver directly...
[chrome #01] Started
[chrome #01] Jasmine started
[chrome #01] (node:1156) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
[chrome #01] (Use `node --trace-deprecation ...` to show where the warning was created)
[chrome #01] .
[chrome #01] testing suite
[chrome #01] √ test case
[chrome #01]
[chrome #01]
[chrome #01]
[chrome #01]
[chrome #01] 1 spec, 0 failures
[chrome #01] Finished in 3.827 seconds
[chrome #01]
[chrome #01] Executed 1 of 1 spec SUCCESS in 4 secs.
[03:44:42] I/testLogger -
[03:44:42] I/launcher - 1 instance(s) of WebDriver still running
.[03:45:06] I/testLogger -
------------------------------------
[03:45:06] I/testLogger - [firefox #11] PID: 864
[firefox #11] Specs: C:\Users\Documents\ProtractorWorkspace\ProjectOne\testCases\allTest.js
[firefox #11]
[firefox #11] [03:44:20] W/driverProviders - Using driver provider directConnect, but also found extra driver provider parameter(s): seleniumAddress
[firefox #11] [03:44:20] I/direct - Using FirefoxDriver directly...
[firefox #11] Started
[firefox #11] Jasmine started
[firefox #11] (node:864) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.
[firefox #11] (Use `node --trace-deprecation ...` to show where the warning was created)
[firefox #11] .
[firefox #11] testing suite
[firefox #11] √ test case
[firefox #11]
[firefox #11]
[firefox #11]
[firefox #11]
[firefox #11] 1 spec, 0 failures
[firefox #11] Finished in 3.308 seconds
[firefox #11]
[firefox #11] Executed 1 of 1 spec SUCCESS in 3 secs.
[03:45:06] I/testLogger -
[03:45:06] I/launcher - 0 instance(s) of WebDriver still running
[03:45:06] I/launcher - chrome #01 passed
[03:45:06] I/launcher - firefox #11 passed
==================================================================
POM : runs at Suite Level
==================================================================
directConnect: "true",
seleniumAddress: "http://localhost:4444/wd/hub/",
// specs: ["..//testCases/allTest.js"],
suites : {
homePage : "..//testCases/allTest.js",
secondPage : ["..//testCases/GoogleTest","..//testCases/dataProviderTest.js"],
},
---------------------------
******************
Comments
Post a Comment