7
7
*/
8
8
9
9
import { BuilderContext , BuilderOutput , createBuilder } from '@angular-devkit/architect' ;
10
- import { Config , ConfigOptions } from 'karma' ;
10
+ import { strings } from '@angular-devkit/core' ;
11
+ import { Config , ConfigOptions , config , constants } from 'karma' ;
12
+ import { createRequire } from 'module' ;
11
13
import * as path from 'path' ;
12
14
import { Observable , from } from 'rxjs' ;
13
15
import { defaultIfEmpty , switchMap } from 'rxjs/operators' ;
@@ -86,9 +88,17 @@ export function execute(
86
88
87
89
return from ( initialize ( options , context , transforms . webpackConfiguration ) ) . pipe (
88
90
switchMap ( async ( [ karma , webpackConfig ] ) => {
89
- const karmaOptions : KarmaConfigOptions = {
90
- singleRun,
91
- } ;
91
+ // Determine project name from builder context target
92
+ const projectName = context . target ?. project ;
93
+ if ( ! projectName ) {
94
+ throw new Error ( `The 'karma' builder requires a target to be specified.` ) ;
95
+ }
96
+
97
+ const karmaOptions : KarmaConfigOptions = options . karmaConfig
98
+ ? { }
99
+ : getBuiltInKarmaConfig ( context . workspaceRoot , projectName ) ;
100
+
101
+ karmaOptions . singleRun = singleRun ;
92
102
93
103
// Convert browsers from a string to an array
94
104
if ( options . browsers ) {
@@ -106,11 +116,6 @@ export function execute(
106
116
}
107
117
}
108
118
109
- const projectName = context . target ?. project ;
110
- if ( ! projectName ) {
111
- throw new Error ( 'The builder requires a target.' ) ;
112
- }
113
-
114
119
if ( ! options . main ) {
115
120
webpackConfig . entry ??= { } ;
116
121
if ( typeof webpackConfig . entry === 'object' && ! Array . isArray ( webpackConfig . entry ) ) {
@@ -140,13 +145,13 @@ export function execute(
140
145
logger : context . logger ,
141
146
} ;
142
147
143
- const config = await karma . config . parseConfig (
144
- path . resolve ( context . workspaceRoot , options . karmaConfig ) ,
148
+ const parsedKarmaConfig = await config . parseConfig (
149
+ options . karmaConfig && path . resolve ( context . workspaceRoot , options . karmaConfig ) ,
145
150
transforms . karmaOptions ? transforms . karmaOptions ( karmaOptions ) : karmaOptions ,
146
151
{ promiseConfig : true , throwErrors : true } ,
147
152
) ;
148
153
149
- return [ karma , config ] as [ typeof karma , KarmaConfigOptions ] ;
154
+ return [ karma , parsedKarmaConfig ] as [ typeof karma , KarmaConfigOptions ] ;
150
155
} ) ,
151
156
switchMap (
152
157
( [ karma , karmaConfig ] ) =>
@@ -178,6 +183,48 @@ export function execute(
178
183
) ;
179
184
}
180
185
186
+ function getBuiltInKarmaConfig (
187
+ workspaceRoot : string ,
188
+ projectName : string ,
189
+ ) : ConfigOptions & Record < string , unknown > {
190
+ let coverageFolderName = projectName . charAt ( 0 ) === '@' ? projectName . slice ( 1 ) : projectName ;
191
+ if ( / [ A - Z ] / . test ( coverageFolderName ) ) {
192
+ coverageFolderName = strings . dasherize ( coverageFolderName ) ;
193
+ }
194
+
195
+ const workspaceRootRequire = createRequire ( workspaceRoot + '/' ) ;
196
+
197
+ return {
198
+ basePath : '' ,
199
+ frameworks : [ 'jasmine' , '@angular-devkit/build-angular' ] ,
200
+ plugins : [
201
+ 'karma-jasmine' ,
202
+ 'karma-chrome-launcher' ,
203
+ 'karma-jasmine-html-reporter' ,
204
+ 'karma-coverage' ,
205
+ '@angular-devkit/build-angular/plugins/karma' ,
206
+ ] . map ( ( p ) => workspaceRootRequire ( p ) ) ,
207
+ client : {
208
+ clearContext : false , // leave Jasmine Spec Runner output visible in browser
209
+ } ,
210
+ jasmineHtmlReporter : {
211
+ suppressAll : true , // removes the duplicated traces
212
+ } ,
213
+ coverageReporter : {
214
+ dir : path . join ( workspaceRoot , 'coverage' , coverageFolderName ) ,
215
+ subdir : '.' ,
216
+ reporters : [ { type : 'html' } , { type : 'text-summary' } ] ,
217
+ } ,
218
+ reporters : [ 'progress' , 'kjhtml' ] ,
219
+ port : 9876 ,
220
+ colors : true ,
221
+ logLevel : constants . LOG_INFO ,
222
+ autoWatch : true ,
223
+ browsers : [ 'Chrome' ] ,
224
+ restartOnFileChange : true ,
225
+ } ;
226
+ }
227
+
181
228
export { KarmaBuilderOptions } ;
182
229
export default createBuilder < Record < string , string > & KarmaBuilderOptions > ( execute ) ;
183
230
0 commit comments