How to use the assigned variable inside of a function, out of it,

I'm using Webdriverjs. I want to assign a variable in a function and then use that result to compare with some data that I retrieved from a csv file. If I want to compare these two in the function that is reading the element from the webpage, then the value of the data from the csv would be the last item in the array. And if I want to use the result of the function outside of the function and compare it with the data from csv, then the variable(pageProductName) that contains the result of the function (textValue) would be undefined, even though I defined the variable outside the function(globally). What can I do to use the value of textValue outside of the function? or What can I do to have the retrieved data from csv in the right order in the function? Here is part of my code that I have problem with:

reader.addListener('data', function(data){
                allEntries.push(data);
         });
reader.addListener('end', function(end)
                { var i=0;
                    console.log(allEntries.length);
                   for(var j=0; j<allEntries.length;j++)
                      {
                       ProductURLArray[i]=(BaseURL+allEntries[j]['col3']+".html");
                       ProductNameArray[i]=allEntries[j]['col2'];
            var url = ProductURLArray[i];
            var name = ProductNameArray[i];
            driver.get(url);
            driver.sleep(3000);
            driver.findElement(webdriver.By.css('.product-name h1')).getText().then(function(textValue){
                        pageProductName=textValue;
                                    });
            console.log(pageProductName);
            assert.equal(pageProductName, name);
}
});

The variable assignment is in a promise, promises will resolve at some point in the future, not necessarily at the point of calling.

The principle is the same as why the getText() call doesn't return the variable from the function and why you have to chain a promise to act on that value.

You would need to chain another 'then' call so that it is guaranteed to manipulate the value after it has been assigned. Given this is the case, it would better to resolve a promise with a given value rather than use a global.

Update

Due to the getText().then promise your pageProductName will not be assigned until sometime after the function exits. Also your for loop complicates the test (I assume this is a unit test) because all of those promises need to finish before this single test is finished.

Without knowing the specifics of your testing framework it's a bit tricky, but if it provides a setup mechanic (something like mocha's before) then you should move your CSV reading into that (note if that CSV contains static test data, then declare it directly in the tests somewhere to make life a lot easier). One final note would be that you need to make use of asynchronous tests, because your test will exit before the code has fully completed executing (the promises). Take a look at how mocha does this by passing a done callback parameter to each test.

So the following is a generic code approach to what you're after, but probably not the solution you need ;)

d = webdriver.promise.defer();
d.then(function(items) {
    return webdriver.promise.map(items, function(item) {
        var url = BaseURL + item['col3'] + ".html";
        var name = item['col2'];
        driver.get(url);
        return driver
            .findElement(webdriver.By.css('.product-name h1'))
            .getText()
            .then(function (text) { return webdriver.promise.fulfilled(text === name); });
    });
})
.then(function (arr) { assert.equal(arr.every(function(item) { return item === true; }), true); })
.then(function () { done(); });

var reader = // get your reader
var allEntries = [];

reader.addListener('data', function (data) { allEntries.push(); });
reader.addListener('end', function () { d.fulfill(allEntries); });

I've just used a text editor for this so be aware it may need 'fixing'.

A quick explanation of the above code:

  • I create a promise (which is not resolved yet)
  • I chain a promise that will
    • execute the test against each element of the passed array
    • the mapping function returns a promise that contains the result of the comparison you're after
  • I chain a promise that will then assert that all comparisons are true
  • I chain a promise that executes the asynchronous completion callback (implementation will depend on testing framework, this is how mocha does it)
  • note at this point no code has run yet
  • I've added your code that reads your input data and now resolves the d promise once it has all the data

I hope that the above is clear, if you aren't sure on anything let me know.

You are not initializing your variable. In order to be able to use it you must initialize your global variable first. Something like this would help

var pageProductName = null;
driver.findElement(webdriver.By.css('.product-name h1')).getText().then(function(textValue){
         pageProductName=textValue;                      
         });
console.log(pageProductName.toString());