1
1
import type { CodeLanguageEnum , NexusGenEnums , NexusGenObjects } from '@packages/graphql/src/gen/nxs.gen'
2
- import { CodeLanguage , CODE_LANGUAGES } from '@packages/types'
3
- import { Bundler , FrontendFramework , FRONTEND_FRAMEWORKS , detect } from '@packages/scaffold-config'
2
+ import { CODE_LANGUAGES } from '@packages/types'
3
+ import { detect , WIZARD_FRAMEWORKS , WIZARD_BUNDLERS , commandsFileBody , supportFileComponent , supportFileE2E } from '@packages/scaffold-config'
4
4
import assert from 'assert'
5
5
import dedent from 'dedent'
6
6
import path from 'path'
7
- import fs from 'fs-extra'
8
7
import Debug from 'debug'
9
8
10
9
const debug = Debug ( 'cypress:data-context:wizard-actions' )
11
10
12
11
import type { DataContext } from '..'
13
12
14
13
interface WizardGetCodeComponent {
15
- chosenLanguage : CodeLanguage
16
- chosenFramework : FrontendFramework
14
+ chosenLanguage : 'js' | 'ts'
15
+ chosenFramework : typeof WIZARD_FRAMEWORKS [ number ]
17
16
}
18
17
19
18
export class WizardActions {
@@ -29,13 +28,15 @@ export class WizardActions {
29
28
return this . ctx . wizardData
30
29
}
31
30
32
- setFramework ( framework : typeof FRONTEND_FRAMEWORKS [ number ] [ 'type' ] | null ) : void {
33
- const next = FRONTEND_FRAMEWORKS . find ( ( x ) => x . type === framework )
31
+ setFramework ( framework : typeof WIZARD_FRAMEWORKS [ number ] | null ) : void {
32
+ const next = WIZARD_FRAMEWORKS . find ( ( x ) => x . type === framework ?. type )
34
33
35
- this . ctx . coreData . wizard . chosenFramework = framework
34
+ this . ctx . update ( ( coreData ) => {
35
+ coreData . wizard . chosenFramework = framework
36
+ } )
36
37
37
38
if ( next ?. supportedBundlers ?. length === 1 ) {
38
- this . setBundler ( next ?. supportedBundlers ?. [ 0 ] . type )
39
+ this . setBundler ( next ?. supportedBundlers ?. [ 0 ] )
39
40
40
41
return
41
42
}
@@ -45,26 +46,30 @@ export class WizardActions {
45
46
// if the previous bundler was incompatible with the
46
47
// new framework that was selected, we need to reset it
47
48
const doesNotSupportChosenBundler = ( chosenBundler && ! new Set (
48
- this . ctx . wizard . chosenFramework ?. supportedBundlers . map ( ( x ) => x . type ) || [ ] ,
49
- ) . has ( chosenBundler ) ) ?? false
49
+ this . ctx . coreData . wizard . chosenFramework ?. supportedBundlers . map ( ( x ) => x . type ) || [ ] ,
50
+ ) . has ( chosenBundler . type ) ) ?? false
50
51
51
- const prevFramework = this . ctx . coreData . wizard . chosenFramework || ''
52
+ const prevFramework = this . ctx . coreData . wizard . chosenFramework ?. type ?? null
52
53
53
- if ( doesNotSupportChosenBundler || ! [ 'react' , 'vue' ] . includes ( prevFramework ) ) {
54
+ if ( ! prevFramework || doesNotSupportChosenBundler || ! [ 'react' , 'vue' ] . includes ( prevFramework ) ) {
54
55
this . setBundler ( null )
55
56
}
56
57
}
57
58
58
- setBundler ( bundler : Bundler | null ) {
59
- this . ctx . coreData . wizard . chosenBundler = bundler
59
+ setBundler ( bundler : typeof WIZARD_BUNDLERS [ number ] | null ) {
60
+ this . ctx . update ( ( coreData ) => {
61
+ coreData . wizard . chosenBundler = bundler
62
+ } )
60
63
61
- return this . data
64
+ return this . ctx . coreData . wizard
62
65
}
63
66
64
67
setCodeLanguage ( lang : NexusGenEnums [ 'CodeLanguageEnum' ] ) {
65
- this . ctx . coreData . wizard . chosenLanguage = lang
68
+ this . ctx . update ( ( coreData ) => {
69
+ coreData . wizard . chosenLanguage = lang
70
+ } )
66
71
67
- return this . data
72
+ return this . ctx . coreData . wizard
68
73
}
69
74
70
75
async completeSetup ( ) {
@@ -83,48 +88,44 @@ export class WizardActions {
83
88
84
89
/// reset wizard status, useful for when changing to a new project
85
90
resetWizard ( ) {
86
- this . data . chosenBundler = null
87
- this . data . chosenFramework = null
88
- this . data . chosenLanguage = 'js'
91
+ this . ctx . update ( ( coreData ) => {
92
+ coreData . wizard . chosenBundler = null
93
+ coreData . wizard . chosenFramework = null
94
+ coreData . wizard . chosenLanguage = 'js'
95
+ coreData . wizard . detectedBundler = null
96
+ coreData . wizard . detectedFramework = null
97
+ } )
89
98
90
- return this . data
99
+ return this . ctx . coreData . wizard
91
100
}
92
101
93
102
async initialize ( ) {
94
103
if ( ! this . ctx . currentProject ) {
95
104
return
96
105
}
97
106
98
- this . ctx . update ( ( coreData ) => {
99
- coreData . wizard . detectedFramework = null
100
- coreData . wizard . detectedBundler = null
101
- coreData . wizard . detectedLanguage = null
102
- } )
107
+ this . resetWizard ( )
103
108
104
109
await this . detectLanguage ( )
105
110
debug ( 'detectedLanguage %s' , this . data . detectedLanguage )
106
111
this . data . chosenLanguage = this . data . detectedLanguage || 'js'
107
112
108
- try {
109
- const detected = detect ( await fs . readJson ( path . join ( this . ctx . currentProject , 'package.json' ) ) )
113
+ const detected = detect ( this . ctx . currentProject )
110
114
111
- debug ( 'detected %o' , detected )
115
+ debug ( 'detected %o' , detected )
112
116
113
- if ( detected ) {
114
- this . ctx . update ( ( coreData ) => {
115
- coreData . wizard . detectedFramework = detected . framework ?. type ?? null
116
- coreData . wizard . chosenFramework = detected . framework ?. type ?? null
117
+ if ( detected ) {
118
+ this . ctx . update ( ( coreData ) => {
119
+ coreData . wizard . detectedFramework = detected . framework ?? null
120
+ coreData . wizard . chosenFramework = detected . framework ?? null
117
121
118
- if ( ! detected . framework ?. supportedBundlers [ 0 ] ) {
119
- return
120
- }
122
+ if ( ! detected . framework ?. supportedBundlers [ 0 ] ) {
123
+ return
124
+ }
121
125
122
- coreData . wizard . detectedBundler = detected . bundler || detected . framework . supportedBundlers [ 0 ] . type
123
- coreData . wizard . chosenBundler = detected . bundler || detected . framework . supportedBundlers [ 0 ] . type
124
- } )
125
- }
126
- } catch {
127
- // Could not detect anything - no problem, no need to do anything.
126
+ coreData . wizard . detectedBundler = detected . bundler || detected . framework . supportedBundlers [ 0 ]
127
+ coreData . wizard . chosenBundler = detected . bundler || detected . framework . supportedBundlers [ 0 ]
128
+ } )
128
129
}
129
130
}
130
131
@@ -160,7 +161,7 @@ export class WizardActions {
160
161
return
161
162
}
162
163
case 'component' : {
163
- const { chosenBundler, chosenFramework } = this . ctx . wizard
164
+ const { chosenBundler, chosenFramework } = this . ctx . coreData . wizard
164
165
165
166
if ( ! chosenBundler || ! chosenFramework ) {
166
167
return
@@ -190,15 +191,15 @@ export class WizardActions {
190
191
191
192
private async scaffoldComponent ( ) {
192
193
debug ( 'scaffoldComponent' )
193
- const { chosenBundler, chosenFramework, chosenLanguage } = this . ctx . wizard
194
+ const { chosenBundler, chosenFramework, chosenLanguage } = this . ctx . coreData . wizard
194
195
195
196
assert ( chosenFramework && chosenLanguage && chosenBundler )
196
197
197
198
return await Promise . all ( [
198
199
this . scaffoldConfig ( 'component' ) ,
199
200
this . scaffoldFixtures ( ) ,
200
- this . scaffoldSupport ( 'component' , chosenLanguage . type ) ,
201
- this . scaffoldSupport ( 'commands' , chosenLanguage . type ) ,
201
+ this . scaffoldSupport ( 'component' , chosenLanguage ) ,
202
+ this . scaffoldSupport ( 'commands' , chosenLanguage ) ,
202
203
this . getComponentIndexHtml ( {
203
204
chosenFramework,
204
205
chosenLanguage,
@@ -213,7 +214,18 @@ export class WizardActions {
213
214
// @ts -ignore
214
215
await this . ctx . fs . mkdir ( supportDir , { recursive : true } )
215
216
216
- const fileContent = fileName === 'commands' ? this . commandsFileBody ( language ) : this . supportFileBody ( fileName , language )
217
+ let fileContent : string | undefined
218
+
219
+ if ( fileName === 'commands' ) {
220
+ fileContent = commandsFileBody ( language )
221
+ } else if ( fileName === 'e2e' ) {
222
+ fileContent = supportFileE2E ( language )
223
+ } else if ( fileName === 'component' ) {
224
+ assert ( this . ctx . coreData . wizard . chosenFramework )
225
+ fileContent = supportFileComponent ( language , this . ctx . coreData . wizard . chosenFramework )
226
+ }
227
+
228
+ assert ( fileContent )
217
229
218
230
await this . scaffoldFile ( supportFile , fileContent , 'Scaffold default support file' )
219
231
@@ -230,11 +242,16 @@ export class WizardActions {
230
242
if ( testingType === 'component' ) {
231
243
const chosenLanguage = CODE_LANGUAGES . find ( ( f ) => f . type === language )
232
244
233
- const { chosenBundler, chosenFramework } = this . ctx . wizard
245
+ const { chosenBundler, chosenFramework } = this . ctx . coreData . wizard
234
246
235
- assert ( chosenFramework && chosenLanguage && chosenBundler )
247
+ assert ( chosenFramework && chosenLanguage && chosenBundler && this . ctx . currentProject )
236
248
237
- return chosenFramework . config [ chosenLanguage . type ] ( chosenBundler . type )
249
+ return chosenFramework . createCypressConfig ( {
250
+ language : chosenLanguage . type ,
251
+ bundler : chosenBundler . type ,
252
+ framework : chosenFramework . configFramework ,
253
+ projectRoot : this . ctx . currentProject ,
254
+ } )
238
255
}
239
256
240
257
return this . wizardGetConfigCodeE2E ( language )
@@ -390,79 +407,8 @@ export class WizardActions {
390
407
private ensureDir ( type : 'component' | 'e2e' | 'fixtures' ) {
391
408
return this . ctx . fs . ensureDir ( path . join ( this . projectRoot , 'cypress' , type ) )
392
409
}
393
-
394
- private supportFileBody ( fileName : 'e2e' | 'component' , language : CodeLanguageEnum ) {
395
- return dedent `
396
- // ***********************************************************
397
- // This example support/${ fileName } .${ language } is processed and
398
- // loaded automatically before your test files.
399
- //
400
- // This is a great place to put global configuration and
401
- // behavior that modifies Cypress.
402
- //
403
- // You can change the location of this file or turn off
404
- // automatically serving support files with the
405
- // 'supportFile' configuration option.
406
- //
407
- // You can read more here:
408
- // https://on.cypress.io/configuration
409
- // ***********************************************************
410
-
411
- // Import commands.js using ES2015 syntax:
412
- import './commands'
413
-
414
- // Alternatively you can use CommonJS syntax:
415
- // require('./commands')
416
- `
417
- }
418
-
419
- private commandsFileBody ( language : CodeLanguageEnum ) {
420
- return dedent `
421
- ${ language === 'ts' ? '/// <reference types="cypress" />' : '' }
422
- // ***********************************************
423
- // This example commands.${ language } shows you how to
424
- // create various custom commands and overwrite
425
- // existing commands.
426
- //
427
- // For more comprehensive examples of custom
428
- // commands please read more here:
429
- // https://on.cypress.io/custom-commands
430
- // ***********************************************
431
- //
432
- //
433
- // -- This is a parent command --
434
- // Cypress.Commands.add('login', (email, password) => { ... })
435
- //
436
- //
437
- // -- This is a child command --
438
- // Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
439
- //
440
- //
441
- // -- This is a dual command --
442
- // Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
443
- //
444
- //
445
- // -- This will overwrite an existing command --
446
- // Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
447
- ${ language === 'ts' ? COMMAND_TYPES : '' }
448
- `
449
- }
450
410
}
451
411
452
- const COMMAND_TYPES = dedent `
453
- //
454
- // declare global {
455
- // namespace Cypress {
456
- // interface Chainable {
457
- // login(email: string, password: string): Chainable<void>
458
- // drag(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
459
- // dismiss(subject: string, options?: Partial<TypeOptions>): Chainable<Element>
460
- // visit(originalFn: CommandOriginalFn, url: string, options: Partial<VisitOptions>): Chainable<Element>
461
- // }
462
- // }
463
- // }
464
- `
465
-
466
412
const E2E_SCAFFOLD_BODY = dedent `
467
413
e2e: {
468
414
setupNodeEvents(on, config) {
0 commit comments