Reputation: 35
I have the below code where I need to fill up an array with the drop list elements and return that array from the function so that I assert that array from the jasmine test case.
getAllCategoryName(): string[]{
var usageCategoryFromPage: string[] = [];
E2EUtil.click(this.usageCategoriesPage.pageinationDropDownBtn);
E2EUtil.click(this.usageCategoriesPage.highestPageRecords);
element.all(by.xpath("//tbody[@class='ui-datatable-data ui-widget-content ui-datatable-hoverable-rows']/tr[*]/td[1]"))
.each(function (element, index) {
element.getText().then(function (text){
usageCategoryFromPage.push(text);
})
})
.then(function(){
console.log("Size of the array from inside the then block " + usageCategoryFromPage.length);
usageCategoryFromPage.forEach(element => {
console.log("Usage Category Elements from inside the the function " + element);
});
return usageCategoryFromPage; // size here is 18
});
console.log("Usage Category size after the then block " +usageCategoryFromPage.length)
usageCategoryFromPage.forEach(element => {
console.log("From Usage Category Page outside the then function" + element);
});
return usageCategoryFromPage; // size here is 0
}
The problem is that the usageCategoryFromPage
array is being returned as 0 outside the then block.
Jasmine test case looks like :
it('Validate the Usage Category droplist values matches with the Usage Categories Table',() => {
usageCategoriesPage.navigateTo();
let allCategoryName = usageCategoriesPage.getAllCategoryName();
allCategoryName.forEach(element => {
console.log("Array elements printed from the test case " + element);
});
Can any one please help?
Upvotes: 0
Views: 3635
Reputation: 13712
1) All protractor API are Async and return promise.
2) You need to consume promise's eventual value in then()
.
3) If a promise follows then()
chain: a promise.then().then()....then()
,
The eventual value of the promise dependents the return value of the last then()
in the then()
chain.
For example:
element(all()).each()
// return a promise and its eventual value is null
element(all()).getText()
// return a promise and its eventual value is an String Array,
// each String is the visible text of each found HTML element
var res = element(all()).getText()
.then(txts => {
// the eventual value of promise: element(all()).getText()
// will be passed-into the callback function of the next then()
// thus txts is the String Array
// you can determine return anything or not return anything in this callback function
// assume we return another String Array
return ['a', 'b'];
})
// the return value in the previous `then()` callback function
// will be passed-into next `then()` callback function
.then(value => {
// value = ['a', 'b']
// assume we return the first String in Array
return value[0]
});
res
is a promise following then()
chain, its eventual value depends on the last then()
.
res.then(value=>{
console.log(value);
// print out a
})
Fixed code:
getAllCategoryName(): string[]{
var usageCategoryFromPage: string[] = [];
E2EUtil.click(this.usageCategoriesPage.pageinationDropDownBtn);
E2EUtil.click(this.usageCategoriesPage.highestPageRecords);
// you missed `return` at here.
return element
.all(by.xpath("//tbody[@class='ui-datatable-data ui-widget-content ui-datatable-hoverable-rows']/tr[*]/td[1]"))
.each(function (element, index) {
element.getText().then(function (text){
usageCategoryFromPage.push(text);
})
})
.then(function(){
console.log("Size of the array from inside the then block " + usageCategoryFromPage.length);
usageCategoryFromPage.forEach(element => {
console.log("Usage Category Elements from inside the the function " + element);
});
return usageCategoryFromPage; // size here is 18
});
}
it('Validate the Usage Category droplist values matches with the Usage Categories Table',() => {
usageCategoriesPage.navigateTo();
let allCategoryName = usageCategoriesPage.getAllCategoryName();
// getAllCategoryName() return a promise,
// thus you need to consume the eventual value of promise in then()
allCategoryName.then(categories => {
console.log("Array elements printed from the test case " + categories.join(', '));
});
}
More concise implement of getAllCategoryName()
through element.all().getText()
getAllCategoryName(): string[]{
E2EUtil.click(this.usageCategoriesPage.pageinationDropDownBtn);
E2EUtil.click(this.usageCategoriesPage.highestPageRecords);
return element
.all(by.xpath("//tbody[@class='ui-datatable-data ui-widget-content ui-datatable-hoverable-rows']/tr[*]/td[1]"))
.getText();
}
Upvotes: 1