Drying test clicks with For-Loops
Question:
How can I click on each link in ul > li a
one test?
Problem: This test passes; however, he does not click on links. I know this because it doesn't redirect or wait 2000ms.
Test:
it("should have proper page linking to all footer link", function() {
browser.driver.sleep(2000);
browser.ignoreSynchronization = true;
//creates an array of strings of all the menu items
var titles = element.all(by.css('.leftMenu.first .submenu li a'))
.map(function(elm) {
return elm.getText().then(function(text){
return text;
});
});
//iterates through the links via titles array
for (var i = 0; i < titles.length; i++) {
// creates a link via selection of cssContainText of the titles array
var link = element(by.cssContainingText('.submenu li a', titles[i]));
//click event
link.click().then(function() {
browser.driver.sleep(2000);
//currently arbitrary expectation but will pass
expect(browser.driver.getTitle()).toBe('welcome to: ' + title[i]);
});
}
});
UPDATE: Found answer: ANSWER
source to share
Your main problem:
return elm.getText;
getText is a method that returns a promise. So you need more like it
return elm.getText().then(function(text){
return text;
});
When you call getText or getInnerHtml method, it only returns a promise. If you are not using wait, if you want the promise to be resolved in order to get the value, then you need to bind it in order to return the value.
source to share
the above answers and approaches all seem to use a "synchronous" approach, so I would like to suggest a solution I found for the same problem that uses the standard asynchronous transport method.
In this example, the footer links are text links like "ABOUT", "CONTACT", etc.) and these cards refer to URLs like "/ about" and "/ contact", etc. etc.
Edit: ptor is defined earlier from protractor.getInstance ();
it('should have a working set of footer links to internal pages', function() {
// element.all( -your selectors- )
// .then() is passed an ARRAY of element finders
element.all(by.css('.footer .nav .links')).then(function(elems) {
// for each element .getText() returns a promise
var txts = elems.map(function(elem) {
return elem.getText().then(function(txt) {
if(txt != ''){
return txt;
}
});
});
// txts is now an ARRAY of promises
// When they are ALL fulfilled the loop below is run
protractor.promise.all(txts).then(function(links) {
for (var i=0; i<links.length; i++) {
// reset browser back to page of interest
// the home page in this case
browser.get('/');
// get a fresh instance of the element and click it
// attempts to click pre-created element list
// will result in 'stale' elements references as pages
// are being navigated
element.all(by.css('.footer .nav .links')).get(i).click();
// expectation of navigation
expect(ptor.getCurrentUrl()).toContain(links[i].toLowerCase());
}
});
});
});
source to share
DUPLICATE: ANSWER TO HERE
You need to wrap the block it
in an IIFE to force the sync
for(var i=0; i < testParams.length; i++) {
(function(testSpec) {
it('write your test here', function() {
//test code here
}
})(testParams[i]);
};
source to share