11'use strict' ;
22
33const Promise = require ( 'bluebird' ) ;
4+ const QEmitter = require ( 'qemitter' ) ;
5+ const bluebirdQ = require ( 'bluebird-q' ) ;
46const Browser = require ( 'lib/browser' ) ;
57const BasicPool = require ( 'lib/browser-pool/basic-pool' ) ;
68const CancelledError = require ( 'lib/errors/cancelled-error' ) ;
79const browserWithId = require ( 'test/util' ) . browserWithId ;
10+ const Events = require ( 'lib/constants/events' ) ;
11+ const _ = require ( 'lodash' ) ;
812
913describe ( 'BasicPool' , ( ) => {
1014 const sandbox = sinon . sandbox . create ( ) ;
1115
12- const stubBrowser = ( id ) => {
16+ const stubBrowser_ = ( id ) => {
1317 id = id || 'id' ;
1418 const browser = browserWithId ( id ) ;
1519 sandbox . stub ( browser , 'launch' , ( ) => {
@@ -26,66 +30,164 @@ describe('BasicPool', () => {
2630
2731 const stubConfig = ( ) => ( { forBrowser : ( id ) => ( { id} ) } ) ;
2832
29- let pool ;
30-
31- beforeEach ( ( ) => {
32- pool = new BasicPool ( stubConfig ( ) ) ;
33+ const mkPool_ = ( opts ) => {
34+ opts = _ . defaults ( opts || { } , {
35+ config : stubConfig ( ) ,
36+ calibrator : 'default-calibrator' ,
37+ emitter : new QEmitter ( )
38+ } ) ;
3339
34- sandbox . stub ( Browser , 'create' ) ;
35- } ) ;
36- afterEach ( ( ) => sandbox . restore ( ) ) ;
40+ return new BasicPool ( opts . config , opts . calibrator , opts . emitter ) ;
41+ } ;
3742
38- const requestBrowser = ( browser ) => {
39- browser = browser || stubBrowser ( ) ;
43+ const requestBrowser_ = ( browser , pool ) => {
44+ browser = browser || stubBrowser_ ( ) ;
45+ pool = pool || mkPool_ ( ) ;
4046
4147 return pool . getBrowser ( browser . id ) ;
4248 } ;
4349
50+ beforeEach ( ( ) => {
51+ sandbox . stub ( Browser , 'create' ) ;
52+ } ) ;
53+
54+ afterEach ( ( ) => sandbox . restore ( ) ) ;
55+
4456 it ( 'should create new browser when requested' , ( ) => {
45- const browser = stubBrowser ( 'foo' ) ;
57+ const browser = stubBrowser_ ( 'foo' ) ;
4658
47- return requestBrowser ( browser )
59+ return requestBrowser_ ( browser )
4860 . then ( ( ) => assert . calledWith ( Browser . create , { id : 'foo' } ) ) ;
4961 } ) ;
5062
5163 it ( 'should launch a browser' , ( ) => {
52- const browser = stubBrowser ( ) ;
64+ const browser = stubBrowser_ ( ) ;
5365
54- return requestBrowser ( browser )
66+ return requestBrowser_ ( browser )
5567 . then ( ( ) => assert . calledOnce ( browser . launch ) ) ;
5668 } ) ;
5769
5870 it ( 'should launch a browser with calibrator' , ( ) => {
59- pool = new BasicPool ( stubConfig ( ) , 'calibrator' ) ;
71+ const pool = mkPool_ ( { calibrator : 'calibrator' } ) ;
6072
61- const browser = stubBrowser ( ) ;
73+ const browser = stubBrowser_ ( ) ;
6274
63- return requestBrowser ( browser )
75+ return requestBrowser_ ( browser , pool )
6476 . then ( ( ) => assert . calledWith ( browser . launch , 'calibrator' ) ) ;
6577 } ) ;
6678
6779 it ( 'should finalize browser if failed to create it' , ( ) => {
68- const browser = stubBrowser ( ) ;
80+ const browser = stubBrowser_ ( ) ;
81+ const pool = mkPool_ ( ) ;
6982 const freeBrowser = sinon . spy ( pool , 'freeBrowser' ) ;
7083 const assertCalled = ( ) => assert . called ( freeBrowser ) ;
7184
72- browser . reset . returns ( Promise . reject ( ) ) ;
85+ browser . reset . returns ( bluebirdQ . reject ( ) ) ;
7386
74- return requestBrowser ( browser )
87+ return requestBrowser_ ( browser , pool )
7588 . then ( assertCalled , assertCalled ) ;
7689 } ) ;
7790
91+ describe ( 'START_BROWSER event' , ( ) => {
92+ it ( 'should be emitted on browser start' , ( ) => {
93+ const emitter = new QEmitter ( ) ;
94+ const onSessionStart = sinon . spy ( ) . named ( 'onSessionStart' ) ;
95+ emitter . on ( Events . START_BROWSER , onSessionStart ) ;
96+
97+ const pool = mkPool_ ( { emitter} ) ;
98+ const browser = stubBrowser_ ( ) ;
99+
100+ return requestBrowser_ ( browser , pool )
101+ . then ( ( ) => {
102+ assert . calledOnce ( onSessionStart ) ;
103+ assert . calledWith ( onSessionStart , browser ) ;
104+ } ) ;
105+ } ) ;
106+
107+ it ( 'handler should be waited by pool' , ( ) => {
108+ const emitter = new QEmitter ( ) ;
109+ const afterSessionStart = sinon . spy ( ) . named ( 'afterSessionStart' ) ;
110+ emitter . on ( Events . START_BROWSER , ( ) => bluebirdQ . delay ( 100 ) . then ( afterSessionStart ) ) ;
111+
112+ const pool = mkPool_ ( { emitter} ) ;
113+ const browser = stubBrowser_ ( ) ;
114+
115+ return requestBrowser_ ( browser , pool )
116+ . then ( ( ) => assert . callOrder ( afterSessionStart , browser . reset ) ) ;
117+ } ) ;
118+
119+ it ( 'handler fail should fail browser request' , ( ) => {
120+ const emitter = new QEmitter ( ) ;
121+ emitter . on ( Events . START_BROWSER , ( ) => bluebirdQ . reject ( 'some-error' ) ) ;
122+
123+ const pool = mkPool_ ( { emitter} ) ;
124+ const browser = stubBrowser_ ( ) ;
125+
126+ return assert . isRejected ( requestBrowser_ ( browser , pool ) , 'some-error' ) ;
127+ } ) ;
128+ } ) ;
129+
78130 it ( 'should quit a browser when freed' , ( ) => {
79- const browser = stubBrowser ( ) ;
131+ const pool = mkPool_ ( ) ;
132+ const browser = stubBrowser_ ( ) ;
80133
81- return requestBrowser ( browser )
134+ return requestBrowser_ ( browser , pool )
82135 . then ( ( browser ) => pool . freeBrowser ( browser ) )
83136 . then ( ( ) => assert . calledOnce ( browser . quit ) ) ;
84137 } ) ;
85138
139+ describe ( 'STOP_BROWSER event' , ( ) => {
140+ it ( 'should be emitted on browser quit' , ( ) => {
141+ const emitter = new QEmitter ( ) ;
142+ const onSessionEnd = sinon . spy ( ) . named ( 'onSessionEnd' ) ;
143+ emitter . on ( Events . STOP_BROWSER , onSessionEnd ) ;
144+
145+ const pool = mkPool_ ( { emitter} ) ;
146+ const browser = stubBrowser_ ( ) ;
147+
148+ return requestBrowser_ ( browser , pool )
149+ . then ( ( browser ) => pool . freeBrowser ( browser ) )
150+ . then ( ( ) => {
151+ assert . calledOnce ( onSessionEnd ) ;
152+ assert . calledWith ( onSessionEnd , browser ) ;
153+ } ) ;
154+ } ) ;
155+
156+ it ( 'handler should be waited before actual quit' , ( ) => {
157+ const emitter = new QEmitter ( ) ;
158+ const afterSessionEnd = sinon . spy ( ) . named ( 'afterSessionEnd' ) ;
159+ emitter . on ( Events . STOP_BROWSER , ( ) => bluebirdQ . delay ( 100 ) . then ( afterSessionEnd ) ) ;
160+
161+ const pool = mkPool_ ( { emitter} ) ;
162+ const browser = stubBrowser_ ( ) ;
163+
164+ return requestBrowser_ ( browser , pool )
165+ . then ( ( browser ) => pool . freeBrowser ( browser ) )
166+ . then ( ( ) => assert . callOrder ( afterSessionEnd , browser . quit ) ) ;
167+ } ) ;
168+
169+ it ( 'handler fail should not prevent browser from quit' , ( ) => {
170+ const emitter = new QEmitter ( ) ;
171+ emitter . on ( Events . STOP_BROWSER , ( ) => bluebirdQ . reject ( ) ) ;
172+
173+ const pool = mkPool_ ( { emitter} ) ;
174+ const browser = stubBrowser_ ( ) ;
175+
176+ return requestBrowser_ ( browser , pool )
177+ . then ( ( browser ) => pool . freeBrowser ( browser ) )
178+ . then ( ( ) => assert . calledOnce ( browser . quit ) ) ;
179+ } ) ;
180+ } ) ;
181+
86182 describe ( 'cancel' , ( ) => {
87183 it ( 'should quit all browsers on cancel' , ( ) => {
88- return Promise . all ( [ requestBrowser ( stubBrowser ( 'id1' ) ) , requestBrowser ( stubBrowser ( 'id2' ) ) ] )
184+ const pool = mkPool_ ( ) ;
185+
186+ return Promise
187+ . all ( [
188+ requestBrowser_ ( stubBrowser_ ( 'id1' ) , pool ) ,
189+ requestBrowser_ ( stubBrowser_ ( 'id2' ) , pool )
190+ ] )
89191 . spread ( ( firstBrowser , secondBrowser ) => {
90192 pool . cancel ( ) ;
91193
@@ -95,7 +197,13 @@ describe('BasicPool', () => {
95197 } ) ;
96198
97199 it ( 'should quit all browser with the same id on cancel' , ( ) => {
98- return Promise . all ( [ requestBrowser ( stubBrowser ( 'id' ) ) , requestBrowser ( stubBrowser ( 'id' ) ) ] )
200+ const pool = mkPool_ ( ) ;
201+
202+ return Promise
203+ . all ( [
204+ requestBrowser_ ( stubBrowser_ ( 'id' ) , pool ) ,
205+ requestBrowser_ ( stubBrowser_ ( 'id' ) , pool )
206+ ] )
99207 . spread ( ( firstBrowser , secondBrowser ) => {
100208 pool . cancel ( ) ;
101209
@@ -105,24 +213,28 @@ describe('BasicPool', () => {
105213 } ) ;
106214
107215 it ( 'should be rejected if getting of a browser was called after cancel' , ( ) => {
216+ const pool = mkPool_ ( ) ;
217+
108218 pool . cancel ( ) ;
109219
110- return assert . isRejected ( requestBrowser ( stubBrowser ( ) ) , CancelledError ) ;
220+ return assert . isRejected ( requestBrowser_ ( stubBrowser_ ( ) , pool ) , CancelledError ) ;
111221 } ) ;
112222
113223 it ( 'should quit a browser once if it was launched after cancel' , ( ) => {
114- const browser = stubBrowser ( ) ;
224+ const pool = mkPool_ ( ) ;
225+ const browser = stubBrowser_ ( ) ;
115226
116227 pool . cancel ( ) ;
117228
118- return requestBrowser ( browser )
229+ return requestBrowser_ ( browser , pool )
119230 . catch ( ( ) => assert . calledOnce ( browser . quit ) ) ;
120231 } ) ;
121232
122233 it ( 'should clean active sessions after cancel' , ( ) => {
123- const browser = stubBrowser ( ) ;
234+ const pool = mkPool_ ( ) ;
235+ const browser = stubBrowser_ ( ) ;
124236
125- return requestBrowser ( browser )
237+ return requestBrowser_ ( browser , pool )
126238 . then ( ( ) => pool . cancel ( ) )
127239 . then ( ( ) => pool . cancel ( ) )
128240 . then ( ( ) => assert . calledOnce ( browser . quit ) ) ;
0 commit comments