Skip to content

Commit 042913a

Browse files
committed
Create default config file
1 parent 645199c commit 042913a

File tree

8 files changed

+108
-52
lines changed

8 files changed

+108
-52
lines changed

packages/data-context/src/actions/FileActions.ts

+10
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,14 @@ export class FileActions {
2525

2626
await this.ctx.fs.remove(path.join(this.ctx.currentProject?.projectRoot, relativePath))
2727
}
28+
29+
async checkIfFileExists (relativePath: string) {
30+
if (!this.ctx.currentProject) {
31+
throw new Error(`Cannot check file in project exists without active project`)
32+
}
33+
34+
const filePath = path.join(this.ctx.currentProject?.projectRoot, relativePath)
35+
36+
return await this.ctx.fs.stat(filePath)
37+
}
2838
}

packages/data-context/src/actions/ProjectActions.ts

+41-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { CodeGenType, MutationAddProjectArgs, MutationAppCreateConfigFileArgs, MutationSetProjectPreferencesArgs, TestingTypeEnum } from '@packages/graphql/src/gen/nxs.gen'
1+
import type { CodeGenType, MutationAddProjectArgs, MutationSetProjectPreferencesArgs, TestingTypeEnum } from '@packages/graphql/src/gen/nxs.gen'
22
import type { FindSpecs, FoundBrowser, FoundSpec, FullConfig, LaunchArgs, LaunchOpts, OpenProjectLaunchOptions, Preferences, SettingsOptions } from '@packages/types'
33
import path from 'path'
44
import type { ActiveProjectShape, ProjectShape } from '../data/coreDataShape'
@@ -59,22 +59,38 @@ export class ProjectActions {
5959
await this.clearActiveProject()
6060

6161
// Set initial properties, so we can set the config object on the active project
62-
this.setCurrentProjectProperties({
62+
await this.setCurrentProjectProperties({
6363
projectRoot,
6464
title,
6565
ctPluginsInitialized: false,
6666
e2ePluginsInitialized: false,
6767
config: null,
6868
configChildProcess: null,
69-
})
70-
71-
this.setCurrentProjectProperties({
72-
isCTConfigured: await this.ctx.project.isTestingTypeConfigured(projectRoot, 'component'),
73-
isE2EConfigured: await this.ctx.project.isTestingTypeConfigured(projectRoot, 'e2e'),
69+
isMissingConfigFile: false,
7470
preferences: await this.ctx.project.getProjectPreferences(title),
7571
})
7672

77-
return this
73+
try {
74+
// read the config and cache it
75+
await this.ctx.project.getConfig(projectRoot)
76+
77+
this.setCurrentProjectProperties({
78+
isCTConfigured: await this.ctx.project.isTestingTypeConfigured(projectRoot, 'component'),
79+
isE2EConfigured: await this.ctx.project.isTestingTypeConfigured(projectRoot, 'e2e'),
80+
})
81+
82+
return this
83+
} catch (error: any) {
84+
if (error.type === 'NO_DEFAULT_CONFIG_FILE_FOUND') {
85+
this.setCurrentProjectProperties({
86+
isMissingConfigFile: true,
87+
})
88+
89+
return this
90+
}
91+
92+
throw error
93+
}
7894
}
7995

8096
private setCurrentProjectProperties (currentProjectProperties: Partial<ActiveProjectShape>) {
@@ -257,14 +273,29 @@ export class ProjectActions {
257273
//
258274
}
259275

260-
createConfigFile (args: MutationAppCreateConfigFileArgs) {
276+
async createConfigFile (type?: 'component' | 'e2e' | null) {
261277
const project = this.ctx.currentProject
262278

263279
if (!project) {
264280
throw Error(`Cannot create config file without currentProject.`)
265281
}
266282

267-
this.ctx.fs.writeFileSync(path.resolve(project.projectRoot, args.configFilename), args.code)
283+
let obj: { [k: string]: object } = {
284+
e2e: {},
285+
component: {},
286+
}
287+
288+
if (type) {
289+
obj = {
290+
[type]: {},
291+
}
292+
}
293+
294+
await this.ctx.fs.writeFile(path.resolve(project.projectRoot, 'cypress.config.js'), `module.exports = ${JSON.stringify(obj, null, 2)}`)
295+
296+
this.setCurrentProjectProperties({
297+
isMissingConfigFile: false,
298+
})
268299
}
269300

270301
async clearLatestProjectCache () {

packages/data-context/src/data/coreDataShape.ts

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export interface ActiveProjectShape extends ProjectShape {
3535
configChildProcess: ConfigChildProcessShape | null
3636
preferences?: Preferences| null
3737
browsers: FoundBrowser[] | null
38+
isMissingConfigFile: boolean
3839
}
3940

4041
export interface AppDataShape {

packages/data-context/src/sources/ProjectDataSource.ts

+19-11
Original file line numberDiff line numberDiff line change
@@ -88,21 +88,29 @@ export class ProjectDataSource {
8888
}
8989

9090
async isTestingTypeConfigured (projectRoot: string, testingType: 'e2e' | 'component') {
91-
const config = await this.getConfig(projectRoot)
91+
try {
92+
const config = await this.getConfig(projectRoot)
9293

93-
if (!config) {
94-
return true
95-
}
94+
if (!config) {
95+
return true
96+
}
9697

97-
if (testingType === 'e2e') {
98-
return Boolean(Object.keys(config.e2e ?? {}).length)
99-
}
98+
if (testingType === 'e2e') {
99+
return Boolean(Object.keys(config.e2e ?? {}).length)
100+
}
100101

101-
if (testingType === 'component') {
102-
return Boolean(Object.keys(config.component ?? {}).length)
103-
}
102+
if (testingType === 'component') {
103+
return Boolean(Object.keys(config.component ?? {}).length)
104+
}
104105

105-
return false
106+
return false
107+
} catch (error: any) {
108+
if (error.type === 'NO_DEFAULT_CONFIG_FILE_FOUND') {
109+
return false
110+
}
111+
112+
throw error
113+
}
106114
}
107115

108116
async getProjectPreferences (projectTitle: string) {

packages/frontend-shared/cypress/support/mock-graphql/stubgql-Mutation.ts

-6
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,6 @@ export const stubMutation: MaybeResolver<Mutation> = {
1818

1919
return true
2020
},
21-
appCreateConfigFile: (source, args, ctx) => {
22-
ctx.wizard.chosenManualInstall = true
23-
ctx.wizard.canNavigateForward = true
24-
25-
return true
26-
},
2721
clearActiveProject (source, args, ctx) {
2822
ctx.currentProject = null
2923

packages/graphql/schemas/schema.graphql

-3
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,6 @@ type Mutation {
430430

431431
"""Create an Index HTML file for a new component testing project"""
432432
appCreateComponentIndexHtml(template: String!): Boolean
433-
434-
"""Create a Cypress config file for a new project"""
435-
appCreateConfigFile(code: String!, configFilename: String!): Boolean
436433
clearActiveProject: Boolean
437434

438435
"""

packages/graphql/src/schemaTypes/objectTypes/gql-Mutation.ts

+6-13
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,16 @@ export const mutation = mutationType({
8484
})),
8585
},
8686
resolve: async (_, args, ctx) => {
87+
if (ctx.coreData.currentProject?.isMissingConfigFile) {
88+
await ctx.actions.project.createConfigFile(args.input.testingType)
89+
}
90+
8791
if (args.input.testingType) {
88-
await ctx.actions.wizard.setTestingType(args.input.testingType)
92+
ctx.actions.wizard.setTestingType(args.input.testingType)
8993
}
9094

9195
if (args.input.direction) {
92-
await ctx.actions.wizard.navigate(args.input.direction)
96+
ctx.actions.wizard.navigate(args.input.direction)
9397
}
9498
},
9599
})
@@ -133,17 +137,6 @@ export const mutation = mutationType({
133137
},
134138
})
135139

136-
t.liveMutation('appCreateConfigFile', {
137-
args: {
138-
code: nonNull('String'),
139-
configFilename: nonNull('String'),
140-
},
141-
description: 'Create a Cypress config file for a new project',
142-
resolve: async (_, args, ctx) => {
143-
await ctx.actions.project.createConfigFile(args)
144-
},
145-
})
146-
147140
t.liveMutation('appCreateComponentIndexHtml', {
148141
args: {
149142
template: nonNull('String'),

packages/launchpad/cypress/e2e/integration/config-files-error-handling.spec.ts

+31-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
describe('Config files error handling', () => {
2-
beforeEach(() => {
2+
it('it handles multiples config files', () => {
33
cy.setupE2E('pristine-with-config-file')
44
cy.visitLaunchpad()
5-
})
65

7-
it('it handles multiples config files', () => {
6+
cy.get('[data-cy-testingType=e2e]').click()
7+
88
cy.withCtx(async (ctx) => {
99
await ctx.actions.file.writeFileInProject('cypress.config.ts', 'export default {}')
1010
})
1111

12-
cy.get('[data-cy-testingType=e2e]').click()
13-
1412
cy.get('body').should('contain.text', 'Configuration Files')
1513

1614
cy.get('button').contains('Continue').click()
@@ -28,13 +26,16 @@ describe('Config files error handling', () => {
2826
})
2927

3028
it('it handles legacy config file', () => {
29+
cy.setupE2E('pristine-with-config-file')
30+
cy.visitLaunchpad()
31+
32+
cy.get('[data-cy-testingType=e2e]').click()
33+
3134
cy.withCtx(async (ctx) => {
3235
await ctx.actions.file.writeFileInProject('cypress.json', '{}')
3336
await ctx.actions.file.removeFileInProject('cypress.config.js')
3437
})
3538

36-
cy.get('[data-cy-testingType=e2e]').click()
37-
3839
cy.get('body').should('contain.text', 'Configuration Files')
3940

4041
cy.get('button').contains('Continue').click()
@@ -62,12 +63,15 @@ describe('Config files error handling', () => {
6263
})
6364

6465
it('it handles config files with legacy config file in same project', () => {
66+
cy.setupE2E('pristine-with-config-file')
67+
cy.visitLaunchpad()
68+
69+
cy.get('[data-cy-testingType=e2e]').click()
70+
6571
cy.withCtx(async (ctx) => {
6672
await ctx.actions.file.writeFileInProject('cypress.json', '{}')
6773
})
6874

69-
cy.get('[data-cy-testingType=e2e]').click()
70-
7175
cy.get('body').should('contain.text', 'Configuration Files')
7276

7377
cy.get('button').contains('Continue').click()
@@ -84,4 +88,22 @@ describe('Config files error handling', () => {
8488
cy.get('body')
8589
.should('not.contain.text', 'Cypress Configuration Error')
8690
})
91+
92+
it('creates config file if it do not exist', () => {
93+
cy.setupE2E('pristine')
94+
cy.visitLaunchpad()
95+
96+
cy.get('[data-cy-testingType=e2e]').click()
97+
98+
cy.get('body').should('contain.text', 'Configuration Files')
99+
100+
cy.get('button').contains('Continue').click()
101+
102+
cy.get('body')
103+
.should('contain.text', 'Initializing Config')
104+
105+
cy.withCtx(async (ctx) => {
106+
await ctx.actions.file.checkIfFileExists('cypress.config.js')
107+
})
108+
})
87109
})

0 commit comments

Comments
 (0)