fix: handle testFiles array in migration (#25969)

* handle testFiles as array

* update project

* macos build

* use castArray
This commit is contained in:
Lachlan Miller
2023-03-01 11:25:36 +10:00
committed by GitHub
parent 55b5f67e72
commit faba531c64
12 changed files with 157 additions and 6 deletions
+3 -1
View File
@@ -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"
]
}
@@ -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'],
},
})