Testing AngularJS applications using protractor is quiet cool. It automates the UI testing and ensures consistent quality throughout your project. Experimenting with the new Angular Material I ran into a problem: interacting with select items using the protractor API.
The problem
There are a few ways you can select an option using protractor. A very elegant solution was proposed on stackoverflow. While this works for regular angularjs projects, angular material is a little different. That is because the
If you try the mentioned solution above using a
element(by.cssContainingText('option', '10')).click();
you’ll get a
NoSuchElementError: No element found using locator: by.cssContainingText("option", "10")
There are actually no option (or md-option) tags on the page until you click the select tag. Okay so select.click() first then option.click(), but if you select the option tag right away and proceed to the next select tag an odd error occurs
element.all(by.css('md-select')).each(function (eachElement, index) { eachElement.click(); //select the
unknown error: Element is not clickable at point (253, 520). Other element would receive the click:
This is because of the overlay that Angular Material puts on the display. It doesn’t disappear right away. So we need to wait for the material effects to take place.
the solution (quickfix):
element.all(by.css('md-select')).each(function (eachElement, index) { eachElement.click(); //select the select browser.driver.sleep(500); //wait for the renderings to take effect element(by.css('md-option')).click(); //select the first md-option browser.driver.sleep(500); //wait for the renderings to take effect });
now the selection works one at a time and angular material has enough time to take away that overlay
Overall though, both the material design implementation of angularjs as well as TDD using protractor and jasmine / karma work very well.
6 Kommentare
Few Corrections..
element.all(by.css(‚md-select‘)).each(function(eachElement) {
eachElement.click(); //select the select
browser.driver.sleep(500); //wait for the renderings to take effect
element(by.css(‚md-option‘)).click //select the first md-option
browser.driver.sleep(500); //wait for the renderings to take effect
});
You’re codeblock is incomplete, yet this is the first hit on google with my searches, so I figured I’d post a comment with the code. Also, better to use waitForAngular() than sleep.
element.all(by.css(‚md-select‘)).each(function (eachElement, index) {
eachElement.click(); // select the
browser.waitForAngular(); // wait for the renderings to take effect
element(by.css(‚md-option‘)).click(); // select the first md-option
browser.waitForAngular(); // wait for the renderings to take effect
});
Hey. thx for the waitForAngular fix. Other than that, I dont see any real differences though.. did you mean something else that is „incomplete“?
Hey, do you know how I can test this using a unit test?
var dropDown = element.find(‚md-select‘);
dropDown.triggerHandler(‚click‘);
scope.$digest();
console.log(element); //compiled hmtl
Pingback: Protractor won’t click items on drop-down (Angular Material 2) – program faq
Pingback: angular material md-select - e2e protractor tests - element not visible - Witty Answer