when i execute the following code using protractor it works. I am passing nested json to for loop. Because of asynchronously working of for loop it print all values of variable i and reaches to last value because of this it always access last pair of username and password. How can i solve this issue?
var data = require('.../testdata.json');
describe('homepage Test', function() {
it('candidate login', function() {
browser.driver.get('https://abcxyz.com');
for (i in data.testdata) {
element(by.id('tool_btn3')).click();
console.log(i);
browser.getTitle().then(function(title) {
console.log("Title: " + title)
if (title === "<page title>") {
browser.driver.sleep(3000);
element(by.id('email_input')).sendKeys(data.testdata[i].username);
element(by.id('pwd_input')).sendKeys(data.testdata[i].password);
element(by.xpath('//*[@id="signIn_btn"]/div[2]')).click();
browser.sleep(3000);
element(by.id('setting_img')).click();
browser.sleep(2000);
element(by.id('logout_div')).click().then(function() {
console.log('success');
});
} else {
console.log("problem");
}
});
}
});
});
You need to keep in mind that you can't use a for
-loop with promises. All is async so in the end it will bite you in the ass, meaning that the it
is ready but the test isn't.
Based on you example it would suggest to make a method called for example logon
(place it in a Page Object or something). It will do the logon and stuff for you. Add an empty promise-container (array) and push the promises in there.
When the for
-loop is done you can resolve the complete promise-container at once and it will execute all the promises 1 after each other. It will look something like this.
var data = require('.../testdata.json');
describe('homepage Test', function() {
it('candidate login', function() {
var promises = [];
browser.driver.get('https://abcxyz.com');
for (i in data.testdata) {
promises.push(expect(logon(data.testdata[i].username, data.testdata[i].password)).to.equal(true));
promises.push(console.log(i));
}
Promise.all(promises);
});
});
/**
* Logon
* @params {string} username
* @params {string} password
* @return {boolean}
*/
function logon(username, password) {
element(by.id('tool_btn3')).click();\
return browser.getTitle().then(function(title) {
console.log("Title: " + title)
if (title === "<page title>") {
browser.driver.sleep(3000);
element(by.id('email_input')).sendKeys(username);
element(by.id('pwd_input')).sendKeys(password);
element(by.xpath('//*[@id="signIn_btn"]/div[2]')).click();
browser.sleep(3000);
element(by.id('setting_img')).click();
browser.sleep(2000);
return element(by.id('logout_div')).click()
.then(function() {
return Promise.resolve(true);
});
} else {
return Promise.resolve(false);
}
});
}
If you are using for example Node 7 you can use async/await
, or use Babel to transpile the code. If you can write TypeScript you also get the async/await