| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * | |
| 3 | * Copyright (c) 2013 Sebastian Golasch | |
| 4 | * | |
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | |
| 6 | * copy of this software and associated documentation files (the "Software"), | |
| 7 | * to deal in the Software without restriction, including without limitation | |
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | |
| 10 | * Software is furnished to do so, subject to the following conditions: | |
| 11 | * | |
| 12 | * The above copyright notice and this permission notice shall be included | |
| 13 | * in all copies or substantial portions of the Software. | |
| 14 | * | |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 21 | * DEALINGS IN THE SOFTWARE. | |
| 22 | * | |
| 23 | */ | |
| 24 | ||
| 25 | 1 | 'use strict'; |
| 26 | ||
| 27 | // ext. libs | |
| 28 | 1 | var fs = require('fs'); |
| 29 | 1 | var Q = require('q'); |
| 30 | ||
| 31 | // int. libs | |
| 32 | 1 | var WD = null; |
| 33 | ||
| 34 | // try/catch loading of the webdriver, so we can | |
| 35 | // fall back to canary builds | |
| 36 | 1 | try { |
| 37 | 1 | WD = require('dalek-internal-webdriver'); |
| 38 | } catch (e) { | |
| 39 | 0 | try { |
| 40 | 0 | WD = require('dalek-internal-webdriver-canary'); |
| 41 | } catch (e) { | |
| 42 | 0 | throw e; |
| 43 | } | |
| 44 | } | |
| 45 | ||
| 46 | /** | |
| 47 | * Loads the webdriver client, | |
| 48 | * launches the browser, | |
| 49 | * initializes al object properties, | |
| 50 | * binds to browser events | |
| 51 | * | |
| 52 | * @param {object} opts Options needed to kick off the driver | |
| 53 | * @constructor | |
| 54 | */ | |
| 55 | ||
| 56 | 1 | var DriverNative = function (opts) { |
| 57 | // get the browser configuration & the browser module | |
| 58 | 0 | var browserConf = opts.browserConf; |
| 59 | 0 | var browser = opts.browserMo; |
| 60 | ||
| 61 | // prepare properties | |
| 62 | 0 | this._initializeProperties(opts); |
| 63 | ||
| 64 | // create a new webdriver client instance | |
| 65 | 0 | this.webdriverClient = new WD(browser, this.events); |
| 66 | ||
| 67 | // listen on browser events | |
| 68 | 0 | this._startBrowserEventListeners(browser); |
| 69 | ||
| 70 | // store desired capabilities of this session | |
| 71 | 0 | this.desiredCapabilities = browser.desiredCapabilities; |
| 72 | 0 | this.browserDefaults = browser.driverDefaults; |
| 73 | ||
| 74 | // launch the browser & when the browser launch | |
| 75 | // promise is fullfilled, issue the driver:ready event | |
| 76 | // for the particular browser | |
| 77 | 0 | browser |
| 78 | .launch(browserConf, this.reporterEvents, this.config) | |
| 79 | .then(this.events.emit.bind(this.events, 'driver:ready:native:' + this.browserName, browser)); | |
| 80 | }; | |
| 81 | ||
| 82 | /** | |
| 83 | * Launches the browsers to test | |
| 84 | * and handles the webdriver requests & responses | |
| 85 | * | |
| 86 | * @module Driver | |
| 87 | * @class DriverNative | |
| 88 | * @namespace Dalek | |
| 89 | * @part DriverNative | |
| 90 | * @api | |
| 91 | */ | |
| 92 | ||
| 93 | 1 | DriverNative.prototype = { |
| 94 | ||
| 95 | /** | |
| 96 | * Initializes the driver properties | |
| 97 | * | |
| 98 | * @method _initializeProperties | |
| 99 | * @param {object} opts Options needed to kick off the driver | |
| 100 | * @chainable | |
| 101 | * @private | |
| 102 | */ | |
| 103 | ||
| 104 | _initializeProperties: function (opts) { | |
| 105 | // prepare properties | |
| 106 | 0 | this.actionQueue = []; |
| 107 | 0 | this.config = opts.config; |
| 108 | 0 | this.lastCalledUrl = null; |
| 109 | 0 | this.driverStatus = {}; |
| 110 | 0 | this.sessionStatus = {}; |
| 111 | // store injcted options in object properties | |
| 112 | 0 | this.events = opts.events; |
| 113 | 0 | this.reporterEvents = opts.reporter; |
| 114 | 0 | this.browserName = opts.browser; |
| 115 | 0 | return this; |
| 116 | }, | |
| 117 | ||
| 118 | /** | |
| 119 | * Binds listeners on browser events | |
| 120 | * | |
| 121 | * @method _initializeProperties | |
| 122 | * @param {object} browser Browser module | |
| 123 | * @chainable | |
| 124 | * @private | |
| 125 | */ | |
| 126 | ||
| 127 | _startBrowserEventListeners: function (browser) { | |
| 128 | 0 | this.reporterEvents.on('browser:notify:data:' + this.browserName, function (data) { |
| 129 | 0 | this.desiredCapabilities = data.desiredCapabilities; |
| 130 | 0 | this.browserDefaults = data.defaults; |
| 131 | }.bind(this)); | |
| 132 | // issue the kill command to the browser, when all tests are completed | |
| 133 | 0 | this.events.on('tests:complete:native:' + this.browserName, browser.kill.bind(browser)); |
| 134 | // clear the webdriver session, when all tests are completed | |
| 135 | 0 | this.events.on('tests:complete:native:' + this.browserName, this.webdriverClient.closeSession.bind(this.webdriverClient)); |
| 136 | 0 | return this; |
| 137 | }, | |
| 138 | ||
| 139 | /** | |
| 140 | * Checks if a webdriver session has already been established, | |
| 141 | * if not, create a new one | |
| 142 | * | |
| 143 | * @method start | |
| 144 | * @return {object} promise Driver promise | |
| 145 | */ | |
| 146 | ||
| 147 | start: function () { | |
| 148 | 0 | var deferred = Q.defer(); |
| 149 | ||
| 150 | // check if a session is already active, | |
| 151 | // if so, reuse that one | |
| 152 | 0 | if(this.webdriverClient.hasSession()) { |
| 153 | 0 | deferred.resolve(); |
| 154 | 0 | return deferred.promise; |
| 155 | } | |
| 156 | ||
| 157 | // start a browser session | |
| 158 | 0 | this._startBrowserSession(deferred, this.desiredCapabilities, this.browserDefaults); |
| 159 | ||
| 160 | 0 | return deferred.promise; |
| 161 | }, | |
| 162 | ||
| 163 | /** | |
| 164 | * Creates a new webdriver session | |
| 165 | * Gets the driver status | |
| 166 | * Gets the session status | |
| 167 | * Resolves the promise (e.g. let them tests run) | |
| 168 | * | |
| 169 | * @method _startBrowserSession | |
| 170 | * @param {object} deferred Browser session deferred | |
| 171 | * @chainable | |
| 172 | * @private | |
| 173 | */ | |
| 174 | ||
| 175 | _startBrowserSession: function (deferred, desiredCapabilities, defaults) { | |
| 176 | 0 | var viewport = this.config.get('viewport'); |
| 177 | ||
| 178 | // start a session, transmit the desired capabilities | |
| 179 | 0 | var promise = this.webdriverClient.createSession({desiredCapabilities: desiredCapabilities}); |
| 180 | ||
| 181 | // set the default viewport if supported by the browser | |
| 182 | 0 | if (defaults.viewport) { |
| 183 | 0 | promise = promise.then(this.webdriverClient.setWindowSize.bind(this.webdriverClient, viewport.width, viewport.height)); |
| 184 | } | |
| 185 | ||
| 186 | // get the driver status if supported by the browser | |
| 187 | 0 | if (defaults.status === true) { |
| 188 | 0 | promise = promise |
| 189 | .then(this.webdriverClient.status.bind(this.webdriverClient)) | |
| 190 | .then(this._driverStatus.bind(this)); | |
| 191 | } else { | |
| 192 | 0 | promise = promise.then(this._driverStatus.bind(this, JSON.stringify({value: defaults.status}))); |
| 193 | } | |
| 194 | ||
| 195 | // get the session info if supported by the browser | |
| 196 | 0 | if (defaults.sessionInfo === true) { |
| 197 | 0 | promise = promise |
| 198 | .then(this.webdriverClient.sessionInfo.bind(this.webdriverClient)) | |
| 199 | .then(this._sessionStatus.bind(this)); | |
| 200 | } else { | |
| 201 | 0 | promise = promise.then(this._driverStatus.bind(this, JSON.stringify({value: defaults.sessionInfo}))); |
| 202 | } | |
| 203 | ||
| 204 | // finally resolve the deferred | |
| 205 | 0 | promise.then(deferred.resolve); |
| 206 | 0 | return this; |
| 207 | }, | |
| 208 | ||
| 209 | /** | |
| 210 | * Starts to execution of a batch of tests | |
| 211 | * | |
| 212 | * @method end | |
| 213 | * @chainable | |
| 214 | */ | |
| 215 | ||
| 216 | end: function () { | |
| 217 | 0 | var result = Q.resolve(); |
| 218 | ||
| 219 | // loop through all promises created by the remote methods | |
| 220 | // this is synchronous, so it waits if a method is finished before | |
| 221 | // the next one will be executed | |
| 222 | 0 | this.actionQueue.forEach(function (f) { |
| 223 | 0 | result = result.then(f); |
| 224 | }); | |
| 225 | ||
| 226 | // flush the queue & fire an event | |
| 227 | // when the queue finished its executions | |
| 228 | 0 | result.then(this.flushQueue.bind(this)); |
| 229 | 0 | return this; |
| 230 | }, | |
| 231 | ||
| 232 | /** | |
| 233 | * Flushes the action queue (e.g. commands that should be send to the wbdriver server) | |
| 234 | * | |
| 235 | * @method flushQueue | |
| 236 | * @chainable | |
| 237 | */ | |
| 238 | ||
| 239 | flushQueue: function () { | |
| 240 | // clear the action queue | |
| 241 | 0 | this.actionQueue = []; |
| 242 | // emit the run.complete event | |
| 243 | 0 | this.events.emit('driver:message', {key: 'run.complete', value: null}); |
| 244 | 0 | return this; |
| 245 | }, | |
| 246 | ||
| 247 | /** | |
| 248 | * Loads the browser session status | |
| 249 | * | |
| 250 | * @method _sessionStatus | |
| 251 | * @param {object} sessionInfo Session information | |
| 252 | * @return {object} promise Browser session promise | |
| 253 | * @private | |
| 254 | */ | |
| 255 | ||
| 256 | _sessionStatus: function (sessionInfo) { | |
| 257 | 0 | var defer = Q.defer(); |
| 258 | 0 | this.sessionStatus = JSON.parse(sessionInfo).value; |
| 259 | 0 | this.events.emit('driver:sessionStatus:native:' + this.browserName, this.sessionStatus); |
| 260 | 0 | defer.resolve(); |
| 261 | 0 | return defer.promise; |
| 262 | }, | |
| 263 | ||
| 264 | /** | |
| 265 | * Loads the browser driver status | |
| 266 | * | |
| 267 | * @method _driverStatus | |
| 268 | * @param {object} statusInfo Driver status information | |
| 269 | * @return {object} promise Driver status promise | |
| 270 | * @private | |
| 271 | */ | |
| 272 | ||
| 273 | _driverStatus: function (statusInfo) { | |
| 274 | 0 | var defer = Q.defer(); |
| 275 | 0 | this.driverStatus = JSON.parse(statusInfo).value; |
| 276 | 0 | this.events.emit('driver:status:native:' + this.browserName, this.driverStatus); |
| 277 | 0 | defer.resolve(); |
| 278 | 0 | return defer.promise; |
| 279 | }, | |
| 280 | ||
| 281 | /** | |
| 282 | * Creates an anonymus function that calls a webdriver | |
| 283 | * method that has no return value, emits an empty result event | |
| 284 | * if the function has been run | |
| 285 | * TODO: Name is weird, should be saner | |
| 286 | * | |
| 287 | * @method _createNonReturnee | |
| 288 | * @param {string} fnName Name of the webdriver function that should be called | |
| 289 | * @return {function} fn | |
| 290 | * @private | |
| 291 | */ | |
| 292 | ||
| 293 | _createNonReturnee: function (fnName) { | |
| 294 | 0 | return this._actionQueueNonReturneeTemplate.bind(this, fnName); |
| 295 | }, | |
| 296 | ||
| 297 | /** | |
| 298 | * Generates a chain of webdriver calls for webdriver | |
| 299 | * methods that don't have a return value | |
| 300 | * TODO: Name is weird, should be saner | |
| 301 | * | |
| 302 | * @method _actionQueueNonReturneeTemplate | |
| 303 | * @param {string} fnName Name of the webdriver function that should be called | |
| 304 | * @param {string} hash Unique action hash | |
| 305 | * @param {string} uuid Unique action hash | |
| 306 | * @chainable | |
| 307 | * @private | |
| 308 | */ | |
| 309 | ||
| 310 | _actionQueueNonReturneeTemplate:function (fnName, hash, uuid) { | |
| 311 | 0 | this.actionQueue.push(this.webdriverClient[fnName].bind(this.webdriverClient)); |
| 312 | 0 | this.actionQueue.push(this._generateDummyDriverMessageFn.bind(this, fnName, hash, uuid)); |
| 313 | 0 | return this; |
| 314 | }, | |
| 315 | ||
| 316 | /** | |
| 317 | * Creates a driver notification with an empty value | |
| 318 | * TODO: Name is weird, should be saner | |
| 319 | * | |
| 320 | * @method _generateDummyDriverMessageFn | |
| 321 | * @param {string} fnName Name of the webdriver function that should be called | |
| 322 | * @param {string} hash Unique action hash | |
| 323 | * @param {string} uuid Unique action hash | |
| 324 | * @return {object} promise Driver message promise | |
| 325 | * @private | |
| 326 | */ | |
| 327 | ||
| 328 | _generateDummyDriverMessageFn: function (fnName, hash, uuid) { | |
| 329 | 0 | var deferred = Q.defer(); |
| 330 | 0 | this.events.emit('driver:message', {key: fnName, value: null, uuid: uuid, hash: hash}); |
| 331 | 0 | deferred.resolve(); |
| 332 | 0 | return deferred.promise; |
| 333 | } | |
| 334 | }; | |
| 335 | ||
| 336 | /** | |
| 337 | * Determines if the driver is a "multi" browser driver, | |
| 338 | * e.g. can handle more than one browser | |
| 339 | * | |
| 340 | * @method isMultiBrowser | |
| 341 | * @return {bool} isMultiBrowser Driver can handle more than one browser | |
| 342 | */ | |
| 343 | ||
| 344 | 1 | module.exports.isMultiBrowser = function () { |
| 345 | 0 | return true; |
| 346 | }; | |
| 347 | ||
| 348 | /** | |
| 349 | * Verifies a browser request | |
| 350 | * TODO: Still a noop, need to add "verify the browser" logic | |
| 351 | * | |
| 352 | * @method verifyBrowser | |
| 353 | * @return {bool} isVerifiedBrowser Driver can handle this browser | |
| 354 | */ | |
| 355 | ||
| 356 | 1 | module.exports.verifyBrowser = function () { |
| 357 | 0 | return true; |
| 358 | }; | |
| 359 | ||
| 360 | /** | |
| 361 | * Creates a new driver instance | |
| 362 | * | |
| 363 | * @method create | |
| 364 | * @param {object} opts Options needed to kick off the driver | |
| 365 | * @return {DriverNative} driver | |
| 366 | */ | |
| 367 | ||
| 368 | 1 | module.exports.create = function (opts) { |
| 369 | // load the remote command helper methods | |
| 370 | 0 | var dir = __dirname + '/lib/commands/'; |
| 371 | 0 | fs.readdirSync(dir).forEach(function (file) { |
| 372 | 0 | require(dir + file)(DriverNative); |
| 373 | }); | |
| 374 | ||
| 375 | 0 | return new DriverNative(opts); |
| 376 | }; | |
| 377 |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * | |
| 3 | * Copyright (c) 2013 Sebastian Golasch | |
| 4 | * | |
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | |
| 6 | * copy of this software and associated documentation files (the "Software"), | |
| 7 | * to deal in the Software without restriction, including without limitation | |
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | |
| 10 | * Software is furnished to do so, subject to the following conditions: | |
| 11 | * | |
| 12 | * The above copyright notice and this permission notice shall be included | |
| 13 | * in all copies or substantial portions of the Software. | |
| 14 | * | |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 21 | * DEALINGS IN THE SOFTWARE. | |
| 22 | * | |
| 23 | */ | |
| 24 | ||
| 25 | 1 | 'use strict'; |
| 26 | ||
| 27 | // ext. libs | |
| 28 | 1 | var Q = require('q'); |
| 29 | ||
| 30 | /** | |
| 31 | * Cookie related methods | |
| 32 | * | |
| 33 | * @module Driver | |
| 34 | * @class Cookie | |
| 35 | * @namespace Dalek.DriverNative.Commands | |
| 36 | */ | |
| 37 | ||
| 38 | 1 | var Cookie = { |
| 39 | ||
| 40 | /** | |
| 41 | * Sets an cookie | |
| 42 | * | |
| 43 | * @method setCookie | |
| 44 | * @param {string} name Name of the cookie | |
| 45 | * @param {string} contents Contents of the cookie | |
| 46 | * @param {string} hash Unique hash of that fn call | |
| 47 | * @chainable | |
| 48 | */ | |
| 49 | ||
| 50 | setCookie: function (name, contents, hash) { | |
| 51 | 0 | this.actionQueue.push(this.webdriverClient.setCookie.bind(this.webdriverClient, {name: name, value: contents})); |
| 52 | 0 | this.actionQueue.push(this._setCookieCb.bind(this, name, contents, hash)); |
| 53 | 0 | return this; |
| 54 | }, | |
| 55 | ||
| 56 | /** | |
| 57 | * Sends out an event with the results of the `setCookie` call | |
| 58 | * | |
| 59 | * @method _setCookieCb | |
| 60 | * @param {string} name Name of the cookie | |
| 61 | * @param {string} contents Contents of the cookie | |
| 62 | * @param {string} hash Unique hash of that fn call | |
| 63 | * @return {object} promise Exists promise | |
| 64 | * @private | |
| 65 | */ | |
| 66 | ||
| 67 | _setCookieCb: function (name, contents, hash) { | |
| 68 | 0 | var deferred = Q.defer(); |
| 69 | 0 | this.events.emit('driver:message', {key: 'setCookie', value: name, contents: contents, uuid: hash, hash: hash}); |
| 70 | 0 | deferred.resolve(); |
| 71 | 0 | return deferred.promise; |
| 72 | }, | |
| 73 | ||
| 74 | /** | |
| 75 | * Retrieves an cookie | |
| 76 | * | |
| 77 | * @method cookie | |
| 78 | * @param {string} name Name of the cookie | |
| 79 | * @param {string} cookie Expected contents of the cookie | |
| 80 | * @param {string} hash Unique hash of that fn call | |
| 81 | * @chainable | |
| 82 | */ | |
| 83 | ||
| 84 | cookie: function (name, cookie, hash) { | |
| 85 | 0 | this.actionQueue.push(this.webdriverClient.getCookie.bind(this.webdriverClient, name)); |
| 86 | 0 | this.actionQueue.push(this._cookieCb.bind(this, name, hash)); |
| 87 | 0 | return this; |
| 88 | }, | |
| 89 | ||
| 90 | /** | |
| 91 | * Sends out an event with the results of the `setCookie` call | |
| 92 | * | |
| 93 | * @method _cookieCb | |
| 94 | * @param {string} name Name of the cookie | |
| 95 | * @param {string} expected Expected contents of the cookie | |
| 96 | * @param {string} hash Unique hash of that fn call | |
| 97 | * @param {string} result Serialized JSON with the reuslts of the exists call | |
| 98 | * @return {object} promise Exists promise | |
| 99 | * @private | |
| 100 | */ | |
| 101 | ||
| 102 | _cookieCb: function (name, expected, hash, res) { | |
| 103 | 0 | var deferred = Q.defer(); |
| 104 | 0 | var cookies = JSON.parse(res).value; |
| 105 | 0 | var cookie = false; |
| 106 | 0 | cookies.forEach(function (cookieItem) { |
| 107 | 0 | if (cookieItem.name === name) { |
| 108 | 0 | cookie = cookieItem.value; |
| 109 | } | |
| 110 | }); | |
| 111 | ||
| 112 | 0 | this.events.emit('driver:message', {key: 'cookie', value: cookie, name: name, expected: expected, uuid: hash, hash: hash}); |
| 113 | 0 | deferred.resolve(); |
| 114 | 0 | return deferred.promise; |
| 115 | }, | |
| 116 | }; | |
| 117 | ||
| 118 | /** | |
| 119 | * Mixes in cookie methods | |
| 120 | * | |
| 121 | * @param {Dalek.DriverNative} DalekNative Native driver base class | |
| 122 | * @return {Dalek.DriverNative} DalekNative Native driver base class | |
| 123 | */ | |
| 124 | ||
| 125 | 1 | module.exports = function (DalekNative) { |
| 126 | // mixin methods | |
| 127 | 0 | Object.keys(Cookie).forEach(function (fn) { |
| 128 | 0 | DalekNative.prototype[fn] = Cookie[fn]; |
| 129 | }); | |
| 130 | ||
| 131 | 0 | return DalekNative; |
| 132 | }; | |
| 133 |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * | |
| 3 | * Copyright (c) 2013 Sebastian Golasch | |
| 4 | * | |
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | |
| 6 | * copy of this software and associated documentation files (the "Software"), | |
| 7 | * to deal in the Software without restriction, including without limitation | |
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | |
| 10 | * Software is furnished to do so, subject to the following conditions: | |
| 11 | * | |
| 12 | * The above copyright notice and this permission notice shall be included | |
| 13 | * in all copies or substantial portions of the Software. | |
| 14 | * | |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 21 | * DEALINGS IN THE SOFTWARE. | |
| 22 | * | |
| 23 | */ | |
| 24 | ||
| 25 | 1 | 'use strict'; |
| 26 | ||
| 27 | // ext. libs | |
| 28 | 1 | var Q = require('q'); |
| 29 | ||
| 30 | /** | |
| 31 | * Element related methods | |
| 32 | * | |
| 33 | * @module Driver | |
| 34 | * @class Element | |
| 35 | * @namespace Dalek.DriverNative.Commands | |
| 36 | */ | |
| 37 | ||
| 38 | 1 | var Element = { |
| 39 | ||
| 40 | /** | |
| 41 | * Checks if an element exists | |
| 42 | * | |
| 43 | * @method exists | |
| 44 | * @param {string} selector Selector expression to find the element | |
| 45 | * @param {string} hash Unique hash of that fn call | |
| 46 | * @chainable | |
| 47 | */ | |
| 48 | ||
| 49 | exists: function (selector, hash) { | |
| 50 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 51 | 0 | this.actionQueue.push(this._existsCb.bind(this, selector, hash)); |
| 52 | 0 | return this; |
| 53 | }, | |
| 54 | ||
| 55 | /** | |
| 56 | * Sends out an event with the results of the `exists` call | |
| 57 | * | |
| 58 | * @method _existsCb | |
| 59 | * @param {string} selector Selector expression to find the element | |
| 60 | * @param {string} hash Unique hash of that fn call | |
| 61 | * @param {string} result Serialized JSON with the reuslts of the exists call | |
| 62 | * @return {object} promise Exists promise | |
| 63 | * @private | |
| 64 | */ | |
| 65 | ||
| 66 | _existsCb: function (selector, hash, result) { | |
| 67 | 0 | var deferred = Q.defer(); |
| 68 | 0 | this.events.emit('driver:message', {key: 'exists', selector: selector, hash: hash, value: (JSON.parse(result).value === -1 || JSON.parse(result).status === 7 ? 'false' : 'true')}); |
| 69 | 0 | deferred.resolve(); |
| 70 | 0 | return deferred.promise; |
| 71 | }, | |
| 72 | ||
| 73 | /** | |
| 74 | * Checks if an element is visible | |
| 75 | * | |
| 76 | * @method visible | |
| 77 | * @param {string} selector Selector expression to find the element | |
| 78 | * @param {string} hash Unique hash of that fn call | |
| 79 | * @chainable | |
| 80 | */ | |
| 81 | ||
| 82 | visible: function (selector, hash) { | |
| 83 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 84 | 0 | this.actionQueue.push(this.webdriverClient.displayed.bind(this.webdriverClient, selector)); |
| 85 | 0 | this.actionQueue.push(this._visibleCb.bind(this, selector, hash)); |
| 86 | 0 | return this; |
| 87 | }, | |
| 88 | ||
| 89 | /** | |
| 90 | * Sends out an event with the results of the `visible` call | |
| 91 | * | |
| 92 | * @method _visibleCb | |
| 93 | * @param {string} selector Selector expression to find the element | |
| 94 | * @param {string} hash Unique hash of that fn call | |
| 95 | * @param {string} result Serialized JSON with the reuslts of the visible call | |
| 96 | * @return {object} promise Visible promise | |
| 97 | * @private | |
| 98 | */ | |
| 99 | ||
| 100 | _visibleCb: function (selector, hash, result) { | |
| 101 | 0 | var deferred = Q.defer(); |
| 102 | 0 | this.events.emit('driver:message', {key: 'visible', selector: selector, hash: hash, value: JSON.parse(result).value}); |
| 103 | 0 | deferred.resolve(); |
| 104 | 0 | return deferred.promise; |
| 105 | }, | |
| 106 | ||
| 107 | /** | |
| 108 | * Checks if an element has the expected text | |
| 109 | * | |
| 110 | * @method text | |
| 111 | * @param {string} selector Selector expression to find the element | |
| 112 | * @param {string} expected The expected text content | |
| 113 | * @param {string} hash Unique hash of that fn call | |
| 114 | * @chainable | |
| 115 | */ | |
| 116 | ||
| 117 | text: function (selector, expected, hash) { | |
| 118 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 119 | 0 | this.actionQueue.push(this.webdriverClient.text.bind(this.webdriverClient, selector)); |
| 120 | 0 | this.actionQueue.push(this._textCb.bind(this, selector, hash, expected)); |
| 121 | 0 | return this; |
| 122 | }, | |
| 123 | ||
| 124 | /** | |
| 125 | * Sends out an event with the results of the `text` call | |
| 126 | * | |
| 127 | * @method _textCb | |
| 128 | * @param {string} selector Selector expression to find the element | |
| 129 | * @param {string} hash Unique hash of that fn call | |
| 130 | * @param {string} expected The expected text content | |
| 131 | * @param {string} result Serialized JSON with the reuslts of the text call | |
| 132 | * @return {object} Promise | |
| 133 | * @private | |
| 134 | */ | |
| 135 | ||
| 136 | _textCb: function (selector, hash, expected, result) { | |
| 137 | 0 | var deferred = Q.defer(); |
| 138 | 0 | this.events.emit('driver:message', {key: 'text', hash: hash, expected: expected, selector: selector, value: JSON.parse(result).value}); |
| 139 | 0 | deferred.resolve(); |
| 140 | 0 | return deferred.promise; |
| 141 | }, | |
| 142 | ||
| 143 | /** | |
| 144 | * Checks if an element has the expected css property/value pairs | |
| 145 | * | |
| 146 | * @method css | |
| 147 | * @param {string} selector Selector expression to find the element | |
| 148 | * @param {string} property The css property to check | |
| 149 | * @param {string} expected The expected css value | |
| 150 | * @param {string} hash Unique hash of that fn call | |
| 151 | * @chainable | |
| 152 | */ | |
| 153 | ||
| 154 | css: function (selector, property, expected, hash) { | |
| 155 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 156 | 0 | this.actionQueue.push(this.webdriverClient.cssProperty.bind(this.webdriverClient, property)); |
| 157 | 0 | this.actionQueue.push(this._cssCb.bind(this, selector, property, hash, expected)); |
| 158 | 0 | return this; |
| 159 | }, | |
| 160 | ||
| 161 | /** | |
| 162 | * Sends out an event with the results of the `css` call | |
| 163 | * | |
| 164 | * @method _cssCb | |
| 165 | * @param {string} selector Selector expression to find the element | |
| 166 | * @param {string} property The css property to check | |
| 167 | * @param {string} expected The expected css value | |
| 168 | * @param {string} hash Unique hash of that fn call | |
| 169 | * @param {string} result Serialized JSON with the reuslts of the text call | |
| 170 | * @return {object} Promise | |
| 171 | * @private | |
| 172 | */ | |
| 173 | ||
| 174 | _cssCb: function (selector, property, hash, expected, result) { | |
| 175 | 0 | var deferred = Q.defer(); |
| 176 | 0 | this.events.emit('driver:message', {key: 'css', hash: hash, property: property, expected: expected, selector: selector, value: JSON.parse(result).value}); |
| 177 | 0 | deferred.resolve(); |
| 178 | 0 | return deferred.promise; |
| 179 | }, | |
| 180 | ||
| 181 | /** | |
| 182 | * Checks th width of an element | |
| 183 | * | |
| 184 | * @method width | |
| 185 | * @param {string} selector Selector expression to find the element | |
| 186 | * @param {string} expected The expected width value | |
| 187 | * @param {string} hash Unique hash of that fn call | |
| 188 | * @chainable | |
| 189 | */ | |
| 190 | ||
| 191 | width: function (selector, expected, hash) { | |
| 192 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 193 | 0 | this.actionQueue.push(this.webdriverClient.size.bind(this.webdriverClient)); |
| 194 | 0 | this.actionQueue.push(this._widthCb.bind(this, selector, hash, expected)); |
| 195 | 0 | return this; |
| 196 | }, | |
| 197 | ||
| 198 | /** | |
| 199 | * Sends out an event with the results of the `width` call | |
| 200 | * | |
| 201 | * @method _widthCb | |
| 202 | * @param {string} selector Selector expression to find the element | |
| 203 | * @param {string} expected The expected width value | |
| 204 | * @param {string} hash Unique hash of that fn call | |
| 205 | * @param {string} result Serialized JSON with the reuslts of the text call | |
| 206 | * @return {object} Promise | |
| 207 | * @private | |
| 208 | */ | |
| 209 | ||
| 210 | _widthCb: function (selector, hash, expected, result) { | |
| 211 | 0 | var deferred = Q.defer(); |
| 212 | 0 | this.events.emit('driver:message', {key: 'width', hash: hash, expected: expected, selector: selector, value: JSON.parse(result).value.width}); |
| 213 | 0 | deferred.resolve(); |
| 214 | 0 | return deferred.promise; |
| 215 | }, | |
| 216 | ||
| 217 | /** | |
| 218 | * Checks th height of an element | |
| 219 | * | |
| 220 | * @method height | |
| 221 | * @param {string} selector Selector expression to find the element | |
| 222 | * @param {string} expected The expected height value | |
| 223 | * @param {string} hash Unique hash of that fn call | |
| 224 | * @chainable | |
| 225 | */ | |
| 226 | ||
| 227 | height: function (selector, expected, hash) { | |
| 228 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 229 | 0 | this.actionQueue.push(this.webdriverClient.size.bind(this.webdriverClient)); |
| 230 | 0 | this.actionQueue.push(this._heightCb.bind(this, selector, hash, expected)); |
| 231 | 0 | return this; |
| 232 | }, | |
| 233 | ||
| 234 | /** | |
| 235 | * Sends out an event with the results of the `height` call | |
| 236 | * | |
| 237 | * @method _heightCb | |
| 238 | * @param {string} selector Selector expression to find the element | |
| 239 | * @param {string} expected The expected height value | |
| 240 | * @param {string} hash Unique hash of that fn call | |
| 241 | * @param {string} result Serialized JSON with the reuslts of the text call | |
| 242 | * @return {object} Promise | |
| 243 | * @private | |
| 244 | */ | |
| 245 | ||
| 246 | _heightCb: function (selector, hash, expected, result) { | |
| 247 | 0 | var deferred = Q.defer(); |
| 248 | 0 | this.events.emit('driver:message', {key: 'height', hash: hash, expected: expected, selector: selector, value: JSON.parse(result).value.height}); |
| 249 | 0 | deferred.resolve(); |
| 250 | 0 | return deferred.promise; |
| 251 | }, | |
| 252 | ||
| 253 | /** | |
| 254 | * Checks if an element has an attribute with the expected value | |
| 255 | * | |
| 256 | * @method attribute | |
| 257 | * @param {string} selector Selector expression to find the element | |
| 258 | * @param {string} attribute The attribute that should be checked | |
| 259 | * @param {string} expected The expected text content | |
| 260 | * @param {string} hash Unique hash of that fn call | |
| 261 | * @chainable | |
| 262 | */ | |
| 263 | ||
| 264 | attribute: function (selector, attribute, expected, hash) { | |
| 265 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 266 | 0 | this.actionQueue.push(this.webdriverClient.getAttribute.bind(this.webdriverClient, attribute)); |
| 267 | 0 | this.actionQueue.push(this._attributeCb.bind(this, selector, hash, attribute, expected)); |
| 268 | 0 | return this; |
| 269 | }, | |
| 270 | ||
| 271 | /** | |
| 272 | * Sends out an event with the results of the `attribute` call | |
| 273 | * | |
| 274 | * @method _attributeCb | |
| 275 | * @param {string} selector Selector expression to find the element | |
| 276 | * @param {string} hash Unique hash of that fn call | |
| 277 | * @param {string} attribute The attribute that should be checked | |
| 278 | * @param {string} expected The expected attribute content | |
| 279 | * @param {string} result Serialized JSON with the results of the attribute call | |
| 280 | * @return {object} promise Attribute promise | |
| 281 | * @private | |
| 282 | */ | |
| 283 | ||
| 284 | _attributeCb: function (selector, hash, attribute, expected, result) { | |
| 285 | 0 | var deferred = Q.defer(); |
| 286 | 0 | this.events.emit('driver:message', {key: 'attribute', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value }); |
| 287 | 0 | deferred.resolve(); |
| 288 | 0 | return deferred.promise; |
| 289 | }, | |
| 290 | ||
| 291 | /** | |
| 292 | * Checks if an element has the expected value | |
| 293 | * | |
| 294 | * @method val | |
| 295 | * @param {string} selector Selector expression to find the element | |
| 296 | * @param {string} expected The expected content | |
| 297 | * @param {string} hash Unique hash of that fn call | |
| 298 | * @chainable | |
| 299 | */ | |
| 300 | ||
| 301 | val: function (selector, expected, hash) { | |
| 302 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 303 | 0 | this.actionQueue.push(this.webdriverClient.getAttribute.bind(this.webdriverClient, 'value')); |
| 304 | 0 | this.actionQueue.push(this._valCb.bind(this, selector, hash, expected)); |
| 305 | 0 | return this; |
| 306 | }, | |
| 307 | ||
| 308 | /** | |
| 309 | * Sends out an event with the results of the `val` call | |
| 310 | * | |
| 311 | * @method _valCb | |
| 312 | * @param {string} selector Selector expression to find the element | |
| 313 | * @param {string} hash Unique hash of that fn call | |
| 314 | * @param {string} expected The expected content | |
| 315 | * @param {string} result Serialized JSON with the results of the val call | |
| 316 | * @return {object} Promise | |
| 317 | * @private | |
| 318 | */ | |
| 319 | ||
| 320 | _valCb: function (selector, hash, expected, result) { | |
| 321 | 0 | var deferred = Q.defer(); |
| 322 | 0 | this.events.emit('driver:message', {key: 'val', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value }); |
| 323 | 0 | deferred.resolve(); |
| 324 | 0 | return deferred.promise; |
| 325 | }, | |
| 326 | ||
| 327 | /** | |
| 328 | * Checks if an element is selected | |
| 329 | * | |
| 330 | * @method selected | |
| 331 | * @param {string} selector Selector expression to find the element | |
| 332 | * @param {string} expected The expected content | |
| 333 | * @param {string} hash Unique hash of that fn call | |
| 334 | * @chainable | |
| 335 | */ | |
| 336 | ||
| 337 | selected: function (selector, expected, hash) { | |
| 338 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 339 | 0 | this.actionQueue.push(this.webdriverClient.selected.bind(this.webdriverClient)); |
| 340 | 0 | this.actionQueue.push(this._selectedCb.bind(this, selector, hash, expected)); |
| 341 | 0 | return this; |
| 342 | }, | |
| 343 | ||
| 344 | /** | |
| 345 | * Sends out an event with the results of the `selected` call | |
| 346 | * | |
| 347 | * @method _selectedCb | |
| 348 | * @param {string} selector Selector expression to find the element | |
| 349 | * @param {string} hash Unique hash of that fn call | |
| 350 | * @param {string} expected The expected content | |
| 351 | * @param {string} result Serialized JSON with the results of the selected call | |
| 352 | * @return {object} Promise | |
| 353 | * @private | |
| 354 | */ | |
| 355 | ||
| 356 | _selectedCb: function (selector, hash, expected, result) { | |
| 357 | 0 | var deferred = Q.defer(); |
| 358 | 0 | this.events.emit('driver:message', {key: 'selected', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value }); |
| 359 | 0 | deferred.resolve(); |
| 360 | 0 | return deferred.promise; |
| 361 | }, | |
| 362 | ||
| 363 | /** | |
| 364 | * Checks if an element is enabled | |
| 365 | * | |
| 366 | * @method enabled | |
| 367 | * @param {string} selector Selector expression to find the element | |
| 368 | * @param {string} expected The expected content | |
| 369 | * @param {string} hash Unique hash of that fn call | |
| 370 | * @chainable | |
| 371 | */ | |
| 372 | ||
| 373 | enabled: function (selector, expected, hash) { | |
| 374 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 375 | 0 | this.actionQueue.push(this.webdriverClient.enabled.bind(this.webdriverClient)); |
| 376 | 0 | this.actionQueue.push(this._enabledCb.bind(this, selector, hash, expected)); |
| 377 | 0 | return this; |
| 378 | }, | |
| 379 | ||
| 380 | /** | |
| 381 | * Sends out an event with the results of the `enabled` call | |
| 382 | * | |
| 383 | * @method _enabledCb | |
| 384 | * @param {string} selector Selector expression to find the element | |
| 385 | * @param {string} hash Unique hash of that fn call | |
| 386 | * @param {string} expected The expected content | |
| 387 | * @param {string} result Serialized JSON with the results of the selected call | |
| 388 | * @return {object} Promise | |
| 389 | * @private | |
| 390 | */ | |
| 391 | ||
| 392 | _enabledCb: function (selector, hash, expected, result) { | |
| 393 | 0 | var deferred = Q.defer(); |
| 394 | 0 | this.events.emit('driver:message', {key: 'enabled', selector: selector, hash: hash, expected: expected, value: JSON.parse(result).value }); |
| 395 | 0 | deferred.resolve(); |
| 396 | 0 | return deferred.promise; |
| 397 | }, | |
| 398 | ||
| 399 | /** | |
| 400 | * Submits a form | |
| 401 | * | |
| 402 | * @method submit | |
| 403 | * @param {string} selector Selector expression to find the element | |
| 404 | * @param {string} hash Unique hash of that fn call | |
| 405 | * @param {string} uuid Unique hash of that fn call | |
| 406 | * @chainable | |
| 407 | */ | |
| 408 | ||
| 409 | submit: function (selector, hash, uuid) { | |
| 410 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 411 | 0 | this.actionQueue.push(this.webdriverClient.submit.bind(this.webdriverClient)); |
| 412 | 0 | this.actionQueue.push(this._submitCb.bind(this, selector, hash, uuid)); |
| 413 | 0 | return this; |
| 414 | }, | |
| 415 | ||
| 416 | /** | |
| 417 | * Sends out an event with the results of the `submit` call | |
| 418 | * | |
| 419 | * @method _submitCb | |
| 420 | * @param {string} selector Selector expression to find the element | |
| 421 | * @param {string} hash Unique hash of that fn call | |
| 422 | * @param {string} uuid Unique hash of that fn call | |
| 423 | * @return {object} promise Click promise | |
| 424 | * @private | |
| 425 | */ | |
| 426 | ||
| 427 | _submitCb: function (selector, hash, uuid) { | |
| 428 | 0 | var deferred = Q.defer(); |
| 429 | 0 | this.events.emit('driver:message', {key: 'submit', value: selector, uuid: uuid, hash: hash}); |
| 430 | 0 | deferred.resolve(); |
| 431 | 0 | return deferred.promise; |
| 432 | }, | |
| 433 | ||
| 434 | /** | |
| 435 | * Clicks an element | |
| 436 | * | |
| 437 | * @method click | |
| 438 | * @param {string} selector Selector expression to find the element | |
| 439 | * @param {string} hash Unique hash of that fn call | |
| 440 | * @param {string} uuid Unique hash of that fn call | |
| 441 | * @chainable | |
| 442 | */ | |
| 443 | ||
| 444 | click: function (selector, hash, uuid) { | |
| 445 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 446 | 0 | this.actionQueue.push(this.webdriverClient.click.bind(this.webdriverClient)); |
| 447 | 0 | this.actionQueue.push(this._clickCb.bind(this, selector, hash, uuid)); |
| 448 | 0 | return this; |
| 449 | }, | |
| 450 | ||
| 451 | /** | |
| 452 | * Sends out an event with the results of the `click` call | |
| 453 | * | |
| 454 | * @method _clickCb | |
| 455 | * @param {string} selector Selector expression to find the element | |
| 456 | * @param {string} hash Unique hash of that fn call | |
| 457 | * @param {string} uuid Unique hash of that fn call | |
| 458 | * @return {object} promise Click promise | |
| 459 | * @private | |
| 460 | */ | |
| 461 | ||
| 462 | _clickCb: function (selector, hash, uuid) { | |
| 463 | 0 | var deferred = Q.defer(); |
| 464 | 0 | this.events.emit('driver:message', {key: 'click', value: selector, uuid: uuid, hash: hash}); |
| 465 | 0 | deferred.resolve(); |
| 466 | 0 | return deferred.promise; |
| 467 | }, | |
| 468 | ||
| 469 | /** | |
| 470 | * Scrolls from an element to a location defined in pixels | |
| 471 | * | |
| 472 | * @method scroll | |
| 473 | * @param {string} selector Selector expression to find the element | |
| 474 | * @param {object} options X offset, Y offset, Speed | |
| 475 | * @param {string} hash Unique hash of that fn call | |
| 476 | * @param {string} uuid Unique hash of that fn call | |
| 477 | * @chainable | |
| 478 | */ | |
| 479 | ||
| 480 | scroll: function (selector, options, hash, uuid) { | |
| 481 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector, options)); |
| 482 | 0 | this.actionQueue.push(this.webdriverClient.scroll.bind(this.webdriverClient)); |
| 483 | 0 | this.actionQueue.push(this._clickCb.bind(this, selector, options, hash, uuid)); |
| 484 | 0 | return this; |
| 485 | }, | |
| 486 | ||
| 487 | /** | |
| 488 | * Sends out an event with the results of the `scroll` call | |
| 489 | * | |
| 490 | * @method _scrollCb | |
| 491 | * @param {string} selector Selector expression to find the element | |
| 492 | * @param {object} options X offset, Y offset, Speed | |
| 493 | * @param {string} hash Unique hash of that fn call | |
| 494 | * @param {string} uuid Unique hash of that fn call | |
| 495 | * @return {object} promise Scroll promise | |
| 496 | * @private | |
| 497 | */ | |
| 498 | ||
| 499 | _scrollCb: function (selector, options, hash, uuid) { | |
| 500 | 0 | var deferred = Q.defer(); |
| 501 | 0 | this.events.emit('driver:message', {key: 'scroll', value: selector, uuid: uuid, hash: hash}); |
| 502 | 0 | deferred.resolve(); |
| 503 | 0 | return deferred.promise; |
| 504 | }, | |
| 505 | ||
| 506 | /** | |
| 507 | * Clicks an element | |
| 508 | * | |
| 509 | * @method click | |
| 510 | * @param {string} selector Selector expression to find the element | |
| 511 | * @param {string} hash Unique hash of that fn call | |
| 512 | * @chainable | |
| 513 | */ | |
| 514 | ||
| 515 | type: function (selector, keystrokes, hash) { | |
| 516 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 517 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 518 | 0 | this.actionQueue.push(this.webdriverClient.val.bind(this.webdriverClient, keystrokes)); |
| 519 | 0 | this.actionQueue.push(this._typeCb.bind(this, selector, keystrokes, hash)); |
| 520 | 0 | return this; |
| 521 | }, | |
| 522 | ||
| 523 | /** | |
| 524 | * Sends out an event with the results of the `type` call | |
| 525 | * | |
| 526 | * @method _typeCb | |
| 527 | * @param {string} selector Selector expression to find the element | |
| 528 | * @param {string} hash Unique hash of that fn call | |
| 529 | * @return {object} promise Type promise | |
| 530 | * @private | |
| 531 | */ | |
| 532 | ||
| 533 | _typeCb: function (selector, keystrokes, hash) { | |
| 534 | 0 | var deferred = Q.defer(); |
| 535 | 0 | this.events.emit('driver:message', {key: 'type', value: selector, keystrokes: keystrokes, uuid: hash, hash: hash}); |
| 536 | 0 | deferred.resolve(); |
| 537 | 0 | return deferred.promise; |
| 538 | }, | |
| 539 | ||
| 540 | /** | |
| 541 | * Set a value to an Element | |
| 542 | * | |
| 543 | * @method setValue | |
| 544 | * @param {string} selector Selector expression to find the element | |
| 545 | * @param {string} hash Unique hash of that fn call | |
| 546 | * @chainable | |
| 547 | */ | |
| 548 | ||
| 549 | setValue: function (selector, keystrokes, hash) { | |
| 550 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 551 | 0 | this.actionQueue.push(this.webdriverClient.clear.bind(this.webdriverClient, selector)); |
| 552 | 0 | this.actionQueue.push(this.webdriverClient.val.bind(this.webdriverClient, keystrokes)); |
| 553 | 0 | this.actionQueue.push(this._setValueCb.bind(this, selector, keystrokes, hash)); |
| 554 | 0 | return this; |
| 555 | }, | |
| 556 | ||
| 557 | /** | |
| 558 | * Sends out an event with the results of the `setvalue` call | |
| 559 | * | |
| 560 | * @method _setValueCb | |
| 561 | * @param {string} selector Selector expression to find the element | |
| 562 | * @param {string} keystrokes Value to set | |
| 563 | * @param {string} hash Unique hash of that fn call | |
| 564 | * @return {object} promise Type promise | |
| 565 | * @private | |
| 566 | */ | |
| 567 | ||
| 568 | _setValueCb: function (selector, keystrokes, hash) { | |
| 569 | 0 | var deferred = Q.defer(); |
| 570 | 0 | this.events.emit('driver:message', {key: 'setValue', value: selector, keystrokes: keystrokes, uuid: hash, hash: hash}); |
| 571 | 0 | deferred.resolve(); |
| 572 | 0 | return deferred.promise; |
| 573 | }, | |
| 574 | ||
| 575 | /** | |
| 576 | * Sends keys to an element (whether or not it is an input) | |
| 577 | * | |
| 578 | * @method sendKeys | |
| 579 | * @param {string} selector Selector expression to find the element | |
| 580 | * @param {string} hash Unique hash of that fn call | |
| 581 | * @chainable | |
| 582 | */ | |
| 583 | ||
| 584 | sendKeys: function (selector, keystrokes, hash) { | |
| 585 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 586 | 0 | this.actionQueue.push(this.webdriverClient.sendKeys.bind(this.webdriverClient, keystrokes)); |
| 587 | 0 | this.actionQueue.push(this._sendKeysCb.bind(this, selector, keystrokes, hash)); |
| 588 | 0 | return this; |
| 589 | }, | |
| 590 | ||
| 591 | /** | |
| 592 | * Sends out an event with the results of the `sendKeys` call | |
| 593 | * | |
| 594 | * @method _sendKeysCb | |
| 595 | * @param {string} selector Selector expression to find the element | |
| 596 | * @param {string} hash Unique hash of that fn call | |
| 597 | * @return {object} promise Type promise | |
| 598 | * @private | |
| 599 | */ | |
| 600 | ||
| 601 | _sendKeysCb: function (selector, keystrokes, hash) { | |
| 602 | 0 | var deferred = Q.defer(); |
| 603 | 0 | this.events.emit('driver:message', {key: 'sendKeys', value: selector, keystrokes: keystrokes, uuid: hash, hash: hash}); |
| 604 | 0 | deferred.resolve(); |
| 605 | 0 | return deferred.promise; |
| 606 | }, | |
| 607 | ||
| 608 | /** | |
| 609 | * Wait for an element for a specific amount of time | |
| 610 | * | |
| 611 | * @method waitForElement | |
| 612 | * @param {string} selector Selector expression to find the element | |
| 613 | * @param {integer} timeout Time to wait in ms | |
| 614 | * @param {string} hash Unique hash of that fn call | |
| 615 | * @param {string} uuid Unique hash of that fn call | |
| 616 | * @chainable | |
| 617 | */ | |
| 618 | ||
| 619 | waitForElement: function (selector, timeout, hash, uuid) { | |
| 620 | 0 | this.actionQueue.push(this.webdriverClient.implicitWait.bind(this.webdriverClient, timeout)); |
| 621 | 0 | this.actionQueue.push(this._waitForElementCb.bind(this, selector, hash, uuid)); |
| 622 | 0 | return this; |
| 623 | }, | |
| 624 | ||
| 625 | /** | |
| 626 | * Sends out an event with the results of the `waitForElement` call | |
| 627 | * | |
| 628 | * @method _waitForElementCb | |
| 629 | * @param {string} selector Selector expression to find the element | |
| 630 | * @param {string} hash Unique hash of that fn call | |
| 631 | * @param {string} uuid Unique hash of that fn call | |
| 632 | * @return {object} promise WaitForElement promise | |
| 633 | * @private | |
| 634 | */ | |
| 635 | ||
| 636 | _waitForElementCb: function (selector, hash, uuid) { | |
| 637 | 0 | var deferred = Q.defer(); |
| 638 | 0 | this.events.emit('driver:message', {key: 'waitForElement', selector: selector, value: selector, uuid: uuid, hash: hash}); |
| 639 | 0 | deferred.resolve(); |
| 640 | 0 | return deferred.promise; |
| 641 | }, | |
| 642 | ||
| 643 | /** | |
| 644 | * Returns the number of elements matched by the selector | |
| 645 | * | |
| 646 | * @method getNumberOfElements | |
| 647 | * @param {string} selector Selector expression to find the elements | |
| 648 | * @param {integer} expected Expected number of matched elements | |
| 649 | * @param {string} uuid Unique hash of that fn call | |
| 650 | * @chainable | |
| 651 | */ | |
| 652 | ||
| 653 | getNumberOfElements: function (selector, expected, hash) { | |
| 654 | 0 | this.actionQueue.push(this.webdriverClient.elements.bind(this.webdriverClient, selector)); |
| 655 | 0 | this.actionQueue.push(this._getNumberOfElementsCb.bind(this, selector, hash, expected)); |
| 656 | 0 | return this; |
| 657 | }, | |
| 658 | ||
| 659 | /** | |
| 660 | * Sends out an event with the results of the `getNumberOfElements` call | |
| 661 | * | |
| 662 | * @method _getNumberOfElementsCb | |
| 663 | * @param {string} selector Selector expression to find the element | |
| 664 | * @param {string} hash Unique hash of that fn call | |
| 665 | * @param {integer} expected Expected number of matched elements | |
| 666 | * @param {string} res Serialized JSON with the results of the getNumberOfElements call | |
| 667 | * @return {object} promise GetNumberOfElements promise | |
| 668 | * @private | |
| 669 | */ | |
| 670 | ||
| 671 | _getNumberOfElementsCb: function (selector, hash, expected, res) { | |
| 672 | 0 | var deferred = Q.defer(); |
| 673 | 0 | var result = JSON.parse(res); |
| 674 | // check if the expression matched any element | |
| 675 | 0 | if (result.value === -1) { |
| 676 | 0 | this.events.emit('driver:message', {key: 'numberOfElements', hash: hash, selector: selector, expected: expected, value: 0}); |
| 677 | } else { | |
| 678 | 0 | this.events.emit('driver:message', {key: 'numberOfElements', selector: selector, expected: expected, hash: hash, value: result.value.length}); |
| 679 | } | |
| 680 | ||
| 681 | 0 | deferred.resolve(); |
| 682 | 0 | return deferred.promise; |
| 683 | }, | |
| 684 | ||
| 685 | ||
| 686 | /** | |
| 687 | * Returns the number of visible elements matched by the selector | |
| 688 | * | |
| 689 | * @method getNumberOfVisibleElements | |
| 690 | * @param {string} selector Selector expression to find the elements | |
| 691 | * @param {integer} expected Expected number of matched elements | |
| 692 | * @param {string} uuid Unique hash of that fn call | |
| 693 | * @chainable | |
| 694 | */ | |
| 695 | ||
| 696 | getNumberOfVisibleElements: function (selector, expected, hash) { | |
| 697 | 0 | this.actionQueue.push(this.webdriverClient.elements.bind(this.webdriverClient, selector)); |
| 698 | 0 | this.actionQueue.push(function (result) { |
| 699 | 0 | var deferred = Q.defer(); |
| 700 | 0 | var res = JSON.parse(result); |
| 701 | 0 | var resLength = res.value.length; |
| 702 | 0 | var curLength = 0; |
| 703 | 0 | var visibleElement = []; |
| 704 | ||
| 705 | 0 | res.value.forEach(function (element) { |
| 706 | 0 | var fakeResponse = JSON.stringify({sessionId: res.sessionId, status: 0, value: element.ELEMENT}); |
| 707 | 0 | this.webdriverClient.options.id = element.ELEMENT; |
| 708 | 0 | this.webdriverClient.displayed.bind(this.webdriverClient, selector)(fakeResponse).then(function (visRes) { |
| 709 | 0 | curLength++; |
| 710 | 0 | if (JSON.parse(visRes).value === true) { |
| 711 | 0 | visibleElement.push(element); |
| 712 | } | |
| 713 | 0 | if (curLength === resLength) { |
| 714 | 0 | deferred.resolve(JSON.stringify({sessionId: res.sessionId, status: 0, value: visibleElement})); |
| 715 | } | |
| 716 | }); | |
| 717 | }.bind(this)); | |
| 718 | ||
| 719 | 0 | return deferred.promise; |
| 720 | }.bind(this)); | |
| 721 | 0 | this.actionQueue.push(this._getNumberOfVisibleElementsCb.bind(this, selector, hash, expected)); |
| 722 | 0 | return this; |
| 723 | }, | |
| 724 | ||
| 725 | /** | |
| 726 | * Sends out an event with the results of the `getNumberOfVisibleElements` call | |
| 727 | * | |
| 728 | * @method _getNumberOfElementsCb | |
| 729 | * @param {string} selector Selector expression to find the element | |
| 730 | * @param {string} hash Unique hash of that fn call | |
| 731 | * @param {integer} expected Expected number of matched elements | |
| 732 | * @param {string} res Serialized JSON with the results of the getNumberOfVisibleElements call | |
| 733 | * @return {object} promise GetNumberOfElements promise | |
| 734 | * @private | |
| 735 | */ | |
| 736 | ||
| 737 | _getNumberOfVisibleElementsCb: function (selector, hash, expected, res) { | |
| 738 | 0 | var deferred = Q.defer(); |
| 739 | 0 | var result = JSON.parse(res); |
| 740 | ||
| 741 | // check if the expression matched any element | |
| 742 | 0 | if (result.value === -1) { |
| 743 | 0 | this.events.emit('driver:message', {key: 'numberOfVisibleElements', hash: hash, selector: selector, expected: expected, value: 0}); |
| 744 | } else { | |
| 745 | 0 | this.events.emit('driver:message', {key: 'numberOfVisibleElements', selector: selector, expected: expected, hash: hash, value: result.value.length}); |
| 746 | } | |
| 747 | ||
| 748 | 0 | deferred.resolve(); |
| 749 | 0 | return deferred.promise; |
| 750 | } | |
| 751 | ||
| 752 | }; | |
| 753 | ||
| 754 | /** | |
| 755 | * Mixes in element methods | |
| 756 | * | |
| 757 | * @param {Dalek.DriverNative} DalekNative Native driver base class | |
| 758 | * @return {Dalek.DriverNative} DalekNative Native driver base class | |
| 759 | */ | |
| 760 | ||
| 761 | 1 | module.exports = function (DalekNative) { |
| 762 | // mixin methods | |
| 763 | 0 | Object.keys(Element).forEach(function (fn) { |
| 764 | 0 | DalekNative.prototype[fn] = Element[fn]; |
| 765 | }); | |
| 766 | ||
| 767 | 0 | return DalekNative; |
| 768 | }; | |
| 769 |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * | |
| 3 | * Copyright (c) 2013 Sebastian Golasch | |
| 4 | * | |
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | |
| 6 | * copy of this software and associated documentation files (the "Software"), | |
| 7 | * to deal in the Software without restriction, including without limitation | |
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | |
| 10 | * Software is furnished to do so, subject to the following conditions: | |
| 11 | * | |
| 12 | * The above copyright notice and this permission notice shall be included | |
| 13 | * in all copies or substantial portions of the Software. | |
| 14 | * | |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 21 | * DEALINGS IN THE SOFTWARE. | |
| 22 | * | |
| 23 | */ | |
| 24 | ||
| 25 | 1 | 'use strict'; |
| 26 | ||
| 27 | // ext. libs | |
| 28 | 1 | var Q = require('q'); |
| 29 | ||
| 30 | /** | |
| 31 | * Frame related methods | |
| 32 | * | |
| 33 | * @module Driver | |
| 34 | * @class Frame | |
| 35 | * @namespace Dalek.DriverNative.Commands | |
| 36 | */ | |
| 37 | ||
| 38 | 1 | var Frame = { |
| 39 | ||
| 40 | /** | |
| 41 | * Switches to frame context | |
| 42 | * | |
| 43 | * @method toFrame | |
| 44 | * @param {string} selector Selector expression to find the element | |
| 45 | * @param {string} hash Unique hash of that fn call | |
| 46 | * @chainable | |
| 47 | */ | |
| 48 | ||
| 49 | toFrame: function (selector, hash) { | |
| 50 | 0 | if (selector !== null) { |
| 51 | 0 | this.actionQueue.push(this.webdriverClient.element.bind(this.webdriverClient, selector)); |
| 52 | } | |
| 53 | 0 | this.actionQueue.push(this.webdriverClient.frame.bind(this.webdriverClient)); |
| 54 | 0 | this.actionQueue.push(this._frameCb.bind(this, selector, hash)); |
| 55 | 0 | return this; |
| 56 | }, | |
| 57 | ||
| 58 | /** | |
| 59 | * Sends out an event with the results of the `toFrame` call | |
| 60 | * | |
| 61 | * @method _frameCb | |
| 62 | * @param {string} selector Selector expression to find the element | |
| 63 | * @param {string} hash Unique hash of that fn call | |
| 64 | * @param {string} result Serialized JSON with the reuslts of the toFrame call | |
| 65 | * @return {object} promise Exists promise | |
| 66 | * @private | |
| 67 | */ | |
| 68 | ||
| 69 | _frameCb: function (selector, hash) { | |
| 70 | 0 | var deferred = Q.defer(); |
| 71 | 0 | this.events.emit('driver:message', {key: 'toFrame', selector: selector, hash: hash, value: true}); |
| 72 | 0 | deferred.resolve(); |
| 73 | 0 | return deferred.promise; |
| 74 | } | |
| 75 | }; | |
| 76 | ||
| 77 | /** | |
| 78 | * Mixes in element methods | |
| 79 | * | |
| 80 | * @param {Dalek.DriverNative} DalekNative Native driver base class | |
| 81 | * @return {Dalek.DriverNative} DalekNative Native driver base class | |
| 82 | */ | |
| 83 | ||
| 84 | 1 | module.exports = function (DalekNative) { |
| 85 | // mixin methods | |
| 86 | 0 | Object.keys(Frame).forEach(function (fn) { |
| 87 | 0 | DalekNative.prototype[fn] = Frame[fn]; |
| 88 | }); | |
| 89 | ||
| 90 | 0 | return DalekNative; |
| 91 | }; | |
| 92 |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * | |
| 3 | * Copyright (c) 2013 Sebastian Golasch | |
| 4 | * | |
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | |
| 6 | * copy of this software and associated documentation files (the "Software"), | |
| 7 | * to deal in the Software without restriction, including without limitation | |
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | |
| 10 | * Software is furnished to do so, subject to the following conditions: | |
| 11 | * | |
| 12 | * The above copyright notice and this permission notice shall be included | |
| 13 | * in all copies or substantial portions of the Software. | |
| 14 | * | |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 21 | * DEALINGS IN THE SOFTWARE. | |
| 22 | * | |
| 23 | */ | |
| 24 | ||
| 25 | 1 | 'use strict'; |
| 26 | ||
| 27 | // ext. libs | |
| 28 | 1 | var Q = require('q'); |
| 29 | ||
| 30 | /** | |
| 31 | * Page related methods | |
| 32 | * | |
| 33 | * @module Driver | |
| 34 | * @class Page | |
| 35 | * @namespace Dalek.DriverNative.Commands | |
| 36 | */ | |
| 37 | ||
| 38 | 1 | var Page = { |
| 39 | ||
| 40 | /** | |
| 41 | * This function is non operational | |
| 42 | * | |
| 43 | * @method noop | |
| 44 | * @param {mixed} message Whatever yu like | |
| 45 | * @param {string} hash Unique hash of that fn call | |
| 46 | * @chainable | |
| 47 | */ | |
| 48 | ||
| 49 | noop: function (message, hash) { | |
| 50 | 0 | this.actionQueue.push(this._noopCb.bind(this, message, hash)); |
| 51 | 0 | return this; |
| 52 | }, | |
| 53 | ||
| 54 | /** | |
| 55 | * Sends out an event with the results of the `noop` call | |
| 56 | * | |
| 57 | * @method _noopCb | |
| 58 | * @param {mixed} message Whatever yu like | |
| 59 | * @param {string} hash Unique hash of that fn call | |
| 60 | * @return {object} Promise | |
| 61 | * @private | |
| 62 | */ | |
| 63 | ||
| 64 | _noopCb: function (message, hash) { | |
| 65 | 0 | var deferred = Q.defer(); |
| 66 | 0 | this.events.emit('driver:message', {key: 'noop', uuid: hash, hash: hash, value: message}); |
| 67 | 0 | deferred.resolve(); |
| 68 | 0 | return deferred.promise; |
| 69 | }, | |
| 70 | ||
| 71 | /** | |
| 72 | * Gets the HTML source of a page | |
| 73 | * | |
| 74 | * @method source | |
| 75 | * @param {string} hash Unique hash of that fn call | |
| 76 | * @chainable | |
| 77 | */ | |
| 78 | ||
| 79 | source: function (hash) { | |
| 80 | 0 | this.actionQueue.push(this.webdriverClient.source.bind(this.webdriverClient)); |
| 81 | 0 | this.actionQueue.push(this._sourceCb.bind(this, hash)); |
| 82 | 0 | return this; |
| 83 | }, | |
| 84 | ||
| 85 | /** | |
| 86 | * Sends out an event with the results of the `source` call | |
| 87 | * | |
| 88 | * @method _sourceCb | |
| 89 | * @param {string} hash Unique hash of that fn call | |
| 90 | * @param {string} source Serialized JSON with the results of the source call | |
| 91 | * @return {object} Promise | |
| 92 | * @private | |
| 93 | */ | |
| 94 | ||
| 95 | _sourceCb: function (hash, source) { | |
| 96 | 0 | var deferred = Q.defer(); |
| 97 | 0 | this.events.emit('driver:message', {key: 'source', uuid: hash, hash: hash, value: JSON.parse(source).value}); |
| 98 | 0 | deferred.resolve(); |
| 99 | 0 | return deferred.promise; |
| 100 | }, | |
| 101 | ||
| 102 | /** | |
| 103 | * Checks the document title of a page | |
| 104 | * | |
| 105 | * @method title | |
| 106 | * @param {string} expected Expected page title | |
| 107 | * @param {string} hash Unique hash of that fn call | |
| 108 | * @chainable | |
| 109 | */ | |
| 110 | ||
| 111 | title: function (expected, hash) { | |
| 112 | 0 | this.actionQueue.push(this.webdriverClient.title.bind(this.webdriverClient)); |
| 113 | 0 | this.actionQueue.push(this._titleCb.bind(this, expected, hash)); |
| 114 | 0 | return this; |
| 115 | }, | |
| 116 | ||
| 117 | /** | |
| 118 | * Sends out an event with the results of the `title` call | |
| 119 | * | |
| 120 | * @method _titleCb | |
| 121 | * @param {string} expected Expected page title | |
| 122 | * @param {string} hash Unique hash of that fn call | |
| 123 | * @param {string} title Serialized JSON with the results of the title call | |
| 124 | * @return {object} promise Title promise | |
| 125 | * @private | |
| 126 | */ | |
| 127 | ||
| 128 | _titleCb: function (expected, hash, title) { | |
| 129 | 0 | var deferred = Q.defer(); |
| 130 | 0 | this.events.emit('driver:message', {key: 'title', expected: expected, hash: hash, value: JSON.parse(title).value}); |
| 131 | 0 | deferred.resolve(); |
| 132 | 0 | return deferred.promise; |
| 133 | }, | |
| 134 | ||
| 135 | /** | |
| 136 | * Checks the text of an alaert, prompt or confirm dialog | |
| 137 | * | |
| 138 | * @method alertText | |
| 139 | * @param {string} expected Expected alert text | |
| 140 | * @param {string} hash Unique hash of that fn call | |
| 141 | * @chainable | |
| 142 | */ | |
| 143 | ||
| 144 | alertText: function (expected, hash) { | |
| 145 | 0 | this.actionQueue.push(this.webdriverClient.alertText.bind(this.webdriverClient)); |
| 146 | 0 | this.actionQueue.push(this._alertTextCb.bind(this, expected, hash)); |
| 147 | 0 | return this; |
| 148 | }, | |
| 149 | ||
| 150 | /** | |
| 151 | * Sends out an event with the results of the `alertText` call | |
| 152 | * | |
| 153 | * @method _alertTextCb | |
| 154 | * @param {string} expected Expected alert text | |
| 155 | * @param {string} hash Unique hash of that fn call | |
| 156 | * @param {string} alertText Serialized JSON with the results of the alertText call | |
| 157 | * @return {object} promise alertText promise | |
| 158 | * @private | |
| 159 | */ | |
| 160 | ||
| 161 | _alertTextCb: function (expected, hash, alertText) { | |
| 162 | 0 | var deferred = Q.defer(); |
| 163 | 0 | this.events.emit('driver:message', {key: 'alertText', expected: expected, hash: hash, value: JSON.parse(alertText).value}); |
| 164 | 0 | deferred.resolve(); |
| 165 | 0 | return deferred.promise; |
| 166 | }, | |
| 167 | ||
| 168 | /** | |
| 169 | * Sends text to a javascript prompt dialog box | |
| 170 | * | |
| 171 | * @method promptText | |
| 172 | * @param {object} dimensions New window width & height | |
| 173 | * @param {string} hash Unique hash of that fn call | |
| 174 | * @chainable | |
| 175 | */ | |
| 176 | ||
| 177 | promptText: function (text, hash) { | |
| 178 | 0 | this.actionQueue.push(this.webdriverClient.promptText.bind(this.webdriverClient, text)); |
| 179 | 0 | this.actionQueue.push(this._promptTextCb.bind(this, text, hash)); |
| 180 | 0 | return this; |
| 181 | }, | |
| 182 | ||
| 183 | /** | |
| 184 | * Sends out an event with the results of the `promptText` call | |
| 185 | * | |
| 186 | * @method _promptTextCb | |
| 187 | * @param {object} dimensions New window width & height | |
| 188 | * @param {string} hash Unique hash of that fn call | |
| 189 | * @param {string} result Serialized JSON with the reuslts of the toFrame call | |
| 190 | * @return {object} promise Exists promise | |
| 191 | * @private | |
| 192 | */ | |
| 193 | ||
| 194 | _promptTextCb: function (text, hash) { | |
| 195 | 0 | var deferred = Q.defer(); |
| 196 | 0 | this.events.emit('driver:message', {key: 'promptText', text: text, hash: hash, value: true}); |
| 197 | 0 | deferred.resolve(); |
| 198 | 0 | return deferred.promise; |
| 199 | }, | |
| 200 | ||
| 201 | /** | |
| 202 | * Accepts (e.g. oressing the OK button) an javascript alert, prompt or confirm dialog | |
| 203 | * | |
| 204 | * @method acceptAlert | |
| 205 | * @param {string} hash Unique hash of that fn call | |
| 206 | * @chainable | |
| 207 | */ | |
| 208 | ||
| 209 | acceptAlert: function (hash) { | |
| 210 | 0 | this.actionQueue.push(this.webdriverClient.acceptAlert.bind(this.webdriverClient)); |
| 211 | 0 | this.actionQueue.push(this._acceptAlertCb.bind(this, hash)); |
| 212 | 0 | return this; |
| 213 | }, | |
| 214 | ||
| 215 | /** | |
| 216 | * Sends out an event with the results of the `acceptAlert` call | |
| 217 | * | |
| 218 | * @method _acceptAlertCb | |
| 219 | * @param {string} hash Unique hash of that fn call | |
| 220 | * @param {string} result Serialized JSON with the reuslts of the toFrame call | |
| 221 | * @return {object} promise Exists promise | |
| 222 | * @private | |
| 223 | */ | |
| 224 | ||
| 225 | _acceptAlertCb: function (text, hash) { | |
| 226 | 0 | var deferred = Q.defer(); |
| 227 | 0 | this.events.emit('driver:message', {key: 'acceptAlert', hash: hash, value: true}); |
| 228 | 0 | deferred.resolve(); |
| 229 | 0 | return deferred.promise; |
| 230 | }, | |
| 231 | ||
| 232 | /** | |
| 233 | * Accepts (e.g. oressing the OK button) an javascript alert, prompt or confirm dialog | |
| 234 | * | |
| 235 | * @method dismissAlert | |
| 236 | * @param {string} hash Unique hash of that fn call | |
| 237 | * @chainable | |
| 238 | */ | |
| 239 | ||
| 240 | dismissAlert: function (hash) { | |
| 241 | 0 | this.actionQueue.push(this.webdriverClient.dismissAlert.bind(this.webdriverClient)); |
| 242 | 0 | this.actionQueue.push(this._dismissAlertCb.bind(this, hash)); |
| 243 | 0 | return this; |
| 244 | }, | |
| 245 | ||
| 246 | /** | |
| 247 | * Sends out an event with the results of the `dismissAlert` call | |
| 248 | * | |
| 249 | * @method _dismissAlertCb | |
| 250 | * @param {string} hash Unique hash of that fn call | |
| 251 | * @param {string} result Serialized JSON with the reuslts of the toFrame call | |
| 252 | * @return {object} promise Exists promise | |
| 253 | * @private | |
| 254 | */ | |
| 255 | ||
| 256 | _dismissAlertCb: function (text, hash) { | |
| 257 | 0 | var deferred = Q.defer(); |
| 258 | 0 | this.events.emit('driver:message', {key: 'dismissAlert', hash: hash, value: true}); |
| 259 | 0 | deferred.resolve(); |
| 260 | 0 | return deferred.promise; |
| 261 | }, | |
| 262 | ||
| 263 | /** | |
| 264 | * Wait for a specific amount of time | |
| 265 | * | |
| 266 | * @method wait | |
| 267 | * @param {integer} timeout Time to wait in ms | |
| 268 | * @param {string} hash Unique hash of that fn call | |
| 269 | * @param {string} uuid Unique hash of that fn call | |
| 270 | * @chainable | |
| 271 | */ | |
| 272 | ||
| 273 | wait: function (timeout, hash, uuid) { | |
| 274 | 0 | this.actionQueue.push(this.webdriverClient.implicitWait.bind(this.webdriverClient, timeout)); |
| 275 | 0 | this.actionQueue.push(this._waitCb.bind(this, timeout, hash, uuid)); |
| 276 | 0 | return this; |
| 277 | }, | |
| 278 | ||
| 279 | /** | |
| 280 | * Sends out an event with the results of the `wait` call | |
| 281 | * | |
| 282 | * @method _waitCb | |
| 283 | * @param {integer} timeout Time to wait in ms | |
| 284 | * @param {string} hash Unique hash of that fn call | |
| 285 | * @param {string} uuid Unique hash of that fn call | |
| 286 | * @return {object} promise WaitForElement promise | |
| 287 | * @private | |
| 288 | */ | |
| 289 | ||
| 290 | _waitCb: function (timeout, hash, uuid) { | |
| 291 | 0 | var deferred = Q.defer(); |
| 292 | 0 | this.events.emit('driver:message', {key: 'wait', timeout: timeout, uuid: uuid, hash: hash, value: timeout + ' ms'}); |
| 293 | 0 | setTimeout(function () { |
| 294 | 0 | deferred.resolve(); |
| 295 | }.bind(this), timeout); | |
| 296 | 0 | return deferred.promise; |
| 297 | } | |
| 298 | ||
| 299 | }; | |
| 300 | ||
| 301 | /** | |
| 302 | * Mixes in page methods | |
| 303 | * | |
| 304 | * @param {Dalek.DriverNative} DalekNative Native driver base class | |
| 305 | * @return {Dalek.DriverNative} DalekNative Native driver base class | |
| 306 | */ | |
| 307 | ||
| 308 | 1 | module.exports = function (DalekNative) { |
| 309 | // mixin methods | |
| 310 | 0 | Object.keys(Page).forEach(function (fn) { |
| 311 | 0 | DalekNative.prototype[fn] = Page[fn]; |
| 312 | }); | |
| 313 | ||
| 314 | 0 | return DalekNative; |
| 315 | }; | |
| 316 |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * | |
| 3 | * Copyright (c) 2013 Sebastian Golasch | |
| 4 | * | |
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | |
| 6 | * copy of this software and associated documentation files (the "Software"), | |
| 7 | * to deal in the Software without restriction, including without limitation | |
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | |
| 10 | * Software is furnished to do so, subject to the following conditions: | |
| 11 | * | |
| 12 | * The above copyright notice and this permission notice shall be included | |
| 13 | * in all copies or substantial portions of the Software. | |
| 14 | * | |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 21 | * DEALINGS IN THE SOFTWARE. | |
| 22 | * | |
| 23 | */ | |
| 24 | ||
| 25 | 1 | 'use strict'; |
| 26 | ||
| 27 | // ext. libs | |
| 28 | 1 | var Q = require('q'); |
| 29 | 1 | var fs = require('fs'); |
| 30 | ||
| 31 | /** | |
| 32 | * Screenshot related methods | |
| 33 | * | |
| 34 | * @module Driver | |
| 35 | * @class Screenshot | |
| 36 | * @namespace Dalek.DriverNative.Commands | |
| 37 | */ | |
| 38 | ||
| 39 | 1 | var Screenshot = { |
| 40 | ||
| 41 | /** | |
| 42 | * Makes an screenshot of the current page | |
| 43 | * | |
| 44 | * @method screenshot | |
| 45 | * @param {string} path Root directory path | |
| 46 | * @param {string} pathname Pathname of the screenshot path | |
| 47 | * @param {string} hash Unique hash of that fn call | |
| 48 | * @param {string} uuid Unique hash of that fn call | |
| 49 | * @chainable | |
| 50 | */ | |
| 51 | ||
| 52 | screenshot: function (path, pathname, hash, uuid) { | |
| 53 | 0 | this.actionQueue.push(this.webdriverClient.screenshot.bind(this.webdriverClient)); |
| 54 | 0 | this.actionQueue.push(this._screenshotCb.bind(this, path, pathname, hash, uuid)); |
| 55 | 0 | return this; |
| 56 | }, | |
| 57 | ||
| 58 | /** | |
| 59 | * Sends out an event with the results of the `screenshot` call | |
| 60 | * and stores the screenshot in the filesystem | |
| 61 | * | |
| 62 | * @method _screenshotCb | |
| 63 | * @param {string} path Root directory path | |
| 64 | * @param {string} pathname Pathname of the screenshot path | |
| 65 | * @param {string} hash Unique hash of that fn call | |
| 66 | * @param {string} uuid Unique hash of that fn call | |
| 67 | * @param {string} result Serialized JSON result of the screenshot call | |
| 68 | * @return {object} promise Screenshot promise | |
| 69 | * @private | |
| 70 | */ | |
| 71 | ||
| 72 | _screenshotCb: function (path, pathname, hash, uuid, result) { | |
| 73 | 0 | var deferred = Q.defer(); |
| 74 | // replace base64 metadata | |
| 75 | 0 | var base64Data = JSON.parse(result).value.replace(/^data:image\/png;base64,/,''); |
| 76 | // replace placeholders | |
| 77 | 0 | var realpath = this._replacePathPlaceholder(path + pathname); |
| 78 | // check if we need to add a new directory | |
| 79 | 0 | this._recursiveMakeDirSync(realpath.substring(0, realpath.lastIndexOf('/'))); |
| 80 | // write the screenshot | |
| 81 | 0 | fs.writeFileSync(realpath, base64Data, 'base64'); |
| 82 | 0 | this.events.emit('driver:message', {key: 'screenshot', value: realpath, uuid: hash, hash: hash}); |
| 83 | 0 | deferred.resolve(); |
| 84 | 0 | return deferred.promise; |
| 85 | }, | |
| 86 | ||
| 87 | /** | |
| 88 | * Recursige mkdir helper | |
| 89 | * | |
| 90 | * @method _recursiveMakeDirSync | |
| 91 | * @param {string} path Path to create | |
| 92 | * @private | |
| 93 | */ | |
| 94 | ||
| 95 | _recursiveMakeDirSync: function (path) { | |
| 96 | 0 | var normalizedPath = require('path').normalize(path); |
| 97 | 0 | var pathSep = require('path').sep; |
| 98 | 0 | var dirs = normalizedPath.split(pathSep); |
| 99 | 0 | var root = ''; |
| 100 | ||
| 101 | 0 | while (dirs.length > 0) { |
| 102 | 0 | var dir = dirs.shift(); |
| 103 | 0 | if (dir === '') { |
| 104 | 0 | root = pathSep; |
| 105 | } | |
| 106 | 0 | if (!fs.existsSync(root + dir)) { |
| 107 | 0 | fs.mkdirSync(root + dir); |
| 108 | } | |
| 109 | 0 | root += dir + pathSep; |
| 110 | } | |
| 111 | }, | |
| 112 | ||
| 113 | /** | |
| 114 | * Return the formatted os name | |
| 115 | * | |
| 116 | * @method _parseOS | |
| 117 | * @param {string} Pathname | |
| 118 | * @return {string} Formatted pathname | |
| 119 | * @private | |
| 120 | */ | |
| 121 | ||
| 122 | _replacePathPlaceholder: function (pathname) { | |
| 123 | 0 | pathname = pathname.replace(':browser', this.browserName); |
| 124 | 0 | pathname = pathname.replace(':version', this._parseBrowserVersion(this.sessionStatus.version)); |
| 125 | 0 | pathname = pathname.replace(':timestamp', Math.round(new Date().getTime() / 1000)); |
| 126 | 0 | pathname = pathname.replace(':osVersion', this._parseOSVersion(this.driverStatus.os.version)); |
| 127 | 0 | pathname = pathname.replace(':os', this._parseOS(this.driverStatus.os.name)); |
| 128 | 0 | pathname = pathname.replace(':datetime', this._parseDatetime()); |
| 129 | 0 | pathname = pathname.replace(':date', this._parseDate()); |
| 130 | 0 | pathname = pathname.replace(':viewport', this._parseViewport()); |
| 131 | 0 | return pathname; |
| 132 | }, | |
| 133 | ||
| 134 | /** | |
| 135 | * Return the formatted os name | |
| 136 | * | |
| 137 | * @method _parseOS | |
| 138 | * @return {string} OS name | |
| 139 | * @private | |
| 140 | */ | |
| 141 | ||
| 142 | _parseOS: function (os) { | |
| 143 | 0 | var mappings = { |
| 144 | 'mac': 'OSX', | |
| 145 | 'Mac OS X': 'OSX' | |
| 146 | }; | |
| 147 | 0 | return mappings[os] || 'unknown'; |
| 148 | }, | |
| 149 | ||
| 150 | /** | |
| 151 | * Return the formatted os version | |
| 152 | * | |
| 153 | * @method _parseOSVersion | |
| 154 | * @return {string} OS version | |
| 155 | * @private | |
| 156 | */ | |
| 157 | ||
| 158 | _parseOSVersion: function (version) { | |
| 159 | 0 | var vs = version.replace(/[^0-9\\.]/g, ''); |
| 160 | 0 | vs = vs.replace(/\./g, '_'); |
| 161 | 0 | return vs; |
| 162 | }, | |
| 163 | ||
| 164 | /** | |
| 165 | * Return the formatted browser version | |
| 166 | * | |
| 167 | * @method _parseBrowserVersion | |
| 168 | * @return {string} Browser version | |
| 169 | * @private | |
| 170 | */ | |
| 171 | ||
| 172 | _parseBrowserVersion: function (version) { | |
| 173 | 0 | return version.replace(/\./g, '_'); |
| 174 | }, | |
| 175 | ||
| 176 | /** | |
| 177 | * Return the ISO 8601 formatted date | |
| 178 | * | |
| 179 | * @method _parseDate | |
| 180 | * @param {object} optional A javascript date object. If undefined, the current date is used. | |
| 181 | * @return {string} Date | |
| 182 | * @private | |
| 183 | */ | |
| 184 | ||
| 185 | _parseDate: function (date) { | |
| 186 | 12 | date = date ? date : new Date(); |
| 187 | 12 | var day = date.getDate(); |
| 188 | 12 | var month = date.getMonth() + 1; |
| 189 | 12 | var year = date.getFullYear(); |
| 190 | ||
| 191 | 12 | month = ('0' + month).slice(-2); |
| 192 | 12 | day = ('0' + day).slice(-2); |
| 193 | ||
| 194 | 12 | return year + '-' + month + '-' + day; |
| 195 | }, | |
| 196 | ||
| 197 | /** | |
| 198 | * Return the ISO 8601 formatted datetime | |
| 199 | * | |
| 200 | * @method _parseDatetime | |
| 201 | * @param {object} optional A javascript date object. If undefined, the current date is used. | |
| 202 | * @return {string} Datetime | |
| 203 | * @private | |
| 204 | */ | |
| 205 | ||
| 206 | _parseDatetime: function (date) { | |
| 207 | 8 | date = date ? date : new Date(); |
| 208 | 8 | var dateStr = this._parseDate(); |
| 209 | 8 | var timeStr = 'T#hours#:#minutes#:#seconds##formattedOffset#'; |
| 210 | 8 | var hours = date.getHours(); |
| 211 | 8 | var minutes = date.getMinutes(); |
| 212 | 8 | var seconds = date.getSeconds(); |
| 213 | 8 | var offsetHours = '' + Math.ceil(date.getTimezoneOffset() / 60); |
| 214 | 8 | var offsetMinutes = '' + Math.abs(date.getTimezoneOffset() % 60); |
| 215 | 8 | var formattedOffset; |
| 216 | ||
| 217 | 8 | hours = ('0' + hours).slice(-2); |
| 218 | 8 | minutes = ('0' + minutes).slice(-2); |
| 219 | 8 | seconds = ('0' + seconds).slice(-2); |
| 220 | ||
| 221 | 8 | if (offsetHours[0] === '-' && offsetHours.length < 3) { |
| 222 | 2 | formattedOffset = offsetHours[0] + '0' + offsetHours[1]; |
| 223 | 6 | } else if (offsetHours.length < 2) { |
| 224 | 6 | formattedOffset = '+0' + offsetHours; |
| 225 | } | |
| 226 | ||
| 227 | 8 | if (offsetMinutes.length < 2) { |
| 228 | 4 | formattedOffset += ':0' + offsetMinutes; |
| 229 | } else { | |
| 230 | 4 | formattedOffset += ':' + offsetMinutes; |
| 231 | } | |
| 232 | ||
| 233 | 8 | if (offsetHours === '0' && offsetMinutes === '0') { |
| 234 | 2 | formattedOffset = 'Z'; |
| 235 | } | |
| 236 | ||
| 237 | 8 | timeStr = timeStr.replace('#hours#', hours); |
| 238 | 8 | timeStr = timeStr.replace('#minutes#', minutes); |
| 239 | 8 | timeStr = timeStr.replace('#seconds#', seconds); |
| 240 | 8 | timeStr = timeStr.replace('#formattedOffset#', formattedOffset); |
| 241 | ||
| 242 | 8 | return dateStr + timeStr; |
| 243 | }, | |
| 244 | ||
| 245 | /** | |
| 246 | * Return the formatted viewport | |
| 247 | * | |
| 248 | * @method _parseViewport | |
| 249 | * @return {string} Viewport | |
| 250 | * @private | |
| 251 | */ | |
| 252 | ||
| 253 | _parseViewport: function () { | |
| 254 | 0 | var viewport = this.config.get('viewport'); |
| 255 | 0 | return 'w' + viewport.width + '_h' + viewport.height; |
| 256 | } | |
| 257 | ||
| 258 | }; | |
| 259 | ||
| 260 | /** | |
| 261 | * Mixes in screenshot methods | |
| 262 | * | |
| 263 | * @param {Dalek.DriverNative} DalekNative Native driver base class | |
| 264 | * @return {Dalek.DriverNative} DalekNative Native driver base class | |
| 265 | */ | |
| 266 | ||
| 267 | 1 | module.exports = function (DalekNative) { |
| 268 | 12 | if ('undefined' === typeof DalekNative) { |
| 269 | 12 | return Screenshot; |
| 270 | } | |
| 271 | // mixin methods | |
| 272 | 0 | Object.keys(Screenshot).forEach(function (fn) { |
| 273 | 0 | DalekNative.prototype[fn] = Screenshot[fn]; |
| 274 | }); | |
| 275 | ||
| 276 | 0 | return DalekNative; |
| 277 | }; | |
| 278 |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * | |
| 3 | * Copyright (c) 2013 Sebastian Golasch | |
| 4 | * | |
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | |
| 6 | * copy of this software and associated documentation files (the "Software"), | |
| 7 | * to deal in the Software without restriction, including without limitation | |
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | |
| 10 | * Software is furnished to do so, subject to the following conditions: | |
| 11 | * | |
| 12 | * The above copyright notice and this permission notice shall be included | |
| 13 | * in all copies or substantial portions of the Software. | |
| 14 | * | |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 21 | * DEALINGS IN THE SOFTWARE. | |
| 22 | * | |
| 23 | */ | |
| 24 | ||
| 25 | 1 | 'use strict'; |
| 26 | ||
| 27 | // ext. libs | |
| 28 | 1 | var Q = require('q'); |
| 29 | ||
| 30 | /** | |
| 31 | * Url related methods | |
| 32 | * | |
| 33 | * @module Driver | |
| 34 | * @class Url | |
| 35 | * @namespace Dalek.DriverNative.Commands | |
| 36 | */ | |
| 37 | ||
| 38 | 1 | var Url = { |
| 39 | ||
| 40 | /** | |
| 41 | * Navigate to a new URL | |
| 42 | * | |
| 43 | * @method open | |
| 44 | * @param {string} url Url to navigate to | |
| 45 | * @param {string} hash Unique hash of that fn call | |
| 46 | * @param {string} uuid Unique hash of that fn call | |
| 47 | * @chainable | |
| 48 | */ | |
| 49 | ||
| 50 | open: function (url, hash, uuid) { | |
| 51 | 0 | this.lastCalledUrl = url; |
| 52 | 0 | this.actionQueue.push(this.webdriverClient.url.bind(this.webdriverClient, url)); |
| 53 | 0 | this.actionQueue.push(this._openCb.bind(this, url, hash, uuid)); |
| 54 | 0 | return this; |
| 55 | }, | |
| 56 | ||
| 57 | /** | |
| 58 | * Sends out an event with the results of the `open` call | |
| 59 | * | |
| 60 | * @method _openCb | |
| 61 | * @param {string} url Url to navigate to | |
| 62 | * @param {string} hash Unique hash of that fn call | |
| 63 | * @param {string} uuid Unique hash of that fn call | |
| 64 | * @return {object} promise Open promise | |
| 65 | * @private | |
| 66 | */ | |
| 67 | ||
| 68 | _openCb: function (url, hash, uuid) { | |
| 69 | 0 | var deferred = Q.defer(); |
| 70 | 0 | this.events.emit('driver:message', {key: 'open', value: url, hash: hash, uuid: uuid}); |
| 71 | 0 | deferred.resolve(); |
| 72 | 0 | return deferred.promise; |
| 73 | }, | |
| 74 | ||
| 75 | /** | |
| 76 | * Fetches the current url | |
| 77 | * | |
| 78 | * @method url | |
| 79 | * @param {string} expected Expected url | |
| 80 | * @param {string} hash Unique hash of that fn call | |
| 81 | * @chainable | |
| 82 | */ | |
| 83 | ||
| 84 | url: function (expected, hash) { | |
| 85 | 0 | this.actionQueue.push(this.webdriverClient.getUrl.bind(this.webdriverClient)); |
| 86 | 0 | this.actionQueue.push(this._urlCb.bind(this, expected, hash)); |
| 87 | 0 | return this; |
| 88 | }, | |
| 89 | ||
| 90 | /** | |
| 91 | * Sends out an event with the results of the `url` call | |
| 92 | * | |
| 93 | * @method _urlCb | |
| 94 | * @param {string} expected Expected url | |
| 95 | * @param {string} hash Unique hash of that fn call | |
| 96 | * @param {string} url Serialized JSON result of url call | |
| 97 | * @return {object} promise Url promise | |
| 98 | * @private | |
| 99 | */ | |
| 100 | ||
| 101 | _urlCb: function (expected, hash, url) { | |
| 102 | 0 | var deferred = Q.defer(); |
| 103 | 0 | this.events.emit('driver:message', {key: 'url', expected: expected, hash: hash, value: JSON.parse(url).value}); |
| 104 | 0 | deferred.resolve(); |
| 105 | 0 | return deferred.promise; |
| 106 | }, | |
| 107 | ||
| 108 | /** | |
| 109 | * Navigate backwards in the browser history, if possible. | |
| 110 | * | |
| 111 | * @method back | |
| 112 | * @param {string} hash Unique hash of that fn call | |
| 113 | * @param {string} uuid Unique hash of that fn call | |
| 114 | * @chainable | |
| 115 | */ | |
| 116 | ||
| 117 | back: function (hash, uuid) { | |
| 118 | 0 | this._createNonReturnee('back')(hash, uuid); |
| 119 | 0 | return this; |
| 120 | }, | |
| 121 | ||
| 122 | /** | |
| 123 | * Navigate forwards in the browser history, if possible. | |
| 124 | * | |
| 125 | * @method forward | |
| 126 | * @param {string} hash Unique hash of that fn call | |
| 127 | * @param {string} uuid Unique hash of that fn call | |
| 128 | * @chainable | |
| 129 | */ | |
| 130 | ||
| 131 | forward: function (hash, uuid) { | |
| 132 | 0 | this._createNonReturnee('forward')(hash, uuid); |
| 133 | 0 | return this; |
| 134 | }, | |
| 135 | ||
| 136 | /** | |
| 137 | * Refresh the current page | |
| 138 | * | |
| 139 | * @method refresh | |
| 140 | * @param {string} hash Unique hash of that fn call | |
| 141 | * @param {string} uuid Unique hash of that fn call | |
| 142 | * @chainable | |
| 143 | */ | |
| 144 | ||
| 145 | refresh: function (hash, uuid) { | |
| 146 | 0 | this._createNonReturnee('refresh')(hash, uuid); |
| 147 | 0 | return this; |
| 148 | } | |
| 149 | }; | |
| 150 | ||
| 151 | /** | |
| 152 | * Mixes in url methods | |
| 153 | * | |
| 154 | * @param {Dalek.DriverNative} DalekNative Native driver base class | |
| 155 | * @return {Dalek.DriverNative} DalekNative Native driver base class | |
| 156 | */ | |
| 157 | ||
| 158 | 1 | module.exports = function (DalekNative) { |
| 159 | // mixin methods | |
| 160 | 0 | Object.keys(Url).forEach(function (fn) { |
| 161 | 0 | DalekNative.prototype[fn] = Url[fn]; |
| 162 | }); | |
| 163 | ||
| 164 | 0 | return DalekNative; |
| 165 | }; | |
| 166 |
| Line | Hits | Source |
|---|---|---|
| 1 | /*! | |
| 2 | * | |
| 3 | * Copyright (c) 2013 Sebastian Golasch | |
| 4 | * | |
| 5 | * Permission is hereby granted, free of charge, to any person obtaining a | |
| 6 | * copy of this software and associated documentation files (the "Software"), | |
| 7 | * to deal in the Software without restriction, including without limitation | |
| 8 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
| 9 | * and/or sell copies of the Software, and to permit persons to whom the | |
| 10 | * Software is furnished to do so, subject to the following conditions: | |
| 11 | * | |
| 12 | * The above copyright notice and this permission notice shall be included | |
| 13 | * in all copies or substantial portions of the Software. | |
| 14 | * | |
| 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS | |
| 16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
| 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |
| 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |
| 21 | * DEALINGS IN THE SOFTWARE. | |
| 22 | * | |
| 23 | */ | |
| 24 | ||
| 25 | 1 | 'use strict'; |
| 26 | ||
| 27 | // ext. libs | |
| 28 | 1 | var Q = require('q'); |
| 29 | ||
| 30 | /** | |
| 31 | * Window related methods | |
| 32 | * | |
| 33 | * @module Driver | |
| 34 | * @class Window | |
| 35 | * @namespace Dalek.DriverNative.Commands | |
| 36 | */ | |
| 37 | ||
| 38 | 1 | var Window = { |
| 39 | ||
| 40 | /** | |
| 41 | * Switches to another window context | |
| 42 | * | |
| 43 | * @method toFrame | |
| 44 | * @param {string} name Name of the window to switch to | |
| 45 | * @param {string} hash Unique hash of that fn call | |
| 46 | * @chainable | |
| 47 | */ | |
| 48 | ||
| 49 | toWindow: function (name, hash) { | |
| 50 | 0 | this.actionQueue.push(this.webdriverClient.windowHandles.bind(this.webdriverClient)); |
| 51 | 0 | this.actionQueue.push(function (result) { |
| 52 | 0 | var deferred = Q.defer(); |
| 53 | 0 | if (name === null) { |
| 54 | 0 | deferred.resolve(JSON.parse(result).value[0]); |
| 55 | } | |
| 56 | 0 | deferred.resolve(name); |
| 57 | 0 | return deferred.promise; |
| 58 | }); | |
| 59 | 0 | this.actionQueue.push(this.webdriverClient.changeWindow.bind(this.webdriverClient)); |
| 60 | 0 | this.actionQueue.push(this._windowCb.bind(this, name, hash)); |
| 61 | 0 | return this; |
| 62 | }, | |
| 63 | ||
| 64 | /** | |
| 65 | * Sends out an event with the results of the `toWindow` call | |
| 66 | * | |
| 67 | * @method _windowCb | |
| 68 | * @param {string} name Name of the window to switch to | |
| 69 | * @param {string} hash Unique hash of that fn call | |
| 70 | * @param {string} result Serialized JSON with the reuslts of the toFrame call | |
| 71 | * @return {object} promise Exists promise | |
| 72 | * @private | |
| 73 | */ | |
| 74 | ||
| 75 | _windowCb: function (name, hash) { | |
| 76 | 0 | var deferred = Q.defer(); |
| 77 | 0 | this.events.emit('driver:message', {key: 'toWindow', name: name, hash: hash, value: true}); |
| 78 | 0 | deferred.resolve(); |
| 79 | 0 | return deferred.promise; |
| 80 | }, | |
| 81 | ||
| 82 | /** | |
| 83 | * Resizes the current window | |
| 84 | * | |
| 85 | * @method resize | |
| 86 | * @param {object} dimensions New window width & height | |
| 87 | * @param {string} hash Unique hash of that fn call | |
| 88 | * @chainable | |
| 89 | */ | |
| 90 | ||
| 91 | resize: function (dimensions, hash) { | |
| 92 | 0 | this.actionQueue.push(this.webdriverClient.setWindowSize.bind(this.webdriverClient, dimensions.width, dimensions.height)); |
| 93 | 0 | this.actionQueue.push(this._resizeCb.bind(this, dimensions, hash)); |
| 94 | 0 | return this; |
| 95 | }, | |
| 96 | ||
| 97 | /** | |
| 98 | * Sends out an event with the results of the `resize` call | |
| 99 | * and stores the current viewport dimensions to the | |
| 100 | * globale Config | |
| 101 | * | |
| 102 | * @method _windowCb | |
| 103 | * @param {object} dimensions New window width & height | |
| 104 | * @param {string} hash Unique hash of that fn call | |
| 105 | * @param {string} result Serialized JSON with the reuslts of the toFrame call | |
| 106 | * @return {object} promise Exists promise | |
| 107 | * @private | |
| 108 | */ | |
| 109 | ||
| 110 | _resizeCb: function (dimensions, hash) { | |
| 111 | 0 | var deferred = Q.defer(); |
| 112 | 0 | this.config.config.viewport = dimensions; |
| 113 | 0 | this.events.emit('driver:message', {key: 'resize', dimensions: dimensions, hash: hash, value: true}); |
| 114 | 0 | deferred.resolve(); |
| 115 | 0 | return deferred.promise; |
| 116 | }, | |
| 117 | ||
| 118 | /** | |
| 119 | * Maximizes the current window | |
| 120 | * | |
| 121 | * @method maximize | |
| 122 | * @param {string} hash Unique hash of that fn call | |
| 123 | * @chainable | |
| 124 | */ | |
| 125 | ||
| 126 | maximize: function (hash) { | |
| 127 | 0 | this.actionQueue.push(this.webdriverClient.maximize.bind(this.webdriverClient)); |
| 128 | 0 | this.actionQueue.push(this._maximizeCb.bind(this, hash)); |
| 129 | 0 | return this; |
| 130 | }, | |
| 131 | ||
| 132 | /** | |
| 133 | * Sends out an event with the results of the `maximize` call | |
| 134 | * | |
| 135 | * @method _maximizeCb | |
| 136 | * @param {string} hash Unique hash of that fn call | |
| 137 | * @param {string} result Serialized JSON with the reuslts of the toFrame call | |
| 138 | * @return {object} promise Exists promise | |
| 139 | * @private | |
| 140 | */ | |
| 141 | ||
| 142 | _maximizeCb: function (hash) { | |
| 143 | 0 | var deferred = Q.defer(); |
| 144 | 0 | this.events.emit('driver:message', {key: 'maximize', hash: hash, value: true}); |
| 145 | 0 | deferred.resolve(); |
| 146 | 0 | return deferred.promise; |
| 147 | }, | |
| 148 | ||
| 149 | /** | |
| 150 | * Closes the current window | |
| 151 | * | |
| 152 | * @method close | |
| 153 | * @param {string} hash Unique hash of that fn call | |
| 154 | * @chainable | |
| 155 | */ | |
| 156 | ||
| 157 | close: function (hash) { | |
| 158 | 0 | this.actionQueue.push(this.webdriverClient.close.bind(this.webdriverClient)); |
| 159 | 0 | this.actionQueue.push(this._closeCb.bind(this, hash)); |
| 160 | 0 | return this; |
| 161 | }, | |
| 162 | ||
| 163 | /** | |
| 164 | * Sends out an event with the results of the `close` call | |
| 165 | * | |
| 166 | * @method _closeCb | |
| 167 | * @param {string} hash Unique hash of that fn call | |
| 168 | * @return {object} promise Exists promise | |
| 169 | * @private | |
| 170 | */ | |
| 171 | ||
| 172 | _closeCb: function (hash) { | |
| 173 | 0 | var deferred = Q.defer(); |
| 174 | 0 | this.events.emit('driver:message', {key: 'close', hash: hash, value: true}); |
| 175 | 0 | deferred.resolve(); |
| 176 | 0 | return deferred.promise; |
| 177 | } | |
| 178 | }; | |
| 179 | ||
| 180 | /** | |
| 181 | * Mixes in element methods | |
| 182 | * | |
| 183 | * @param {Dalek.DriverNative} DalekNative Native driver base class | |
| 184 | * @return {Dalek.DriverNative} DalekNative Native driver base class | |
| 185 | */ | |
| 186 | ||
| 187 | 1 | module.exports = function (DalekNative) { |
| 188 | // mixin methods | |
| 189 | 0 | Object.keys(Window).forEach(function (fn) { |
| 190 | 0 | DalekNative.prototype[fn] = Window[fn]; |
| 191 | }); | |
| 192 | ||
| 193 | 0 | return DalekNative; |
| 194 | }; | |
| 195 |