Something like this should work. Let me know if you have any questions.
var util = require('util'); var events = require('events'); function WaitUntilElementIsClickable() { events.EventEmitter.call(this); this.startTimeInMilliseconds = null; } util.inherits(WaitUntilElementIsClickable, events.EventEmitter); WaitUntilElementIsClickable.prototype.command = function (element, timeoutInMilliseconds) { this.startTimeInMilliseconds = new Date().getTime(); var self = this; var message; if (typeof timeoutInMilliseconds !== 'number') { timeoutInMilliseconds = this.api.globals.waitForConditionTimeout; } this.check(element, function (result, loadedTimeInMilliseconds) { if (result) { message = '@' + element + ' was clickable after ' + (loadedTimeInMilliseconds - self.startTimeInMilliseconds) + ' ms.'; } else { message = '@' + element + ' was still not clickable after ' + timeoutInMilliseconds + ' ms.'; } self.client.assertion(result, 'not visible or disabled', 'visible and not disabled', message, true); self.emit('complete'); }, timeoutInMilliseconds); return this; }; WaitUntilElementIsClickable.prototype.check = function (element, callback, maxTimeInMilliseconds) { var self = this; var promises =[]; promises.push(new Promise(function(resolve) { self.api.isVisible(element, function(result) { resolve(result.status === 0 && result.value === true); }); })); promises.push(new Promise(function(resolve) { self.api.getAttribute(element, 'disabled', function (result) { resolve(result.status === 0 && result.value === null); }); })); Promise.all(promises) .then(function(results) { var now = new Date().getTime(); const visibleAndNotDisabled = !!results[0] && !!results[1]; if (visibleAndNotDisabled) { callback(true, now); } else if (now - self.startTimeInMilliseconds < maxTimeInMilliseconds) { setTimeout(function () { self.check(element, callback, maxTimeInMilliseconds); }, 500); } else { callback(false); } }) .catch(function(error) { setTimeout(function () { self.check(element, callback, maxTimeInMilliseconds); }, 500); }); }; module.exports = WaitUntilElementIsClickable;
Add this code to the file in the command folder. It should be called waitUntilElementIsClickable.js or whatever you want your command to be.
Using:
browser.waitUntilElementIsClickable('.some.css');
You can also use page elements:
var page = browser.page.somePage(); page.waitUntilElementIsClickable('@someElement');
source share