I've written a test to check if a element is visible on screen, in my case an angular-ui-bootstrap collapsible panel, aka, the "warning". The code works, but the tests used to fail ~75% of the time.
There is a collapse animation on the display of the "warning", and I can't shutwod the animation for the tests, since it's a jquery animation. The warning is always 'present' in the DOM, just collapsed when there is no reason to show it.
At first, I've tested with this code, which is pretty easy:
expect(element('.warning').isDisplayed()).toEqual(true);
The problem came when I needed to test that the element is not displayed, e.g. : once the warning is displayed, some action cause it to collapse.
That test:
expect(element('.warning').isDisplayed()).toEqual(false);
will pass only if the animation started. It will fail when the condition is checked while the element is still displayed.
I've came up with two solutions.
The easy one using a ptor.driver.sleep(2000)
. Is slows my tests and is not acceptable.
The hard, ugly one, but that gives me good results:
exports.isWarningDisplayed = function (expectedVisibility) {
return ptor.driver.wait(function () {
if (expectedVisibility) {
return element(by.css('.warning')).isDisplayed().then(function(visibility) {
return visibility === expectedVisibility;
});
} else {
return element.all(by.css('.warning .collapse.in')).then(function(items) {
return items.length === 0;
});
}
}, 2000).then(function() {
return element.all(by.css('.warning .collapse.in'));
}).then(function (items) {
return items.length > 0;
});
};
My problem is that it just feels awfully wrong. Have you found a better way to handle that situation? My expectation would be to have something like:
expect(element('.warning').not.isDisplayed()).toEqual(true);
...but there is no .not
in protractor or webDriver AFAIK.