Yes it is fine to be using multiple types of waiting, I use implicit waits 95% of the time but need to use explicit waits for some conditions. If you app is fully Angular and properly synchronizes (i.e. no outstanding $http calls - more info) you shouldn't need too many waits as Protractor tends to know when Angular/your app is ready. However I don't know your app and this could very well not be true for your case, I'll give a few thoughts on the topic:
Implicit: These are your best bet, for both consistency and stability. I would challenge you and say most of your wait problems could probably be resolved with a proper use of Implicit waits (stronger use cases, compounded across multiple conditions etc). But again, I don't know your app, I think it's worth revisiting though. You can review the list here, the ones I frequently use are presenceOf()
, visibilityOf()
and their counterparts stalenessOf()
and invisibilityOf()
.
Explicit: I try very hard to avoid these, however I have found it necessary in some cases. Such as an animation occurring over a few seconds and there is nothing to track with an implicit wait. I have created a few methods of my own to try and capture these scenarios and use a more implicit wait approach, such as the one below:
// wait for an attribute to be present i.e. "ng-invalid" to be added to a class
// el = element, attr = attribute to check (i.e. class, id etc), target = attribute value to look for
Util.prototype.waitForAttributePresent = function (el, attr, target, time) {
var timeout = time || 0;
return browser.wait(function () {
return el.getAttribute(attr).then(function (val) {
return ~val.indexOf(target) < 0;
});
}, timeout);
};
Use case:
// waits 5 seconds for the elements class to contain "active"
var el = $('div');
Util.waitForAttributePresent(el, 'class', 'active', 5000);
expect(true).toBe(true);
Static: Not sure what you mean by static, that sounds the same as an explicit wait. You are stopping it for a set amount of time, not based on any conditions.