Protractor / WebDriverJS Return element values as an array of objects

406 Views Asked by At

I'm from Java+WebDriver background and new to Protractor, WebdriverJS and Jasmine. In the displayed image I'm trying to hover the mouse over all bubbles and get the tool tip values (city, sold, connected) and assign them to an array as objects and return it to the calling function. Can anyone please tell me how to create an array of objects in this situation? I'm trying to assert it from my spec file.

When I call this function the return arr; runs before the rest of the code. Seems it is due to the Asynchronous behavior.

this.getSalesVolumeDistribution = function() {
var arr = [];
var icons = element.all(by.css('#map-container svg>circle'));
icons.map(function(elm) {
        browser.actions().mouseMove(elm).perform();
        var toolTipCity = element(by
            .css('#map-container g.highcharts-tooltip tspan:nth-of-type(2)'));
        var toolTipUnitsSold = element(by
            .css('#map-container g.highcharts-tooltip tspan:nth-of-type(3)'));
        var toolTipUnitsConnceted = element(by
            .css('#map-container g.highcharts-tooltip tspan:nth-of-type(4)'));

        toolTipCity.getText().then(function(text) {
            var cityVal = text.replace('City: ', '').replace(',', '');
            console.log(text.replace('City: ', '').replace(',', ''));
            var soldVal = toolTipUnitsSold.getText().then(function(text) {
                return text.replace('Units Sold: ', '').replace(',', '');
            });
            var connVal = toolTipUnitsConnceted.getText().then(function(text) {
                return text.replace('Units Connected: ', '');
            });

            arr.push({
                city: cityVal,
                sold: soldVal,
                conn: connVal
            });

            });
    });
return arr;
};

enter image description here

2

There are 2 best solutions below

2
alecxe On BEST ANSWER

You should return the result of map() which would be a promise resolving into an array of objects:

this.getSalesVolumeDistribution = function() {
    var icons = element.all(by.css('#map-container svg>circle'));

    // CHANGE WAS MADE HERE v
    return icons.map(function(elm) {
        browser.actions().mouseMove(elm).perform();
        var toolTipCity = element(by
            .css('#map-container g.highcharts-tooltip tspan:nth-of-type(2)')).getText();
        var toolTipUnitsSold = element(by
            .css('#map-container g.highcharts-tooltip tspan:nth-of-type(3)')).getText();
        var toolTipUnitsConnceted = element(by
            .css('#map-container g.highcharts-tooltip tspan:nth-of-type(4)')).getText();

        // CHANGE WAS MADE HERE v
        return protractor.promise.all([toolTipCity, toolTipUnitsSold, toolTipUnitsConnceted]).then(function(tooltips) {
            var cityVal = tooltips[0].replace('City: ', '').replace(',', '');
            var soldVal = tooltips[1].replace('Units Sold: ', '').replace(',', '');
            var connVal = tooltips[2].replace('Units Connected: ', '');

            // CHANGE WAS MADE HERE v
            return {
                city: cityVal,
                sold: soldVal,
                conn: connVal
            };
        });
    });
};

Note how I've put the returns here (marked with comments). And notice the protractor.promise.all() that helped to resolve multiple promises for the tooltip texts.

Then, if you need to assert the result of the function, put it into expect() - it would resolve the promise implicitly and then make the assertion, e.g.:

expect(myPageObject.getSalesVolumeDistribution()).toEqual([
    {city: 'El Paso', sold: '344', conn: '321'},
    {city: 'New York', sold: '500', conn: '600'}
]);
0
reutsey On

The map function in protractor will allow you to return an array of values: http://www.protractortest.org/#/api?view=ElementArrayFinder.prototype.map

So instead of pushing onto array just do: return { city: cityVal, sold: soldVal, conn: connVal }