问题
What I am trying to achieve in Protractor is getting all the links on a page and go to them one by one to check if there is a link that routes to a 404 page.
The following piece of code comes from my email page object, please note that I am calling replace
on the href because the links on the pages that I will test are the following format: https://app.perflectie.nl/something
and I want to end-to-end test on https://staging.perflectie.nl
and on my localhost.
// Used to check for 'broken' links - links that lead to a 404 page
Email.prototype.verifyLinkQuality = function() {
browser.driver.findElements(by.css('a')).then(function (elements) {
elements.forEach(function(el) {
// Change the url to the base url this tests now runs on, e.g. localhost or staging
el.getAttribute('href').then(function(href) {
var url = href.replace(/https\:\/\/app\.perflectie\.nl\//g, localhost);
browser.get(url);
browser.driver.getCurrentUrl().then(function(url) {
expect(url).not.toContain('/Error/');
browser.navigate().back();
});
});
});
});
}
If I run this, I am getting the following error message:
Failed: Element not found in the cache - perhaps the page has changed since it was looked up
For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html
Build info: version: '2.48.2', revision: '41bccdd', time: '2015-10-09 19:59:12'
System info: host: 'DESKTOP-QLFLPK5', ip: '169.254.82.243', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_73'
Driver info: driver.version: unknown
I am at a loss why this is failing, and I would very much appreciate your help.
回答1:
Instead of going back and forth, which often leads to stale element reference errors cause of the DOM change/reload, I would collect all the links into an array using map() and then process them one by one. This would also have a positive impact on the performance of the test:
$$('a').map(function(link) {
return link.getAttribute("href").then(function (href) {
return href.replace(/https\:\/\/app\.perflectie\.nl\//g, localhost);
});
}).then(function(links) {
links.forEach(function(link) {
browser.get(link);
expect(browser.getCurrentUrl()).not.toContain('/Error/');
});
});
Note that there is also no need to resolve the .getCurrentUrl()
explicitly since expect()
would do that implicitly for us before making the expectation.
来源:https://stackoverflow.com/questions/36016179/test-all-links-for-validity-on-a-page-using-protractor