Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use correct path for scaffolding spec on CT #21411

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions packages/app/cypress/e2e/specs.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,8 @@ describe('App: Specs', () => {

it('shows success modal when empty spec is created', () => {
cy.get('@CreateEmptySpecDialog').within(() => {
cy.findByLabelText('Enter a relative path...').invoke('val').should('eq', getPathForPlatform('cypress/component/filename.cy.ts'))

cy.findByLabelText('Enter a relative path...').clear().type('cypress/my-empty-spec.cy.js')

cy.findByRole('button', { name: 'Create Spec' }).click()
Expand All @@ -533,6 +535,8 @@ describe('App: Specs', () => {

it('navigates to spec runner when selected', () => {
cy.get('@CreateEmptySpecDialog').within(() => {
cy.findByLabelText('Enter a relative path...').invoke('val').should('eq', getPathForPlatform('cypress/component/filename.cy.ts'))

cy.findByLabelText('Enter a relative path...').clear().type('cypress/my-empty-spec.cy.js')

cy.findByRole('button', { name: 'Create Spec' }).click()
Expand All @@ -551,6 +555,8 @@ describe('App: Specs', () => {

it('displays alert with docs link on new spec', () => {
cy.get('@CreateEmptySpecDialog').within(() => {
cy.findByLabelText('Enter a relative path...').invoke('val').should('eq', getPathForPlatform('cypress/component/filename.cy.ts'))

cy.findByLabelText('Enter a relative path...').clear().type('cypress/my-empty-spec.cy.js')

cy.findByRole('button', { name: 'Create Spec' }).click()
Expand Down
18 changes: 12 additions & 6 deletions packages/data-context/src/sources/ProjectDataSource.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os from 'os'
import chokidar from 'chokidar'
import type { ResolvedFromConfig, RESOLVED_FROM, FoundSpec } from '@packages/types'
import type { ResolvedFromConfig, RESOLVED_FROM, FoundSpec, TestingType } from '@packages/types'
import { WIZARD_FRAMEWORKS } from '@packages/scaffold-config'
import { scanFSForAvailableDependency } from 'create-cypress-tests'
import minimatch from 'minimatch'
Expand Down Expand Up @@ -104,7 +104,7 @@ export function transformSpec ({
}
}

export function getDefaultSpecFileName (specPattern: string, fileExtensionToUse?: 'js' | 'ts') {
export function getDefaultSpecFileName (specPattern: string, testingType: TestingType, fileExtensionToUse?: 'js' | 'ts') {
function replaceWildCard (s: string, fallback: string) {
return s.replace(/\*/g, fallback)
}
Expand All @@ -121,7 +121,7 @@ export function getDefaultSpecFileName (specPattern: string, fileExtensionToUse?
dirname = dirname.replace('**', 'cypress')
}

const splittedDirname = dirname.split('/').filter((s) => s !== '**').map((x) => replaceWildCard(x, 'e2e')).join('/')
const splittedDirname = dirname.split('/').filter((s) => s !== '**').map((x) => replaceWildCard(x, testingType)).join('/')
const fileName = replaceWildCard(parsedGlob.path.filename, 'filename')

const extnameWithoutExt = parsedGlob.path.extname.replace(parsedGlob.path.ext, '')
Expand Down Expand Up @@ -282,13 +282,15 @@ export class ProjectDataSource {
}

async defaultSpecFileName () {
const defaultFileName = 'cypress/e2e/filename.cy.js'
const getDefaultFileName = (testingType: TestingType) => `cypress/${testingType}/filename.cy.${this.ctx.lifecycleManager.fileExtensionToUse}`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem correct. What if cypress/component does not exist? Considering the default is something like src/**/*.cy.{js.jsx}, it likely won't exist for most users.

Should we make sure the default placeholder is a valid path (or we don't care?)

We could check against the specPattern to make sure it matches (we've already got this logic here.

If it does not match, we could do something like:

const root = specPattern.split('/')[0]
const getDefaultFileName = path.join(root, 'filename.cy', this.ctx.lifecycleManager.fileExtensionToUse)`

What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's why it is checked here to be sure it's the default specPattern - so, this ^^ is just for the default paths

when there're custom specPatterns as you mention it is updated here using the custom pattern and wild cards

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉


try {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not directly related but do we need this try/catch?

if (!this.ctx.currentProject || !this.ctx.coreData.currentTestingType) {
return null
}

const defaultFileName = getDefaultFileName(this.ctx.coreData.currentTestingType)

let specPatternSet: string | undefined
const { specPattern = [] } = await this.ctx.project.specPatterns()

Expand All @@ -300,15 +302,19 @@ export class ProjectDataSource {
return defaultFileName
}

const specFileName = getDefaultSpecFileName(specPatternSet, this.ctx.lifecycleManager.fileExtensionToUse)
if (specPatternSet === defaultSpecPattern[this.ctx.coreData.currentTestingType]) {
return defaultFileName
}

const specFileName = getDefaultSpecFileName(specPatternSet, this.ctx.coreData.currentTestingType, this.ctx.lifecycleManager.fileExtensionToUse)

if (!specFileName) {
return defaultFileName
}

return specFileName
} catch {
return defaultFileName
return getDefaultFileName(this.ctx.coreData.currentTestingType ?? 'e2e')
}
}

Expand Down
44 changes: 22 additions & 22 deletions packages/data-context/test/unit/sources/ProjectDataSource.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,145 +192,145 @@ describe('getDefaultSpecFileName', () => {
context('dirname', () => {
it('returns pattern without change if it is do not a glob', () => {
const specPattern = 'cypress/e2e/foo.spec.ts'
const defaultFileName = getDefaultSpecFileName(specPattern)
const defaultFileName = getDefaultSpecFileName(specPattern, 'e2e')

expect(defaultFileName).to.eq(specPattern)
})

it('remove ** from glob if it is not in the beginning', () => {
const defaultFileName = getDefaultSpecFileName('cypress/**/foo.spec.ts')
const defaultFileName = getDefaultSpecFileName('cypress/**/foo.spec.ts', 'e2e')

expect(defaultFileName).to.eq('cypress/foo.spec.ts')
})

it('replace ** for cypress if it starts with **', () => {
const defaultFileName = getDefaultSpecFileName('**/e2e/foo.spec.ts')
const defaultFileName = getDefaultSpecFileName('**/e2e/foo.spec.ts', 'e2e')

expect(defaultFileName).to.eq('cypress/e2e/foo.spec.ts')
})

it('replace ** for cypress if it starts with ** and omit extra **', () => {
const defaultFileName = getDefaultSpecFileName('**/**/foo.spec.ts')
const defaultFileName = getDefaultSpecFileName('**/**/foo.spec.ts', 'e2e')

expect(defaultFileName).to.eq('cypress/foo.spec.ts')
})

it('selects first option if there are multiples possibilities of values', () => {
const defaultFileName = getDefaultSpecFileName('{cypress,tests}/{integration,e2e}/foo.spec.ts')
const defaultFileName = getDefaultSpecFileName('{cypress,tests}/{integration,e2e}/foo.spec.ts', 'e2e')

expect(defaultFileName).to.eq('cypress/integration/foo.spec.ts')
})
})

context('filename', () => {
it('replace * for filename', () => {
const defaultFileName = getDefaultSpecFileName('cypress/e2e/*.spec.ts')
const defaultFileName = getDefaultSpecFileName('cypress/e2e/*.spec.ts', 'e2e')

expect(defaultFileName).to.eq('cypress/e2e/filename.spec.ts')
})

it('selects first option if there are multiples possibilities of values', () => {
const defaultFileName = getDefaultSpecFileName('cypress/e2e/{foo,filename}.spec.ts')
const defaultFileName = getDefaultSpecFileName('cypress/e2e/{foo,filename}.spec.ts', 'e2e')

expect(defaultFileName).to.eq('cypress/e2e/foo.spec.ts')
})
})

context('test extension', () => {
it('replace * for filename', () => {
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.*.ts')
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.*.ts', 'e2e')

expect(defaultFileName).to.eq('cypress/e2e/filename.cy.ts')
})

it('selects first option if there are multiples possibilities of values', () => {
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.{spec,cy}.ts')
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.{spec,cy}.ts', 'e2e')

expect(defaultFileName).to.eq('cypress/e2e/filename.spec.ts')
})
})

context('lang extension', () => {
it('if project use TS, set TS as extension if it exists in the glob', () => {
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.cy.ts', 'ts')
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.cy.ts', 'e2e', 'ts')

expect(defaultFileName).to.eq('cypress/e2e/filename.cy.ts')
})

it('if project use TS, set TS as extension if it exists in the options of extensions', () => {
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.cy.{js,ts,tsx}', 'ts')
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.cy.{js,ts,tsx}', 'e2e', 'ts')

expect(defaultFileName).to.eq('cypress/e2e/filename.cy.ts')
})

it('if project use TS, do not set TS as extension if it do not exists in the options of extensions', () => {
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.cy.{js,jsx}', 'ts')
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.cy.{js,jsx}', 'e2e', 'ts')

expect(defaultFileName).to.eq('cypress/e2e/filename.cy.js')
})

it('selects first option if there are multiples possibilities of values', () => {
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.cy.{ts,js}')
const defaultFileName = getDefaultSpecFileName('cypress/e2e/filename.cy.{ts,js}', 'e2e')

expect(defaultFileName).to.eq('cypress/e2e/filename.cy.ts')
})
})

context('extra cases', () => {
it('creates specName for tests/*.js', () => {
const defaultFileName = getDefaultSpecFileName('tests/*.js')
const defaultFileName = getDefaultSpecFileName('tests/*.js', 'e2e')

expect(defaultFileName).to.eq('tests/filename.js')
})

it('creates specName for src/*-test.js', () => {
const defaultFileName = getDefaultSpecFileName('src/*-test.js')
const defaultFileName = getDefaultSpecFileName('src/*-test.js', 'e2e')

expect(defaultFileName).to.eq('src/filename-test.js')
})

it('creates specName for src/*.foo.bar.js', () => {
const defaultFileName = getDefaultSpecFileName('src/*.foo.bar.js')
const defaultFileName = getDefaultSpecFileName('src/*.foo.bar.js', 'e2e')

expect(defaultFileName).to.eq('src/filename.foo.bar.js')
})

it('creates specName for src/prefix.*.test.js', () => {
const defaultFileName = getDefaultSpecFileName('src/prefix.*.test.js')
const defaultFileName = getDefaultSpecFileName('src/prefix.*.test.js', 'e2e')

expect(defaultFileName).to.eq('src/prefix.cy.test.js')
})

it('creates specName for src/*/*.test.js', () => {
const defaultFileName = getDefaultSpecFileName('src/*/*.test.js')
const defaultFileName = getDefaultSpecFileName('src/*/*.test.js', 'e2e')

expect(defaultFileName).to.eq('src/e2e/filename.test.js')
})

it('creates specName for src-*/**/*.test.js', () => {
const defaultFileName = getDefaultSpecFileName('src-*/**/*.test.js')
const defaultFileName = getDefaultSpecFileName('src-*/**/*.test.js', 'e2e')

expect(defaultFileName).to.eq('src-e2e/filename.test.js')
})

it('creates specName for src/*.test.(js|jsx)', () => {
const defaultFileName = getDefaultSpecFileName('src/*.test.(js|jsx)')
const defaultFileName = getDefaultSpecFileName('src/*.test.(js|jsx)', 'e2e')

const possiblesFileNames = ['src/filename.test.jsx', 'src/filename.test.js']

expect(possiblesFileNames.includes(defaultFileName)).to.eq(true)
})

it('creates specName for (src|components)/**/*.test.js', () => {
const defaultFileName = getDefaultSpecFileName('(src|components)/**/*.test.js')
const defaultFileName = getDefaultSpecFileName('(src|components)/**/*.test.js', 'e2e')

const possiblesFileNames = ['src/filename.test.js', 'components/filename.test.js']

expect(possiblesFileNames.includes(defaultFileName)).to.eq(true)
})

it('creates specName for e2e/**/*.cy.{js,jsx,ts,tsx}', () => {
const defaultFileName = getDefaultSpecFileName('e2e/**/*.cy.{js,jsx,ts,tsx}')
const defaultFileName = getDefaultSpecFileName('e2e/**/*.cy.{js,jsx,ts,tsx}', 'e2e')

expect(defaultFileName).to.eq('e2e/filename.cy.js')
})
Expand Down