|
| 1 | +var WaitForJqueryElement, events, |
| 2 | + extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, |
| 3 | + hasProp = {}.hasOwnProperty; |
| 4 | + |
| 5 | +events = require('events'); |
| 6 | + |
| 7 | + |
| 8 | +/** |
| 9 | + * This custom command allows us to locate an HTML element on the page and then wait until the value of a |
| 10 | + * specified attribute matches the provided expression (aka. the 'checker' function). |
| 11 | + * It retries executing the checker function every 100ms until either it evaluates to true or it reaches |
| 12 | + * maxTimeInMilliseconds (which fails the test). Nightwatch uses the Node.js EventEmitter pattern to handle |
| 13 | + * asynchronous code so this command is also an EventEmitter. |
| 14 | + * |
| 15 | + * h3 Examples: |
| 16 | + * |
| 17 | + * browser.waitForAttribute("img", "src", function(imageSource) { |
| 18 | + * return imageSource === "img/header.jpg"; |
| 19 | + * }); |
| 20 | + * |
| 21 | + * @author maxgalbu |
| 22 | + * @param {String} elementSelector - jquery selector for the element |
| 23 | + * @param {Integer} [timeoutInMilliseconds] - timeout of this wait commands in milliseconds |
| 24 | + */ |
| 25 | + |
| 26 | +WaitForJqueryElement = (function(superClass) { |
| 27 | + extend(WaitForJqueryElement, superClass); |
| 28 | + |
| 29 | + WaitForJqueryElement.prototype.timeoutRetryInMilliseconds = 100; |
| 30 | + |
| 31 | + WaitForJqueryElement.prototype.defaultTimeoutInMilliseconds = 5000; |
| 32 | + |
| 33 | + function WaitForJqueryElement() { |
| 34 | + WaitForJqueryElement.__super__.constructor.apply(this, arguments); |
| 35 | + this.startTimeInMilliseconds = null; |
| 36 | + } |
| 37 | + |
| 38 | + WaitForJqueryElement.prototype.command = function(elementSelector, timeoutInMilliseconds) { |
| 39 | + this.startTimeInMilliseconds = new Date().getTime(); |
| 40 | + if (typeof timeoutInMilliseconds !== 'number') { |
| 41 | + timeoutInMilliseconds = this.api.globals.waitForConditionTimeout; |
| 42 | + } |
| 43 | + if (typeof timeoutInMilliseconds !== 'number') { |
| 44 | + timeoutInMilliseconds = this.defaultTimeoutInMilliseconds; |
| 45 | + } |
| 46 | + this.check(elementSelector, (function(_this) { |
| 47 | + return function(result, loadedTimeInMilliseconds) { |
| 48 | + var message; |
| 49 | + if (result) { |
| 50 | + message = "WaitForJqueryElement: " + elementSelector + ". Expression was true after " + (loadedTimeInMilliseconds - _this.startTimeInMilliseconds) + "."; |
| 51 | + } else { |
| 52 | + message = "WaitForJqueryElement: " + elementSelector + ". Expression wasn't true in " + timeoutInMilliseconds + " ms."; |
| 53 | + } |
| 54 | + _this.client.assertion(result, 'expression false', 'expression true', message, true); |
| 55 | + return _this.emit('complete'); |
| 56 | + }; |
| 57 | + })(this), timeoutInMilliseconds); |
| 58 | + return this; |
| 59 | + }; |
| 60 | + |
| 61 | + WaitForJqueryElement.prototype.check = function(elementSelector, callback, maxTimeInMilliseconds) { |
| 62 | + return this.api.jqueryElement(elementSelector, (function(_this) { |
| 63 | + return function(result) { |
| 64 | + var now; |
| 65 | + now = new Date().getTime(); |
| 66 | + if (result) { |
| 67 | + return callback(true, now); |
| 68 | + } else if (now - _this.startTimeInMilliseconds < maxTimeInMilliseconds) { |
| 69 | + return setTimeout(function() { |
| 70 | + return _this.check(elementSelector, callback, maxTimeInMilliseconds); |
| 71 | + }, _this.timeoutRetryInMilliseconds); |
| 72 | + } else { |
| 73 | + return callback(false); |
| 74 | + } |
| 75 | + }; |
| 76 | + })(this)); |
| 77 | + }; |
| 78 | + |
| 79 | + return WaitForJqueryElement; |
| 80 | + |
| 81 | +})(events.EventEmitter); |
| 82 | + |
| 83 | +module.exports = WaitForJqueryElement; |
0 commit comments