@@ -32,11 +32,17 @@ class TestExecutionService implements ITestExecutionService {
32
32
private $options : IOptions ,
33
33
private $pluginsService : IPluginsService ,
34
34
private $errors : IErrors ,
35
- private $devicesService : Mobile . IDevicesService ) {
35
+ private $androidDebugService :IDebugService ,
36
+ private $iOSDebugService : IDebugService ,
37
+ private $devicesService : Mobile . IDevicesService ,
38
+ private $childProcess : IChildProcess ) {
36
39
}
37
40
41
+ public platform : string ;
42
+
38
43
public startTestRunner ( platform : string ) : IFuture < void > {
39
44
return ( ( ) => {
45
+ this . platform = platform ;
40
46
this . $options . justlaunch = true ;
41
47
let blockingOperationFuture = new Future < void > ( ) ;
42
48
process . on ( 'message' , ( launcherConfig : any ) => {
@@ -50,7 +56,7 @@ class TestExecutionService implements ITestExecutionService {
50
56
let configOptions : IKarmaConfigOptions = JSON . parse ( launcherConfig ) ;
51
57
this . $options . debugBrk = configOptions . debugBrk ;
52
58
this . $options . debugTransport = configOptions . debugTransport ;
53
- let configJs = this . generateConfig ( configOptions ) ;
59
+ let configJs = this . generateConfig ( this . $options . port . toString ( ) , configOptions ) ;
54
60
this . $fs . writeFile ( path . join ( projectDir , TestExecutionService . CONFIG_FILE_NAME ) , configJs ) . wait ( ) ;
55
61
56
62
let socketIoJsUrl = `http://localhost:${ this . $options . port } /socket.io/socket.io.js` ;
@@ -93,37 +99,47 @@ class TestExecutionService implements ITestExecutionService {
93
99
public startKarmaServer ( platform : string ) : IFuture < void > {
94
100
return ( ( ) => {
95
101
platform = platform . toLowerCase ( ) ;
96
- this . $pluginsService . ensureAllDependenciesAreInstalled ( ) . wait ( ) ;
97
- let pathToKarma = path . join ( this . $projectData . projectDir , 'node_modules/karma' ) ;
98
- let KarmaServer = require ( path . join ( pathToKarma , 'lib/server' ) ) ;
99
- if ( platform === 'ios' && this . $options . emulator ) {
100
- platform = 'ios_simulator' ;
101
- }
102
- let karmaConfig : any = {
103
- browsers : [ platform ] ,
104
- configFile : path . join ( this . $projectData . projectDir , 'karma.conf.js' ) ,
105
- _NS : {
106
- log : this . $logger . getLevel ( ) ,
107
- path : this . $options . path ,
108
- tns : process . argv [ 1 ] ,
109
- node : process . execPath ,
110
- options : {
111
- debugTransport : this . $options . debugTransport ,
112
- debugBrk : this . $options . debugBrk ,
113
- }
114
- } ,
115
- } ;
116
- if ( this . $config . DEBUG || this . $logger . getLevel ( ) === 'TRACE' ) {
117
- karmaConfig . logLevel = 'DEBUG' ;
118
- }
119
- if ( ! this . $options . watch ) {
120
- karmaConfig . singleRun = true ;
102
+ this . platform = platform ;
103
+
104
+ if ( this . $options . debugBrk && this . $options . watch ) {
105
+ this . $errors . failWithoutHelp ( "You cannot use --watch and --debug-brk simultaneously. Remove one of the flags and try again." ) ;
121
106
}
122
- if ( this . $options . debugBrk ) {
123
- karmaConfig . browserNoActivityTimeout = 1000000000 ;
107
+
108
+ if ( ! this . $platformService . preparePlatform ( platform ) . wait ( ) ) {
109
+ this . $errors . failWithoutHelp ( "Verify that listed files are well-formed and try again the operation." ) ;
124
110
}
125
- this . $logger . debug ( JSON . stringify ( karmaConfig , null , 4 ) ) ;
126
- new KarmaServer ( karmaConfig ) . start ( ) ;
111
+
112
+ let projectDir = this . $projectData . projectDir ;
113
+ this . $devicesService . initialize ( { platform : platform , deviceId : this . $options . device } ) . wait ( ) ;
114
+
115
+ let karmaConfig = this . getKarmaConfiguration ( platform ) ,
116
+ karmaRunner = this . $childProcess . fork ( path . join ( __dirname , "karma-execution.js" ) ) ;
117
+
118
+ karmaRunner . send ( { karmaConfig : karmaConfig } ) ;
119
+ karmaRunner . on ( "message" , ( karmaData : any ) => {
120
+ fiberBootstrap . run ( ( ) => {
121
+ this . $logger . trace ( "## Unit-testing: Parent process received message" , karmaData ) ;
122
+ let port : string ;
123
+ if ( karmaData . url ) {
124
+ port = karmaData . url . port ;
125
+ let socketIoJsUrl = `http://${ karmaData . url . host } /socket.io/socket.io.js` ;
126
+ let socketIoJs = this . $httpClient . httpRequest ( socketIoJsUrl ) . wait ( ) . body ;
127
+ this . $fs . writeFile ( path . join ( projectDir , TestExecutionService . SOCKETIO_JS_FILE_NAME ) , socketIoJs ) . wait ( ) ;
128
+ }
129
+
130
+ if ( karmaData . launcherConfig ) {
131
+ let configOptions : IKarmaConfigOptions = JSON . parse ( karmaData . launcherConfig ) ;
132
+ let configJs = this . generateConfig ( port , configOptions ) ;
133
+ this . $fs . writeFile ( path . join ( projectDir , TestExecutionService . CONFIG_FILE_NAME ) , configJs ) . wait ( ) ;
134
+ }
135
+
136
+ if ( this . $options . debugBrk ) {
137
+ this . getDebugService ( platform ) . debug ( ) . wait ( ) ;
138
+ } else {
139
+ this . liveSyncProject ( platform ) . wait ( ) ;
140
+ }
141
+ } ) ;
142
+ } ) ;
127
143
} ) . future < void > ( ) ( ) ;
128
144
}
129
145
@@ -138,8 +154,7 @@ class TestExecutionService implements ITestExecutionService {
138
154
} ) . future < void > ( ) ( ) ;
139
155
}
140
156
141
- private generateConfig ( options : any ) : string {
142
- let port = this . $options . port ;
157
+ private generateConfig ( port : string , options : any ) : string {
143
158
let nics = os . networkInterfaces ( ) ;
144
159
let ips = Object . keys ( nics )
145
160
. map ( nicName => nics [ nicName ] . filter ( ( binding : any ) => binding . family === 'IPv4' && ! binding . internal ) [ 0 ] )
@@ -154,5 +169,65 @@ class TestExecutionService implements ITestExecutionService {
154
169
155
170
return 'module.exports = ' + JSON . stringify ( config ) ;
156
171
}
172
+
173
+ private getDebugService ( platform : string ) : IDebugService {
174
+ let lowerCasedPlatform = platform . toLowerCase ( ) ;
175
+ if ( lowerCasedPlatform === this . $devicePlatformsConstants . iOS . toLowerCase ( ) ) {
176
+ return this . $iOSDebugService ;
177
+ } else if ( lowerCasedPlatform === this . $devicePlatformsConstants . Android . toLowerCase ( ) ) {
178
+ return this . $androidDebugService ;
179
+ }
180
+
181
+ throw new Error ( `Invalid platform ${ platform } . Valid platforms are ${ this . $devicePlatformsConstants . iOS } and ${ this . $devicePlatformsConstants . Android } ` ) ;
182
+ }
183
+
184
+ private getKarmaConfiguration ( platform : string ) : any {
185
+ let karmaConfig : any = {
186
+ browsers : [ platform ] ,
187
+ configFile : path . join ( this . $projectData . projectDir , 'karma.conf.js' ) ,
188
+ _NS : {
189
+ log : this . $logger . getLevel ( ) ,
190
+ path : this . $options . path ,
191
+ tns : process . argv [ 1 ] ,
192
+ node : process . execPath ,
193
+ options : {
194
+ debugTransport : this . $options . debugTransport ,
195
+ debugBrk : this . $options . debugBrk ,
196
+ }
197
+ } ,
198
+ } ;
199
+ if ( this . $config . DEBUG || this . $logger . getLevel ( ) === 'TRACE' ) {
200
+ karmaConfig . logLevel = 'DEBUG' ;
201
+ }
202
+ if ( ! this . $options . watch ) {
203
+ karmaConfig . singleRun = true ;
204
+ }
205
+ if ( this . $options . debugBrk ) {
206
+ karmaConfig . browserNoActivityTimeout = 1000000000 ;
207
+ }
208
+
209
+ karmaConfig . projectDir = this . $projectData . projectDir ;
210
+ this . $logger . debug ( JSON . stringify ( karmaConfig , null , 4 ) ) ;
211
+
212
+ return karmaConfig ;
213
+ }
214
+
215
+ private liveSyncProject ( platform : string ) : IFuture < void > {
216
+ return ( ( ) => {
217
+ let platformData = this . $platformsData . getPlatformData ( platform . toLowerCase ( ) ) ,
218
+ projectFilesPath = path . join ( platformData . appDestinationDirectoryPath , constants . APP_FOLDER_NAME ) ;
219
+
220
+ let liveSyncData : ILiveSyncData = {
221
+ platform : platform ,
222
+ appIdentifier : this . $projectData . projectId ,
223
+ projectFilesPath : projectFilesPath ,
224
+ syncWorkingDirectory : path . join ( this . $projectData . projectDir , constants . APP_FOLDER_NAME ) ,
225
+ canExecuteFastSync : false , // Always restart the application when change is detected, so tests will be rerun.
226
+ excludedProjectDirsAndFiles : constants . LIVESYNC_EXCLUDED_FILE_PATTERNS
227
+ } ;
228
+
229
+ this . $liveSyncServiceBase . sync ( liveSyncData ) . wait ( ) ;
230
+ } ) . future < void > ( ) ( ) ;
231
+ }
157
232
}
158
233
$injector . register ( 'testExecutionService' , TestExecutionService ) ;
0 commit comments