mirror of
https://github.com/cypress-io/cypress.git
synced 2026-04-22 07:00:22 -05:00
fix: handle testFiles array in migration (#25969)
* handle testFiles as array * update project * macos build * use castArray
This commit is contained in:
@@ -30,6 +30,7 @@ mainBuildFilters: &mainBuildFilters
|
||||
- /^release\/\d+\.\d+\.\d+$/
|
||||
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
|
||||
- 'update-v8-snapshot-cache-on-develop'
|
||||
- 'lmiller/issue-25947'
|
||||
- 'fix/preflight'
|
||||
|
||||
# usually we don't build Mac app - it takes a long time
|
||||
@@ -42,6 +43,7 @@ macWorkflowFilters: &darwin-workflow-filters
|
||||
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
|
||||
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
|
||||
- equal: [ 'fix/preflight', << pipeline.git.branch >> ]
|
||||
- equal: [ 'lmiller/issue-25947', << pipeline.git.branch >> ]
|
||||
- matches:
|
||||
pattern: /^release\/\d+\.\d+\.\d+$/
|
||||
value: << pipeline.git.branch >>
|
||||
@@ -139,7 +141,7 @@ commands:
|
||||
- run:
|
||||
name: Check current branch to persist artifacts
|
||||
command: |
|
||||
if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "fix/preflight" && "$CIRCLE_BRANCH" != "update-v8-snapshot-cache-on-develop" ]]; then
|
||||
if [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "lmiller/issue-25947" && "$CIRCLE_BRANCH" != "update-v8-snapshot-cache-on-develop" ]]; then
|
||||
echo "Not uploading artifacts or posting install comment for this branch."
|
||||
circleci-agent step halt
|
||||
fi
|
||||
|
||||
@@ -252,3 +252,15 @@ export default defineConfig({
|
||||
})
|
||||
|
||||
`
|
||||
|
||||
exports['cypress.config.js generation generates correct config for component testing migration with custom testFiles array of glob 1'] = `
|
||||
const { defineConfig } = require('cypress')
|
||||
|
||||
module.exports = defineConfig({
|
||||
e2e: {
|
||||
setupNodeEvents(on, config) {},
|
||||
specPattern: ['cypress/e2e/**/*.spec.js', 'cypress/e2e/**/*.test.js'],
|
||||
},
|
||||
})
|
||||
|
||||
`
|
||||
|
||||
@@ -511,25 +511,35 @@ export function reduceConfig (cfg: LegacyCypressConfigJson, options: CreateConfi
|
||||
}, { global: {}, e2e: {}, component: {} })
|
||||
}
|
||||
|
||||
function propOrArrayProp<T> (val: T[]): T | T[] {
|
||||
if (val[0] && val.length === 1) {
|
||||
return val[0]
|
||||
}
|
||||
|
||||
return val
|
||||
}
|
||||
|
||||
export function getSpecPattern (cfg: LegacyCypressConfigJson, testingType: TestingType, shouldAddCustomE2ESpecPattern: boolean = false) {
|
||||
const specPattern = cfg[testingType]?.testFiles ?? cfg.testFiles ?? (testingType === 'e2e' && shouldAddCustomE2ESpecPattern ? '**/*.{js,jsx,ts,tsx}' : '**/*.cy.{js,jsx,ts,tsx}')
|
||||
let _specPattern = cfg[testingType]?.testFiles ?? cfg.testFiles ?? (testingType === 'e2e' && shouldAddCustomE2ESpecPattern ? '**/*.{js,jsx,ts,tsx}' : '**/*.cy.{js,jsx,ts,tsx}')
|
||||
const specPattern = _.castArray(_specPattern)
|
||||
|
||||
const customComponentFolder = cfg.component?.componentFolder ?? cfg.componentFolder ?? null
|
||||
|
||||
if (testingType === 'component' && customComponentFolder) {
|
||||
return `${customComponentFolder}/${specPattern}`
|
||||
return propOrArrayProp(specPattern.map((pattern) => `${customComponentFolder}/${pattern}`))
|
||||
}
|
||||
|
||||
if (testingType === 'e2e') {
|
||||
const customIntegrationFolder = cfg.e2e?.integrationFolder ?? cfg.integrationFolder ?? null
|
||||
|
||||
if (customIntegrationFolder && customIntegrationFolder !== legacyIntegrationFolder) {
|
||||
return `${customIntegrationFolder}/${specPattern}`
|
||||
return propOrArrayProp(specPattern.map((pattern) => `${customIntegrationFolder}/${pattern}`))
|
||||
}
|
||||
|
||||
return `cypress/e2e/${specPattern}`
|
||||
return propOrArrayProp(specPattern.map((pattern) => `cypress/e2e/${pattern}`))
|
||||
}
|
||||
|
||||
return specPattern
|
||||
return propOrArrayProp(specPattern)
|
||||
}
|
||||
|
||||
function formatWithBundledBabel (config: string) {
|
||||
|
||||
@@ -38,6 +38,26 @@ describe('cypress.config.js generation', () => {
|
||||
snapshot(generatedConfig)
|
||||
})
|
||||
|
||||
it('generates correct config for component testing migration with custom testFiles array of glob', async () => {
|
||||
const config = {
|
||||
e2e: {
|
||||
testFiles: ['**/*.spec.js', '**/*.test.js'],
|
||||
},
|
||||
}
|
||||
|
||||
const generatedConfig = await createConfigString(config, {
|
||||
hasE2ESpec: true,
|
||||
hasComponentTesting: false,
|
||||
hasPluginsFile: false,
|
||||
projectRoot,
|
||||
isUsingTypeScript: false,
|
||||
shouldAddCustomE2ESpecPattern: true,
|
||||
isProjectUsingESModules: false,
|
||||
})
|
||||
|
||||
snapshot(generatedConfig)
|
||||
})
|
||||
|
||||
it('should create a string when passed only a global option', async () => {
|
||||
const config: Partial<Cypress.Config> = {
|
||||
viewportWidth: 300,
|
||||
|
||||
@@ -684,6 +684,59 @@ describe('Full migration flow for each project', { retries: { openMode: 0, runMo
|
||||
checkOutcome()
|
||||
})
|
||||
|
||||
it('completes journey for migration-e2e-custom-test-files', () => {
|
||||
const project = 'migration-e2e-custom-test-files-array'
|
||||
|
||||
startMigrationFor(project)
|
||||
// default integration but custom testFiles
|
||||
// can rename integration->e2e
|
||||
cy.get(renameAutoStep).should('exist')
|
||||
// no CT
|
||||
cy.get(renameManualStep).should('not.exist')
|
||||
// supportFile is false - cannot migrate
|
||||
cy.get(renameSupportStep).should('exist')
|
||||
cy.get(setupComponentStep).should('not.exist')
|
||||
cy.get(configFileStep).should('exist')
|
||||
|
||||
cy.scaffoldProject(project)
|
||||
cy.openProject(project)
|
||||
cy.visitLaunchpad()
|
||||
|
||||
// default testFiles but custom integration - can rename automatically
|
||||
cy.get(renameAutoStep).should('exist')
|
||||
// no CT
|
||||
cy.get(renameManualStep).should('not.exist')
|
||||
// supportFile is false - cannot migrate
|
||||
cy.get(renameSupportStep).should('exist')
|
||||
cy.get(setupComponentStep).should('not.exist')
|
||||
cy.get(configFileStep).should('exist')
|
||||
|
||||
// Migration workflow
|
||||
// before auto migration
|
||||
cy.contains('cypress/integration/basic.test.js')
|
||||
cy.contains('cypress/integration/basic.spec.js')
|
||||
|
||||
// after auto migration
|
||||
cy.contains('cypress/e2e/basic.test.js')
|
||||
cy.contains('cypress/e2e/basic.spec.js')
|
||||
|
||||
runAutoRename()
|
||||
|
||||
cy.withRetryableCtx(async (ctx) => {
|
||||
const specs = ['cypress/e2e/basic.test.js', 'cypress/e2e/basic.spec.js']
|
||||
|
||||
for (const spec of specs) {
|
||||
const stats = await ctx.file.checkIfFileExists(ctx.path.join(spec))
|
||||
|
||||
expect(stats).to.not.be.null
|
||||
}
|
||||
})
|
||||
|
||||
renameSupport()
|
||||
migrateAndVerifyConfig()
|
||||
checkOutcome()
|
||||
})
|
||||
|
||||
it('completes journey for migration-e2e-defaults', () => {
|
||||
startMigrationFor('migration-e2e-defaults')
|
||||
// defaults, rename all the things
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
## Migration E2E Custom testFiles
|
||||
|
||||
An e2e project with a custom testFiles but default integrationFolder. We won't rename the specs, but we will rename `integration` to `e2e`. `testFiles` is an *array* of globs.
|
||||
|
||||
The following migration steps will be used during this migration:
|
||||
|
||||
- [x] automatic file rename
|
||||
- [ ] manual file rename
|
||||
- [x] rename support
|
||||
- [x] update config file
|
||||
- [ ] setup component testing
|
||||
|
||||
## Automatic Migration
|
||||
|
||||
Unless the user skips this step, after this step, the filesystem will be:
|
||||
|
||||
| Before | After|
|
||||
|---|---|
|
||||
| `integration/basic.test.js` | `e2e/basic.test.js` |
|
||||
| `integration/basic.spec.js` | `e2e/basic.spec.js` |
|
||||
|
||||
## Manual Files
|
||||
|
||||
This step is not used.
|
||||
|
||||
## Rename supportFile
|
||||
|
||||
The project has a default support file, `cypress/support/index.js`. We can rename it for them to `cypress/support/e2e.js`.
|
||||
|
||||
| Before | After|
|
||||
|---|---|
|
||||
| `cypress/support/index.js` | `cypress/support/e2e.js` |
|
||||
|
||||
## Update Config
|
||||
|
||||
The expected output is in [`expected-cypress.config.js`](./expected-cypress.config.js).
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"testFiles": [
|
||||
"**/*.test.js",
|
||||
"**/*.spec.js"
|
||||
]
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
const { defineConfig } = require('cypress')
|
||||
|
||||
module.exports = defineConfig({
|
||||
e2e: {
|
||||
// We've imported your old cypress plugins here.
|
||||
// You may want to clean this up later by importing these.
|
||||
setupNodeEvents (on, config) {
|
||||
return require('./cypress/plugins/index.js')(on, config)
|
||||
},
|
||||
specPattern: ['cypress/e2e/**/*.test.js', 'cypress/e2e/**/*.spec.js'],
|
||||
},
|
||||
})
|
||||
Reference in New Issue
Block a user