1
1
'use strict' ;
2
2
3
3
const Promise = require ( 'bluebird' ) ;
4
+ const QEmitter = require ( 'qemitter' ) ;
5
+ const bluebirdQ = require ( 'bluebird-q' ) ;
4
6
const Browser = require ( 'lib/browser' ) ;
5
7
const BasicPool = require ( 'lib/browser-pool/basic-pool' ) ;
6
8
const CancelledError = require ( 'lib/errors/cancelled-error' ) ;
7
9
const browserWithId = require ( 'test/util' ) . browserWithId ;
10
+ const Events = require ( 'lib/constants/events' ) ;
11
+ const _ = require ( 'lodash' ) ;
8
12
9
13
describe ( 'BasicPool' , ( ) => {
10
14
const sandbox = sinon . sandbox . create ( ) ;
11
15
12
- const stubBrowser = ( id ) => {
16
+ const stubBrowser_ = ( id ) => {
13
17
id = id || 'id' ;
14
18
const browser = browserWithId ( id ) ;
15
19
sandbox . stub ( browser , 'launch' , ( ) => {
@@ -26,66 +30,164 @@ describe('BasicPool', () => {
26
30
27
31
const stubConfig = ( ) => ( { forBrowser : ( id ) => ( { id} ) } ) ;
28
32
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
+ } ) ;
33
39
34
- sandbox . stub ( Browser , 'create' ) ;
35
- } ) ;
36
- afterEach ( ( ) => sandbox . restore ( ) ) ;
40
+ return new BasicPool ( opts . config , opts . calibrator , opts . emitter ) ;
41
+ } ;
37
42
38
- const requestBrowser = ( browser ) => {
39
- browser = browser || stubBrowser ( ) ;
43
+ const requestBrowser_ = ( browser , pool ) => {
44
+ browser = browser || stubBrowser_ ( ) ;
45
+ pool = pool || mkPool_ ( ) ;
40
46
41
47
return pool . getBrowser ( browser . id ) ;
42
48
} ;
43
49
50
+ beforeEach ( ( ) => {
51
+ sandbox . stub ( Browser , 'create' ) ;
52
+ } ) ;
53
+
54
+ afterEach ( ( ) => sandbox . restore ( ) ) ;
55
+
44
56
it ( 'should create new browser when requested' , ( ) => {
45
- const browser = stubBrowser ( 'foo' ) ;
57
+ const browser = stubBrowser_ ( 'foo' ) ;
46
58
47
- return requestBrowser ( browser )
59
+ return requestBrowser_ ( browser )
48
60
. then ( ( ) => assert . calledWith ( Browser . create , { id : 'foo' } ) ) ;
49
61
} ) ;
50
62
51
63
it ( 'should launch a browser' , ( ) => {
52
- const browser = stubBrowser ( ) ;
64
+ const browser = stubBrowser_ ( ) ;
53
65
54
- return requestBrowser ( browser )
66
+ return requestBrowser_ ( browser )
55
67
. then ( ( ) => assert . calledOnce ( browser . launch ) ) ;
56
68
} ) ;
57
69
58
70
it ( 'should launch a browser with calibrator' , ( ) => {
59
- pool = new BasicPool ( stubConfig ( ) , 'calibrator' ) ;
71
+ const pool = mkPool_ ( { calibrator : 'calibrator' } ) ;
60
72
61
- const browser = stubBrowser ( ) ;
73
+ const browser = stubBrowser_ ( ) ;
62
74
63
- return requestBrowser ( browser )
75
+ return requestBrowser_ ( browser , pool )
64
76
. then ( ( ) => assert . calledWith ( browser . launch , 'calibrator' ) ) ;
65
77
} ) ;
66
78
67
79
it ( 'should finalize browser if failed to create it' , ( ) => {
68
- const browser = stubBrowser ( ) ;
80
+ const browser = stubBrowser_ ( ) ;
81
+ const pool = mkPool_ ( ) ;
69
82
const freeBrowser = sinon . spy ( pool , 'freeBrowser' ) ;
70
83
const assertCalled = ( ) => assert . called ( freeBrowser ) ;
71
84
72
- browser . reset . returns ( Promise . reject ( ) ) ;
85
+ browser . reset . returns ( bluebirdQ . reject ( ) ) ;
73
86
74
- return requestBrowser ( browser )
87
+ return requestBrowser_ ( browser , pool )
75
88
. then ( assertCalled , assertCalled ) ;
76
89
} ) ;
77
90
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
+
78
130
it ( 'should quit a browser when freed' , ( ) => {
79
- const browser = stubBrowser ( ) ;
131
+ const pool = mkPool_ ( ) ;
132
+ const browser = stubBrowser_ ( ) ;
80
133
81
- return requestBrowser ( browser )
134
+ return requestBrowser_ ( browser , pool )
82
135
. then ( ( browser ) => pool . freeBrowser ( browser ) )
83
136
. then ( ( ) => assert . calledOnce ( browser . quit ) ) ;
84
137
} ) ;
85
138
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
+
86
182
describe ( 'cancel' , ( ) => {
87
183
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
+ ] )
89
191
. spread ( ( firstBrowser , secondBrowser ) => {
90
192
pool . cancel ( ) ;
91
193
@@ -95,7 +197,13 @@ describe('BasicPool', () => {
95
197
} ) ;
96
198
97
199
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
+ ] )
99
207
. spread ( ( firstBrowser , secondBrowser ) => {
100
208
pool . cancel ( ) ;
101
209
@@ -105,24 +213,28 @@ describe('BasicPool', () => {
105
213
} ) ;
106
214
107
215
it ( 'should be rejected if getting of a browser was called after cancel' , ( ) => {
216
+ const pool = mkPool_ ( ) ;
217
+
108
218
pool . cancel ( ) ;
109
219
110
- return assert . isRejected ( requestBrowser ( stubBrowser ( ) ) , CancelledError ) ;
220
+ return assert . isRejected ( requestBrowser_ ( stubBrowser_ ( ) , pool ) , CancelledError ) ;
111
221
} ) ;
112
222
113
223
it ( 'should quit a browser once if it was launched after cancel' , ( ) => {
114
- const browser = stubBrowser ( ) ;
224
+ const pool = mkPool_ ( ) ;
225
+ const browser = stubBrowser_ ( ) ;
115
226
116
227
pool . cancel ( ) ;
117
228
118
- return requestBrowser ( browser )
229
+ return requestBrowser_ ( browser , pool )
119
230
. catch ( ( ) => assert . calledOnce ( browser . quit ) ) ;
120
231
} ) ;
121
232
122
233
it ( 'should clean active sessions after cancel' , ( ) => {
123
- const browser = stubBrowser ( ) ;
234
+ const pool = mkPool_ ( ) ;
235
+ const browser = stubBrowser_ ( ) ;
124
236
125
- return requestBrowser ( browser )
237
+ return requestBrowser_ ( browser , pool )
126
238
. then ( ( ) => pool . cancel ( ) )
127
239
. then ( ( ) => pool . cancel ( ) )
128
240
. then ( ( ) => assert . calledOnce ( browser . quit ) ) ;
0 commit comments