Coverage

12%
81
10
71

/home/ubuntu/src/github.com/dalekjs/dalek-browser-ie/index.js

8%
78
7
71
LineHitsSource
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
251'use strict';
26
27// ext. libs
281var Q = require('q');
291var cp = require('child_process');
301var portscanner = require('portscanner');
31
32// int. libs
331var iedriver = require('./lib/iedriver');
34
35/**
36 * This module is a browser plugin for [DalekJS](//github.com/dalekjs/dalek).
37 * It provides all a WebDriverServer & browser launcher for Internet Explorer.
38 *
39 * The browser plugin can be installed with the following command:
40 *
41 * ```bash
42 * $ npm install dalek-browser-ie --save-dev
43 * ```
44 *
45 * You can use the browser plugin by adding a config option to the your Dalekfile
46 *
47 * ```javascript
48 * "browsers": ["IE"]
49 * ```
50 *
51 * Or you can tell Dalek that it should test in this browser via the command line:
52 *
53 * ```bash
54 * $ dalek mytest.js -b IE
55 * ```
56 *
57 * The Webdriver Server tries to open Port 5555 by default,
58 * if this port is blocked, it tries to use a port between 5555 & 5564
59 * You can specifiy a different port from within your [Dalekfile](/pages/config.html) like so:
60 *
61 * ```javascript
62 * "browsers": {
63 * "ie": {
64 * "port": 6555
65 * }
66 * }
67 * ```
68 *
69 * It is also possible to specify a range of ports:
70 *
71 * ```javascript
72 * "browsers": {
73 * "ie": {
74 * "portRange": [6100, 6120]
75 * }
76 * }
77 * ```
78 *
79 * @module DalekJS
80 * @class InternetExplorer
81 * @namespace Browser
82 * @part InternetExplorer
83 * @api
84 */
85
861var InternetExplorer = {
87
88 /**
89 * Verbose version of the browser name
90 *
91 * @property longName
92 * @type string
93 * @default Internet Explorer
94 * @api
95 */
96
97 longName: 'Internet Explorer',
98
99 /**
100 * Default port of the IEDriverServer
101 * The port may change, cause the port conflict resultion
102 * tool might pick another one, if the default one is blocked
103 *
104 * @property port
105 * @type integer
106 * @default 5555
107 */
108
109 port: 5555,
110
111 /**
112 * Default maximum port of the IEDriverServer
113 * The port is the highest port in the range that can be allocated
114 * by the IEDriverServer
115 *
116 * @property maxPort
117 * @type integer
118 * @default 5654
119 */
120
121 maxPort: 5654,
122
123 /**
124 * Default host of the IEDriverServer
125 * The host may be overridden with
126 * a user configured value
127 *
128 * @property host
129 * @type string
130 * @default localhost
131 */
132
133 host: 'localhost',
134
135 /**
136 * Default desired capabilities that should be
137 * transferred when the browser session gets requested
138 *
139 * @property desiredCapabilities
140 * @type object
141 */
142
143 desiredCapabilities: {
144 browserName: 'InternetExplorer'
145 },
146
147 /**
148 * Driver defaults, what should the driver be able to access.
149 *
150 * @property driverDefaults
151 * @type object
152 */
153
154 driverDefaults: {
155 viewport: true,
156 status: true,
157 sessionInfo: true
158 },
159
160 /**
161 * Path to the IEDriverServer.exe file
162 *
163 * @property path
164 * @type string
165 * @default /
166 */
167
168 path: '/',
169
170 /**
171 * Child process instance of the IEDriverServer
172 *
173 * @property spawned
174 * @type null|Object
175 */
176
177 spawned: null,
178
179 /**
180 * IE processes that are running on startup,
181 * and therefor shouldn`t be closed
182 *
183 * @property openProcesses
184 * @type array
185 * @default []
186 */
187
188 openProcesses: [],
189
190 /**
191 * Resolves the driver port
192 *
193 * @method getPort
194 * @return {integer} port WebDriver server port
195 */
196
197 getPort: function () {
1980 return this.port;
199 },
200
201 /**
202 * Returns the driver host
203 *
204 * @method getHost
205 * @return {string} host WebDriver server hostname
206 */
207
208 getHost: function () {
2090 return this.host;
210 },
211
212 /**
213 * Resolves the maximum range for the driver port
214 *
215 * @method getMaxPort
216 * @return {integer} port Max WebDriver server port range
217 */
218
219 getMaxPort: function () {
2200 return this.maxPort;
221 },
222
223 /**
224 * Launches the driver
225 * (the driver takes care of launching the browser)
226 *
227 * @method launch
228 * @return {object} promise Browser promise
229 */
230
231 launch: function (configuration, events, config) {
2320 var deferred = Q.defer();
233
234 // store injected configuration/log event handlers
2350 this.reporterEvents = events;
2360 this.configuration = configuration;
2370 this.config = config;
238
239 // check for a user set port
2400 var browsers = this.config.get('browsers');
2410 if (browsers && Array.isArray(browsers)) {
2420 browsers.forEach(this._checkUserDefinedPorts.bind(this));
243 }
244
245 // check if the current port is in use, if so, scan for free ports
2460 portscanner.findAPortNotInUse(this.getPort(), this.getMaxPort(), this.getHost(), this._checkPorts.bind(this, deferred));
2470 return deferred.promise;
248 },
249
250 /**
251 * Kills the driver & browser processes
252 *
253 * @method kill
254 * @chainable
255 */
256
257 kill: function () {
258 // get a list of all running processes
2590 this._list(function(svc){
260 // filter out the browser process
2610 svc.forEach(function (item, idx) {
2620 Object.keys(item).forEach(function (key) {
2630 if(svc[idx][key] === 'iexplore.exe') {
264 // kill the browser process
2650 this._kill(svc[idx].PID);
266 }
267 }.bind(this));
268 }.bind(this));
269 }.bind(this),true);
270
271 // kill the driver process
2720 this.spawned.kill('SIGTERM');
2730 return this;
274 },
275
276 _checkPorts: function (deferred, err, port) {
277 // check if the port was blocked & if we need to switch to another port
2780 if (this.port !== port) {
2790 this.reporterEvents.emit('report:log:system', 'dalek-browser-ie: Switching to port: ' + port);
2800 this.port = port;
281 }
282
283 // invoke the ie driver afterwards
2840 this._startIEdriver(deferred);
2850 return this;
286 },
287
288 _startIEdriver: function (deferred) {
2890 var stream = '';
2900 this.spawned = cp.spawn(iedriver.path, ['--port=' + this.getPort()]);
291
2920 this.spawned.stdout.on('data', function (data) {
2930 var dataStr = data + '';
2940 stream += dataStr;
2950 if (stream.search('Listening on port') !== -1) {
2960 deferred.resolve();
297 }
298 });
2990 return this;
300 },
301
302 /**
303 * Process user defined ports
304 *
305 * @method _checkUserDefinedPorts
306 * @param {object} browser Browser configuration
307 * @chainable
308 * @private
309 */
310
311 _checkUserDefinedPorts: function (browser) {
312 // check for a single defined port
3130 if (browser.ie && browser.ie.port) {
3140 this.port = parseInt(browser.ie.port, 10);
3150 this.maxPort = this.port + 90;
3160 this.reporterEvents.emit('report:log:system', 'dalek-browser-ie: Switching to user defined port: ' + this.port);
317 }
318
319 // check for a port range
3200 if (browser.ie && browser.ie.portRange && browser.ie.portRange.length === 2) {
3210 this.port = parseInt(browser.ie.portRange[0], 10);
3220 this.maxPort = parseInt(browser.ie.portRange[1], 10);
3230 this.reporterEvents.emit('report:log:system', 'dalek-browser-ie: Switching to user defined port(s): ' + this.port + ' -> ' + this.maxPort);
324 }
325
3260 return this;
327 },
328
329 /**
330 * Lists all running processes (win only)
331 *
332 * @method _list
333 * @param {Function} callback Receives the process object as the only callback argument
334 * @param {Boolean} [verbose=false] Verbose output
335 * @chainable
336 * @private
337 */
338
339 _list: function(callback, verbose) {
3400 verbose = typeof verbose === 'boolean' ? verbose : false;
3410 cp.exec('tasklist /FO CSV' + (verbose === true ? ' /V' : ''), function (err, stdout) {
3420 var pi = stdout.split('\r\n');
3430 var p = [];
344
3450 pi.forEach(function (line) {
3460 if (line.trim().length !== 0) {
3470 p.push(line);
348 }
349 });
350
3510 var proc = [];
3520 var head = null;
3530 while (p.length > 1) {
3540 var rec = p.shift();
3550 rec = rec.replace(/\"\,/gi,'";').replace(/\"|\'/gi,'').split(';');
3560 if (head === null){
3570 head = rec;
3580 for (var i=0;i<head.length;i++){
3590 head[i] = head[i].replace(/ /gi,'');
360 }
361 } else {
3620 var tmp = {};
3630 for (var j=0;j<rec.length;j++){
3640 tmp[head[j]] = rec[j].replace(/\"|\'/gi,'');
365 }
3660 proc.push(tmp);
367 }
368 }
3690 callback(proc);
370 });
371
3720 return this;
373 },
374
375 /**
376 * Kill a specific process (win only)
377 *
378 * @method _kill
379 * @param {Number} PID Process ID
380 * @param {Boolean} [force=false] Force close the process.
381 * @param {Function} [callback] Callback after process has been killed
382 * @chainable
383 * @private
384 */
385
386 _kill: function(pid, force, callback) {
3870 if (!pid){
3880 throw new Error('PID is required for the kill operation.');
389 }
3900 callback = callback || function(){};
3910 if (typeof force === 'function'){
3920 callback = force;
3930 force = false;
394 }
3950 cp.exec('taskkill /PID ' + pid + (force === true ? ' /f' : ''),callback);
3960 return this;
397 }
398
399};
400
401// expose the module
4021module.exports = InternetExplorer;
403

/home/ubuntu/src/github.com/dalekjs/dalek-browser-ie/lib/iedriver.js

100%
3
3
0
LineHitsSource
1// Copyright 2013 The Obvious Corporation.
2
3/**
4 * @fileoverview Helpers made available via require('dalek-browser-ie') once package is
5 * installed.
6 */
7
81var path = require('path');
9
10
11/**
12 * Where the iedriverserver binary can be found.
13 * @type {string}
14 */
151exports.path = path.join(__dirname, 'bin', 'IEDriverServer.exe');
16
17
18/**
19 * The version of iedriverserver installed by this package.
20 * @type {number}
21 */
221exports.version = '23.0.0';
23