Returning a value from a from a protractor promise inside a function
Solution 1
Thanks to @alecxe for starting me off on the right foot.
I found a solution I am now using quite a bit after reading this.
By passing an object by reference, you can add properties on the fly and use them later in your spec.
Example:
describe('My Test', function () {
var tempObject = {};
it('should go get some text from the page', function () {
browser.get('https://angularjs.org/');
getTextFromElement(tempObject); //pass an object by reference to populate with page text
});
it('should do some random other stuff', function () {
$('div.someDiv').click();
});
it('should be able to use the text from the first page in this test', function () {
console.log(tempObject.textFromFirstPage); //works!
});
});
function getTextFromElement(tempObject) {
$('a.some-link').getText().then(function (txt) {
tempObject.textFromFirstPage = txt;
});
}
Solution 2
First of all, you are not returning anything from the function:
function getTextFromElement() {
return $('a.learn-link').getText();
}
Now, this function would return you a promise which you need to resolve before using:
it('should be able to use the text from the first page in this test', function () {
tempVariable.then(function (tempVariableValue) {
console.log('\ntempVariable: ' + tempVariableValue);
expect(typeof tempVariableValue).not.toBe('undefined', 'failed: tempVariable was undefined!');
});
});
Plus, to determine whether a variable is defined or not, I would use toBeDefined()
from jasmine-matchers
:
expect(tempVariableValue).toBeDefined();
Solution 3
None of the above worked for me. This is working for me:
var item = element.all(by.xpath("some xpath here"));
this.methodToGetTheText = function () {
return Promise.resolve(item.getText().then(function (text) {
return text;
}));
}
luker02
Updated on June 04, 2022Comments
-
luker02 almost 2 years
I’m trying to get text from a page and then use that text further down in the spec to assert on another element.
I’ve pasted a very simple spec you can run that shows you can’t return a value from a function if the function’s return statement is inside a protractor promise
return txt;
(line 24)…describe('My Test', function () { var tempVariable; it('should go get some text from the page', function () { browser.get('https://angularjs.org/'); tempVariable = getTextFromElement(); //it appears javascript immediately sets this variable before waiting for protractor to return the value }); it('should do some random other stuff', function () { element.all(by.cssContainingText('a', 'Learn')).get(0).click(); element.all(by.cssContainingText('a', 'Case Studies')).get(0).click(); element.all(by.cssContainingText('a', ' Home')).get(0).click(); }); it('should be able to use the text from the first page in this test', function () { console.log('\ntempVariable: ' + tempVariable); //this is undefined! expect(typeof tempVariable).not.toBe('undefined', 'failed: tempVariable was undefined!'); }); }); function getTextFromElement() { $('a.learn-link').getText().then(function (txt) { console.log('\nInitial text: ' + txt); return txt; //how do we return this so it's available to other 'it' blocks? }); }
Updated snippet of code following @alecxe answer and my comment.
I am attempting to contruct an object from various text on a page and return it to assert on in a later page...
function getRandomProductFromList() { var Product = function (line, name, subname, units) { this.line = line; this.name = name; this.subname = subname; this.units = units; }; var myProduct = new Product(); myProduct.line = 'Ford'; myProduct.units = 235; //select a random product on the page and add it to 'myProduct' var allProducts = element.all('div.product'); allProducts.count().then(function (count) { var randomIndex = Math.floor(Math.random() * count); var productName = allProducts.get(randomIndex); productName.getText().then(function (prodName) { myProduct.name = prodName; productName.click(); }); }); //If a sub-product can be chosen, select it and add it to 'myProduct' var subproduct = $('div.subproduct'); subproduct.isDisplayed().then(function (subProductExists) { if (subProductExists) { subproduct.getText().then(function (subProductName) { myProduct.subname = subProductName; }); subproduct.click(); } }, function (err) {}); return myProduct; }