22
33var BrowserStack = require ( 'browserstack' ) ,
44 fs = require ( 'fs' ) ,
5+ chalk = require ( 'chalk' ) ,
56 utils = require ( '../lib/utils' ) ,
67 Server = require ( '../lib/server' ) . Server ,
78 config = require ( '../lib/config' ) ,
89 Tunnel = require ( '../lib/local' ) . Tunnel ,
910 ConfigParser = require ( '../lib/configParser' ) . ConfigParser ,
1011 serverPort = 8888 ,
12+ timeout = null ,
13+ activityTimeout = null ,
1114 tunnel ;
1215
1316var client = BrowserStack . createClient ( {
@@ -19,7 +22,8 @@ var pid_file = process.cwd() + '/browserstack-run.pid';
1922fs . writeFileSync ( pid_file , process . pid , 'utf-8' )
2023
2124var workers = { } ;
22- var cleanUp = function cleanUp ( ) {
25+ var workerKeys = { } ;
26+ var cleanUp = function ( signal ) {
2327 try {
2428 server . close ( ) ;
2529 } catch ( e ) {
@@ -29,33 +33,39 @@ var cleanUp = function cleanUp () {
2933 console . log ( "Exiting" ) ;
3034
3135 for ( var key in workers ) {
36+ var worker = workers [ key ] ;
3237 if ( workers . hasOwnProperty ( key ) ) {
33- client . terminateWorker ( workers [ key ] . id , function ( ) {
38+ client . terminateWorker ( worker . id , function ( ) {
3439 if ( ! workers [ key ] ) {
3540 return ;
3641 }
3742
38- console . log ( '[%s] Terminated' , workers [ key ] . string ) ;
39- clearTimeout ( workers [ key ] . activityTimeout ) ;
40- delete workers [ key ]
43+ console . log ( '[%s] Terminated' , worker . string ) ;
44+ clearTimeout ( worker . activityTimeout ) ;
45+ delete workers [ key ] ;
46+ delete workerKeys [ worker . id ] ;
4147 } ) ;
4248 }
4349 }
50+ if ( statusPoller ) statusPoller . stop ( ) ;
4451
4552 try {
4653 process . kill ( tunnel . process . pid , 'SIGKILL' ) ;
4754 } catch ( e ) {
4855 console . log ( "Non existent tunnel" ) ;
4956 }
5057 try {
51- fs . unlink ( pid_file ) ;
58+ fs . unlinkSync ( pid_file ) ;
5259 } catch ( e ) {
5360 console . log ( "Non existent pid file." ) ;
5461 }
62+ if ( signal ) {
63+ process . kill ( process . pid , 'SIGTERM' ) ;
64+ }
5565} ;
5666
57- process . on ( 'exit' , cleanUp ) ;
58- process . on ( 'SIGINT' , cleanUp ) ;
67+ process . on ( 'exit' , function ( ) { cleanUp ( false ) } ) ;
68+ process . on ( 'SIGINT' , function ( ) { cleanUp ( true ) } ) ;
5969
6070console . log ( "Launching server on port:" , serverPort ) ;
6171
@@ -88,13 +98,13 @@ function launchBrowser(browser, url) {
8898 browser [ "tunnel_identifier" ] = config . tunnelIdentifier ;
8999 }
90100
91- var timeout = parseInt ( config . timeout ) ;
101+ timeout = parseInt ( config . timeout ) ;
92102 if ( ! isNaN ( timeout ) ) {
93103 browser . timeout = timeout ;
94104 } else {
95105 timeout = 300 ;
96106 }
97- var activityTimeout = timeout - 10 ;
107+ activityTimeout = timeout - 10 ;
98108
99109 client . createWorker ( browser , function ( err , worker ) {
100110 if ( err || typeof worker !== 'object' ) {
@@ -110,47 +120,9 @@ function launchBrowser(browser, url) {
110120 worker . config = browser ;
111121 worker . string = browserString ;
112122 workers [ key ] = worker ;
113-
114- var statusPoller = setInterval ( function ( ) {
115- client . getWorker ( worker . id , function ( err , _worker ) {
116- if ( worker . launched ) {
117- return ;
118- }
119-
120- if ( _worker . status === 'running' ) {
121- clearInterval ( statusPoller ) ;
122- console . log ( '[%s] Launched' , worker . string ) ;
123- worker . launched = true ;
124-
125- worker . activityTimeout = setTimeout ( function ( ) {
126- if ( ! worker . acknowledged ) {
127- var subject = "Worker inactive for too long: " + worker . string ;
128- var content = "Worker details:\n" + JSON . stringify ( worker . config , null , 4 ) ;
129- client . takeScreenshot ( worker . id , function ( error , screenshot ) {
130- if ( ! error && screenshot . url ) {
131- console . log ( '[%s] Screenshot: %s' , worker . string , screenshot . url ) ;
132- }
133- utils . alertBrowserStack ( subject , content ) ;
134- } ) ;
135- }
136- } , activityTimeout * 1000 ) ;
137-
138- setTimeout ( function ( ) {
139- if ( workers [ key ] ) {
140- var subject = "Tests timed out on: " + worker . string ;
141- var content = "Worker details:\n" + JSON . stringify ( worker . config , null , 4 ) ;
142- client . takeScreenshot ( worker . id , function ( error , screenshot ) {
143- if ( ! error && screenshot . url ) {
144- console . log ( '[%s] Screenshot: %s' , worker . string , screenshot . url ) ;
145- }
146- utils . alertBrowserStack ( subject , content ) ;
147- } ) ;
148- }
149- } , ( activityTimeout * 1000 ) ) ;
150- }
151- } ) ;
152- } , 2000 ) ;
123+ workerKeys [ worker . id ] = { key : key , marked : false } ;
153124 } ) ;
125+
154126}
155127
156128var launchBrowsers = function ( config , browser ) {
@@ -167,6 +139,81 @@ var launchBrowsers = function(config, browser) {
167139 } , 100 ) ;
168140}
169141
142+ var statusPoller = {
143+ poller : null ,
144+
145+ start : function ( ) {
146+ statusPoller . poller = setInterval ( function ( ) {
147+ client . getWorkers ( function ( err , _workers ) {
148+ _workers = _workers . filter ( function ( currentValue , index , array ) {
149+ return currentValue . status == 'running' && workerKeys [ currentValue . id ] && ! workerKeys [ currentValue . id ] . marked ;
150+ } ) ;
151+ for ( var i in _workers ) {
152+ var _worker = _workers [ i ] ;
153+ var workerData = workerKeys [ _worker . id ] ;
154+ var worker = workers [ workerData . key ] ;
155+ if ( worker . launched ) {
156+ return ;
157+ }
158+
159+ if ( _worker . status === 'running' ) {
160+ //clearInterval(statusPoller);
161+ console . log ( '[%s] Launched' , worker . string ) ;
162+ worker . launched = true ;
163+ workerData . marked = true ;
164+
165+ worker . activityTimeout = setTimeout ( function ( ) {
166+ if ( ! worker . acknowledged ) {
167+ var subject = "Worker inactive for too long: " + worker . string ;
168+ var content = "Worker details:\n" + JSON . stringify ( worker . config , null , 4 ) ;
169+ utils . alertBrowserStack ( subject , content , null , function ( ) { } ) ;
170+ delete workers [ workerData . key ] ;
171+ delete workerKeys [ worker . id ] ;
172+ config . status += 1 ;
173+ if ( utils . objectSize ( workers ) === 0 ) {
174+ var color = config . status > 0 ? "red" : "green" ;
175+ console . log ( chalk [ color ] ( "All tests done, failures: %d." ) , config . status ) ;
176+
177+ if ( config . status > 0 ) {
178+ config . status = 1 ;
179+ }
180+
181+ process . exit ( config . status ) ;
182+ }
183+ }
184+ } , activityTimeout * 1000 ) ;
185+
186+ setTimeout ( function ( ) {
187+ if ( worker . acknowledged ) {
188+ var subject = "Tests timed out on: " + worker . string ;
189+ var content = "Worker details:\n" + JSON . stringify ( worker . config , null , 4 ) ;
190+ utils . alertBrowserStack ( subject , content , null , function ( ) { } ) ;
191+ delete workers [ workerData . key ] ;
192+ delete workerKeys [ worker . id ] ;
193+ config . status += 1 ;
194+ if ( utils . objectSize ( workers ) === 0 ) {
195+ var color = config . status > 0 ? "red" : "green" ;
196+ console . log ( chalk [ color ] ( "All tests done, failures: %d." ) , config . status ) ;
197+
198+ if ( config . status > 0 ) {
199+ config . status = 1 ;
200+ }
201+
202+ process . exit ( config . status ) ;
203+ }
204+ }
205+ } , ( activityTimeout * 1000 ) ) ;
206+ }
207+ }
208+ } ) ;
209+ } , 2000 ) ;
210+ } ,
211+
212+ stop : function ( ) {
213+ clearInterval ( statusPoller . poller ) ;
214+ }
215+ } ;
216+
170217if ( config . browsers && config . browsers . length > 0 ) {
171218 ConfigParser . parse ( client , config . browsers , function ( browsers ) {
172219 tunnel = new Tunnel ( config . key , serverPort , config . tunnelIdentifier , function ( ) {
@@ -187,5 +234,6 @@ if (config.browsers && config.browsers.length > 0) {
187234 }
188235 } ) ;
189236 } ) ;
237+ statusPoller . start ( ) ;
190238 } ) ;
191239}
0 commit comments