How to use protractor to check if an element is visible?
I'm trying to test if an element is visible using protractor. Here's what the element looks like:
<i class="icon-spinner icon-spin ng-hide" ng-show="saving"></i>
When in the chrome console, I can use this jQuery selector to test if the element is visible:
$('[ng-show=saving].icon-spin')
[
<i class="icon-spinner icon-spin ng-hide" ng-show="saving"></i>
]
> $('[ng-show=saving].icon-spin:visible')
[]
However, when I try to do the same in protractor, I get this error at runtime:
InvalidElementStateError:
invalid element state: Failed to execute 'querySelectorAll' on 'Document':
'[ng-show=saving].icon-spin:visible' is not a valid selector.
Why is this not valid? How can I check for visibility using protractor?
This should do it:
expect($('[ng-show=saving].icon-spin').isDisplayed()).toBe(true);
Remember protractor's $
isn't jQuery and :visible
is not yet a part of available CSS selectors + pseudo-selectors
More info at https://stackoverflow.com/a/13388700/511069
The correct way for checking the visibility of an element with Protractor is to call the isDisplayed
method. You should be careful though since isDisplayed
does not return a boolean, but rather a promise
providing the evaluated visibility. I've seen lots of code examples that use this method wrongly and therefore don't evaluate its actual visibility.
Example for getting the visibility of an element:
element(by.className('your-class-name')).isDisplayed().then(function (isVisible) {
if (isVisible) {
// element is visible
} else {
// element is not visible
}
});
However, you don't need this if you are just checking the visibility of the element (as opposed to getting it) because protractor patches Jasmine expect() so it always waits for promises to be resolved. See github.com/angular/jasminewd
So you can just do:
expect(element(by.className('your-class-name')).isDisplayed()).toBeTruthy();
Since you're using AngularJS
to control the visibility of that element, you could also check its class attribute for ng-hide
like this:
var spinner = element.by.css('i.icon-spin');
expect(spinner.getAttribute('class')).not.toMatch('ng-hide'); // expect element to be visible