I have a code (credit to #kishanpatel) Traverse-through-each-row-for-a-column-text which will verify whether the value is added in grid or not. i want to put this in my page object. i was thinking to add the elements into page object and the if condition in a different helper file similar to selenium but i am not sure is that the right appraoch. see the details below.
if I call the mo.helper in spec.ts, it says gridcheck.ispresent() is not a function. How to handle this scenario?
code:
it('verify the grid that master obligation is added', function () {
var testvar = "'test_protractor'";
var row_check = element(by.xpath("//div[contains(text()," + testvar + ")]"));
if (row_check.isPresent()) {
row_check.getText().then(function (msg) {
if (row_check.isPresent()) {
console.log("Grid contains========== " + msg);
}
});
}
});
i have the below method in mo.ts(page object page):
this.grid = function (value) {
// var testvar = "'test_protractor'";
var row_check = element(by.xpath("//div[contains(text()," + value + ")]"));
return require('./mohelper.ts')
}
}
mohelper.ts:
require('../page/mo.ts')
var mohelper = function () {
this.gridvaluepresent = function () {
require('../page/mo.ts')
var gridcheck = mo.grid();
if(gridcheck.isPresent()) {
gridcheck.getText().then(function (msg) {
if (gridcheck.isPresent()) {
console.log("Grid contains========== " + msg);
}
})
}
}
}
module.exports = new mohelper();
spec.ts:
it('go to corresponding module and verify whether the master obligation is added ', function () {
browser.sleep(10000);
taxhome.selectmodule;
taxhome.selectmoduledropdown(1);
mo.grid("test_protractor");
mohelper.gridvaluepresent();
});
Couple of things here to be considered -
1) Most of the protractor's api methods are asynchronous i.e. they return promises you have to resolve/reject them to perform actions.
isPresent() also returns a promise, you need to resolve it-
var row_check = element(by.xpath("//div[contains(text()," + value + ")]"));
row_check.isPresent().then(function(present) {
if(present) { // it returns a boolean value
row_check.getText().then(function (msg) {
console.log("Grid contains========== " + msg);
});
}
});
2) Since you are using TypeScript , use its syntax rather than conventional js-
let row_check = element(by.xpath("//div[contains(text()," + value + ")]")); // Block scoped variable using 'let'
row_check.isPresent().then((present) => { // notice the thick arrow
if(present) {
row_check.getText().then((msg) => {
console.log("Grid contains========== " + msg);
});
}
});
3) Maintain Page Objects efficiently and readable-
All the helper methods, elements etc. for a single page should go in a single page object. Write them in separate classes, typescript uses the concept of classes and transpiles them to global functions.
moHelper.ts
import {ElementFinder, element} from 'protractor';
export class MoHelper {
public row_check: ElementFinder; // its of element finder type
gridValueCheck(value : string) {
row_check = element(by.xpath("//div[contains(text()," + value + ")]")); // please use Css selectors instead of Xpath!
row_check.isPresent().then((present) => {
if(present) {
row_check.getText().then((msg) => {
return msg; // here you are returning the msg of the row from your page!
});
}
});
}
}
Your spec.ts should validate that row msg!
import {MoHelper} from './moHelper.ts'
let mo: MoHelper = new MoHelper();
it('go to corresponding module and verify whether the master obligation is added ', () => {
browser.sleep(10000); // please refrain from using sleeps instead use Expected Conditions
taxhome.selectmodule;
taxhome.selectmoduledropdown(1);
expect(mo.gridValueCheck("test_protractor")).toEqual("Your Expected Message");
});
Please find the links for your reference to understand the above in more detail-
isPresent
Getting started with typescript
Using page objects in protractor/style guide
Expected Conditions
The search should be based on the first name and last name. During entering the letters the middle letters from the word should not come. It should come only only from the first name and last name. I got the auto-complete code from code pen and Github but as per requirement I need auto search;
Like:
Auto Search
You should look at creating your own custom directive or using an existing one like this https://github.com/guylabs/ion-autocomplete
This is my code snippet for auto-complete which I used but I need First name and last name Search (It should not search random letters) -
var airlines = [{"fs":"LCI","iata":"LF","icao":"LCI","name":"Lao Central Airlines ","active":true},{"fs":"TGU","iata":"5U","icao":"TGU","name":"TAG","active":true},{"fs":"BT","iata":"BT","icao":"BTI","name":"Air Baltic","active":true},{"fs":"9J","iata":"9J","icao":"DAN","name":"Dana Airlines","active":true},{"fs":"2O","iata":"2O","icao":"RNE","name":"Island Air Service","active":true},{"fs":"NPT","icao":"NPT","name":"Atlantic Airlines","active":true},{"fs":"C8","iata":"C8","icao":"ICV","name":"Cargolux Italia","active":true},{"fs":"FK","iata":"FK","icao":"WTA","name":"Africa West","active":true},{"fs":"8K","iata":"8K","icao":"EVS","name":"EVAS Air Charters","active":true},{"fs":"W8","iata":"W8","icao":"CJT","name":"Cargojet","active":true},{"fs":"JBW","iata":"3J","icao":"JBW","name":"Jubba Airways (Kenya)","active":true},{"fs":"TNU","iata":"M8","icao":"TNU","name":"TransNusa","active":true},{"fs":"HCC","iata":"HC","icao":"HCC","name":"Holidays Czech Airlines","active":true},{"fs":"APJ","iata":"MM","icao":"APJ","name":"Peach Aviation","active":true},{"fs":"TUY","iata":"L4","icao":"TUY","name":"LTA","active":true},{"fs":"LAE","iata":"L7","icao":"LAE","name":"LANCO","active":true},{"fs":"L5*","iata":"L5","icao":"LTR","name":"Lufttransport","active":true},{"fs":"QA","iata":"QA","icao":"CIM","name":"Cimber","active":true},{"fs":"KBZ","iata":"K7","icao":"KBZ","name":"Air KBZ","active":true},{"fs":"L2","iata":"L2","icao":"LYC","name":"Lynden Air Cargo","active":true},{"fs":"MPK","iata":"I6","icao":"MPK","name":"Air Indus","active":true},{"fs":"CAO","icao":"CAO","name":"Air China Cargo ","active":true},{"fs":"BEK","iata":"Z9","icao":"BEK","name":"Bek Air","active":true},{"fs":"IAE","iata":"IO","icao":"IAE","name":"IrAero","active":true},{"fs":"GL*","iata":"GL","name":"Airglow Aviation Services","active":true},{"fs":"ATN","iata":"8C","icao":"ATN","name":"ATI","active":true},{"fs":"GU","iata":"GU","icao":"GUG","name":"Aviateca Guatemala","active":true},{"fs":"GHY","icao":"GHY","name":"German Sky Airlines ","active":true},{"fs":"SS","iata":"SS","icao":"CRL","name":"Corsair","active":true},{"fs":"XK","iata":"XK","icao":"CCM","name":"Air Corsica","active":true},{"fs":"W9*","iata":"W9","icao":"JAB","name":"Air Bagan","active":true},{"fs":"Z8*","iata":"Z8","icao":"AZN","name":"Amaszonas","active":true},{"fs":"D2","iata":"D2","icao":"SSF","name":"Severstal Aircompany","active":true},{"fs":"SNC","iata":"2Q","icao":"SNC","name":"Air Cargo Carriers","active":true},{"fs":"PST","iata":"7P","icao":"PST","name":"Air Panama","active":true},{"fs":"VV","iata":"VV","icao":"AEW","name":"Aerosvit Airlines","active":true},{"fs":"UJ","iata":"UJ","icao":"LMU","name":"AlMasria","active":true},{"fs":"9U","iata":"9U","icao":"MLD","name":"Air Moldova","active":true},{"fs":"NF","iata":"NF","icao":"AVN","name":"Air Vanuatu","phoneNumber":"678 238 48","active":true},{"fs":"NJS","iata":"NC","icao":"NJS","name":"Cobham Aviation","active":true}];
airlines = airlines.sort(function(a, b) {
var airlineA = a.name.to();
var airlineB = b.name.toLowerCase();
if(airlineA > airlineB) return 1;
if(airlineA < airlineB) return -1;
return 0;
});
console.log(airlines);
angular.module('ionicApp', ['ionic'])
.factory('FlightDataService', function($q, $timeout) {
var searchAirlines = function(searchFilter) {
console.log('Searching airlines for ' + searchFilter);
var deferred = $q.defer();
var matches = airlines.filter( function(airline) {
if(airline.name.toLowerCase().indexOf(searchFilter.toLowerCase()) !== -1 ) return true;
})
$timeout( function(){
deferred.resolve( matches );
}, 100);
return deferred.promise;
};
return {
searchAirlines : searchAirlines
}
})
.controller('MyCtrl', ['$scope', 'FlightDataService', function($scope, FlightDataService) {
$scope.myTitle = 'Auto Complete Example';
$scope.data = { "airlines" : [], "search" : '' };
$scope.search = function() {
FlightDataService.searchAirlines($scope.data.search).then(
function(matches) {
$scope.data.airlines = matches;
}
)
}
}]);
I have this:
element(by.id('x')).sendKeys('xxx').then(function(text) {
element(by.id('y')).sendKeys('yyy').then(function(text) {
element(by.id('z')).sendKeys('zzz').then(function(text) {
expect(element(by.id('myButton')).isEnabled()).toBe(true);
})
});
});
The button 'myButton' is enabled when the elements 'x', 'y' and 'z' all have values. It's my understanding that sendKeys returns a promise.
So is this the only way that I can check if 'myButton' which depends on data in all the three fields is enabled?
You don't need to chain any promises because protractor will wait until all the statements are done: https://github.com/angular/protractor/blob/master/docs/control-flow.md
element(by.id('x')).sendKeys('xxx');
element(by.id('y')).sendKeys('yyy');
element(by.id('z')).sendKeys('zzz');
expect(element(by.id('myButton'));
If you want to resolve multiple promises use:
var webdriver = require('selenium-webdriver');
webdriver.promise.fullyResolved(promises);
For example: https://github.com/angular/protractor/blob/d15d35a82a5a2/lib/protractor.js#L327
this is a bit after the fact, but:
var x = element(by.id('x')).sendKeys('xxx');
var y = element(by.id('y')).sendKeys('yyy');
var z = element(by.id('z')).sendKeys('zzz');
myFun(x,y,z).then(function(){
expect(element(by.id('myButton')).isEnabled()).toBe(true);
});
// in a common function library
function myFun(Xel,Yel,Zel) {
return protractor.promise.all([Xel,Yel,Zel]).then(function(results){
var xText = results[0];
var yText = results[1];
var zText = results[2];
});
}
but an even better way:
var x = element(by.id('x')).sendKeys('xxx');
var y = element(by.id('y')).sendKeys('yyy');
var z = element(by.id('z')).sendKeys('zzz');
myFun(x,y,z);
//isEnabled() is contained in the expect() function, so it'll wait for
// myFun() promise to be fulfilled
expect(element(by.id('myButton')).isEnabled()).toBe(true);
// in a common function library
function myFun(Xel,Yel,Zel) {
return protractor.promise.all([Xel,Yel,Zel]).then(function(results){
var xText = results[0];
var yText = results[1];
var zText = results[2];
});
}
another way is to chain the .thens together:
element(by.id('x')).sendKeys('xxx').
then(function(xtext){
element(by.id('y')).sendKeys('yyy');
}).then(function(ytext){
element(by.id('z')).sendKeys('zzz');
}).then(function(ztext){
expect(element(by.id('myButton')).isEnabled()).toBe(true);
});
it seems protractor supports all - protractor.promise.all
read more at:
https://github.com/angular/protractor/issues/2062#issuecomment-94030055
describe('promise.all', function() {
it('should greet the named user', function() {
browser.get('http://juliemr.github.io/protractor-demo');
$('div').click().then(function () {
return protractor.promise.all([
$('h3').getText(),
$('h4').getText()
]);
}).then(function (params) {
console.log('A');
});
});
it('does something else', function() {
console.log('B');
});
If you want to return an object instead of a list, seems you can also do that - used it and it's awesome
element.all(by.css('.fc-event-inner')).map(function(el) {
return {
time: el.findElement(by.className('fc-event-time')).getText(),
title: el.findElement(by.className('fc-event-title')).getText()
}
});
See the properties are actually promises.. protractor will resolve them.