Coverage

12%
83
10
73

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

8%
80
7
73
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 initialBrowserUrl: ''
146 },
147
148 /**
149 * Driver defaults, what should the driver be able to access.
150 *
151 * @property driverDefaults
152 * @type object
153 */
154
155 driverDefaults: {
156 viewport: true,
157 status: true,
158 sessionInfo: true
159 },
160
161 /**
162 * Path to the IEDriverServer.exe file
163 *
164 * @property path
165 * @type string
166 * @default /
167 */
168
169 path: '/',
170
171 /**
172 * Child process instance of the IEDriverServer
173 *
174 * @property spawned
175 * @type null|Object
176 */
177
178 spawned: null,
179
180 /**
181 * IE processes that are running on startup,
182 * and therefor shouldn`t be closed
183 *
184 * @property openProcesses
185 * @type array
186 * @default []
187 */
188
189 openProcesses: [],
190
191 /**
192 * Resolves the driver port
193 *
194 * @method getPort
195 * @return {integer} port WebDriver server port
196 */
197
198 getPort: function () {
1990 return this.port;
200 },
201
202 /**
203 * Returns the driver host
204 *
205 * @method getHost
206 * @return {string} host WebDriver server hostname
207 */
208
209 getHost: function () {
2100 return this.host;
211 },
212
213 /**
214 * Resolves the maximum range for the driver port
215 *
216 * @method getMaxPort
217 * @return {integer} port Max WebDriver server port range
218 */
219
220 getMaxPort: function () {
2210 return this.maxPort;
222 },
223
224 /**
225 * Launches the driver
226 * (the driver takes care of launching the browser)
227 *
228 * @method launch
229 * @return {object} promise Browser promise
230 */
231
232 launch: function (configuration, events, config) {
2330 var deferred = Q.defer();
234
235 // store injected configuration/log event handlers
2360 this.reporterEvents = events;
2370 this.configuration = configuration;
2380 this.config = config;
239
240 // check for a user set port
2410 var browsers = this.config.get('browsers');
2420 if (browsers && Array.isArray(browsers)) {
2430 browsers.forEach(this._checkUserDefinedPorts.bind(this));
244 }
245
246 // check if the current port is in use, if so, scan for free ports
2470 portscanner.findAPortNotInUse(this.getPort(), this.getMaxPort(), this.getHost(), this._checkPorts.bind(this, deferred));
2480 return deferred.promise;
249 },
250
251 /**
252 * Kills the driver & browser processes
253 *
254 * @method kill
255 * @chainable
256 */
257
258 kill: function () {
259 // get a list of all running processes
2600 this._list(function(svc){
261 // filter out the browser process
2620 svc.forEach(function (item, idx) {
2630 Object.keys(item).forEach(function (key) {
2640 if(svc[idx][key] === 'iexplore.exe') {
265 // kill the browser process
2660 this._kill(svc[idx].PID, true);
267 }
268 }.bind(this));
269 }.bind(this));
270 }.bind(this),true);
271
272 // kill the driver process
2730 this.spawned.kill('SIGTERM');
2740 return this;
275 },
276
277 _checkPorts: function (deferred, err, port) {
278 // check if the port was blocked & if we need to switch to another port
2790 if (this.port !== port) {
2800 this.reporterEvents.emit('report:log:system', 'dalek-browser-ie: Switching to port: ' + port);
2810 this.port = port;
282 }
283
284 // invoke the ie driver afterwards
2850 this._startIEdriver(deferred);
2860 return this;
287 },
288
289 _startIEdriver: function (deferred) {
2900 var stream = '';
2910 this.spawned = cp.spawn(iedriver.path, ['--port=' + this.getPort()]);
292
2930 this.spawned.stdout.on('data', function (data) {
2940 var dataStr = data + '';
2950 stream += dataStr;
2960 if (stream.search('Listening on port') !== -1) {
2970 deferred.resolve();
298 }
299 });
3000 return this;
301 },
302
303 /**
304 * Process user defined ports
305 *
306 * @method _checkUserDefinedPorts
307 * @param {object} browser Browser configuration
308 * @chainable
309 * @private
310 */
311
312 _checkUserDefinedPorts: function (browser) {
313 // check for a single defined port
3140 if (browser.ie && browser.ie.port) {
3150 this.port = parseInt(browser.ie.port, 10);
3160 this.maxPort = this.port + 90;
3170 this.reporterEvents.emit('report:log:system', 'dalek-browser-ie: Switching to user defined port: ' + this.port);
318 }
319
320 // check for a port range
3210 if (browser.ie && browser.ie.portRange && browser.ie.portRange.length === 2) {
3220 this.port = parseInt(browser.ie.portRange[0], 10);
3230 this.maxPort = parseInt(browser.ie.portRange[1], 10);
3240 this.reporterEvents.emit('report:log:system', 'dalek-browser-ie: Switching to user defined port(s): ' + this.port + ' -> ' + this.maxPort);
325 }
326
3270 return this;
328 },
329
330 /**
331 * Lists all running processes (win only)
332 *
333 * @method _list
334 * @param {Function} callback Receives the process object as the only callback argument
335 * @param {Boolean} [verbose=false] Verbose output
336 * @chainable
337 * @private
338 */
339
340 _list: function(callback, verbose) {
3410 verbose = typeof verbose === 'boolean' ? verbose : false;
3420 cp.exec('tasklist /FO CSV' + (verbose === true ? ' /V' : ''), function (err, stdout) {
3430 var pi = stdout.split('\r\n');
3440 var p = [];
345
3460 pi.forEach(function (line) {
3470 if (line.trim().length !== 0) {
3480 p.push(line);
349 }
350 });
351
3520 var proc = [];
3530 var head = null;
3540 while (p.length > 1) {
3550 var rec = p.shift();
3560 rec = rec.replace(/\"\,/gi,'";').replace(/\"|\'/gi,'').split(';');
3570 if (head === null){
3580 head = rec;
3590 for (var i=0;i<head.length;i++){
3600 head[i] = head[i].replace(/ /gi,'');
361 }
362
3630 if (head.indexOf('PID')<0){
3640 head[1] = 'PID';
365 }
366 } else {
3670 var tmp = {};
3680 for (var j=0;j<rec.length;j++){
3690 tmp[head[j]] = rec[j].replace(/\"|\'/gi,'');
370 }
3710 proc.push(tmp);
372 }
373 }
3740 callback(proc);
375 });
376
3770 return this;
378 },
379
380 /**
381 * Kill a specific process (win only)
382 *
383 * @method _kill
384 * @param {Number} PID Process ID
385 * @param {Boolean} [force=false] Force close the process.
386 * @param {Function} [callback] Callback after process has been killed
387 * @chainable
388 * @private
389 */
390
391 _kill: function(pid, force, callback) {
3920 if (!pid || isNaN(parseInt(pid))){
3930 throw new Error('PID is required for the kill operation.');
394 }
3950 callback = callback || function(){};
3960 if (typeof force === 'function'){
3970 callback = force;
3980 force = false;
399 }
4000 cp.exec('taskkill /PID ' + pid + (force === true ? ' /f' : ''),callback);
4010 return this;
402 }
403
404};
405
406// expose the module
4071module.exports = InternetExplorer;
408

/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