feat: use supportFile by testingType (#19364)

* feat: use supportFile by testingType

* Fix defaults

* Start renaming files, and updating system-tests

* Fix some tests

* Fix some tests

* Fix more tests

* Try to fix CI

* Fix more tests

* Fix some tests

* Revert changes

* Revert supportFile defaultValue

* Fix some tests

* Fix some tests

* Fix some tests

* Fix some tests

* Update supportFile example

* Update snapshots

* Remove scaffold support

* Handle config errors

* Remove scaffold

* Fix tests

* Fix test

* Update test

* Fix test

* Update supportFile template

* Fix template
This commit is contained in:
Alejandro Estrada
2022-01-05 13:37:44 -05:00
committed by GitHub
parent 59703a6169
commit 0366d4fa89
191 changed files with 567 additions and 493 deletions

View File

@@ -22,7 +22,8 @@ system-tests/projects/**/static/*
system-tests/projects/**/*.jsx
system-tests/projects/**/fail.js
system-tests/lib/scaffold/plugins/index.js
system-tests/lib/scaffold/support/index.js
system-tests/lib/scaffold/support/e2e.js
system-tests/lib/scaffold/support/component.js
system-tests/lib/scaffold/support/commands.js
system-tests/test/support/projects/e2e/cypress/
system-tests/projects/e2e/cypress/integration/stdout_exit_early_failing_spec.js

View File

@@ -813,6 +813,13 @@ commands:
rm -rf cypress.json
echo 'module.exports = {}' > cypress.config.js
fi
- run:
name: Rename support file
working_directory: /tmp/<<parameters.repo>>
command: |
if [[ -f cypress/support/index.js ]]; then
mv cypress/support/index.js cypress/support/e2e.js
fi
- run:
name: Print Cypress version
working_directory: /tmp/<<parameters.repo>>
@@ -1681,7 +1688,7 @@ jobs:
steps:
- clone-repo-and-checkout-branch:
repo: cypress-example-kitchensink
pull_request_id: 510
pull_request_id: 523
- install-required-node
- run:
name: Remove cypress.json
@@ -1933,6 +1940,10 @@ jobs:
},
},
}" > cypress.config.ts
- run:
name: Rename support file
working_directory: <<parameters.wd>>
command: mv cypress/support/index.ts cypress/support/e2e.js
- run:
name: Run project tests 🗳
working_directory: <<parameters.wd>>
@@ -2003,7 +2014,7 @@ jobs:
- test-binary-against-repo:
repo: cypress-example-kitchensink
browser: "electron"
pull_request_id: 510
pull_request_id: 523
test-binary-against-awesome-typescript-loader:
<<: *defaults
@@ -2011,6 +2022,7 @@ jobs:
- test-binary-against-repo:
repo: cypress-test-awesome-typescript-loader
browser: "electron"
pull_request_id: 7
test-binary-against-kitchensink-firefox:
<<: *defaults
@@ -2019,7 +2031,7 @@ jobs:
- test-binary-against-repo:
repo: cypress-example-kitchensink
browser: firefox
pull_request_id: 510
pull_request_id: 523
test-binary-against-kitchensink-chrome:
<<: *defaults
@@ -2028,7 +2040,7 @@ jobs:
- test-binary-against-repo:
repo: cypress-example-kitchensink
browser: chrome
pull_request_id: 510
pull_request_id: 523
test-binary-against-todomvc-firefox:
<<: *defaults
@@ -2120,6 +2132,10 @@ jobs:
command: |
rm -rf cypress.json
echo 'module.exports = {}' > cypress.config.js
- run:
name: Rename support file
working_directory: test-binary
command: mv cypress/support/index.js cypress/support/e2e.js
- run:
name: Verify Cypress binary
working_directory: test-binary

View File

@@ -147,7 +147,7 @@
"string",
"boolean"
],
"default": "cypress/support/index.js",
"default": "cypress/support/e2e.js",
"description": "Path to file to load before test files load. This file is compiled and bundled. (Pass false to disable)"
},
"videosFolder": {

View File

@@ -2742,7 +2742,7 @@ declare namespace Cypress {
screenshotsFolder: string | false
/**
* Path to file to load before test files load. This file is compiled and bundled. (Pass false to disable)
* @default "cypress/support/index.js"
* @default "cypress/support/{e2e|component}.js"
*/
supportFile: string | false
/**
@@ -5476,7 +5476,7 @@ declare namespace Cypress {
```
// likely want to do this in a support file
// so it's applied to all spec files
// cypress/support/index.js
// cypress/support/{e2e|component}.js
Cypress.on('uncaught:exception', (err, runnable) => {
// returning false here prevents Cypress from

View File

@@ -14,7 +14,7 @@ Ensure you have a version of Cypress > 7.
Add the following to your support file:
```js
// cypress/support/index.js
// cypress/support/component.js
// core-js 3.*
require('core-js/es/reflect');
// core-js 2.*
@@ -159,7 +159,7 @@ module.exports = {
- Then add the code below to your supportFile and pluginsFile
```javascript
// cypress/support/index.js
// cypress/support/component.js
import '@cypress/code-coverage/support';
// cypress/plugins/index.js
module.exports = (on, config) => {

View File

@@ -8,6 +8,7 @@ export default defineConfig({
'projectId': 'nf7zag',
'component': {
'specPattern': 'src/app/**/*cy-spec.ts',
'supportFile': 'cypress/support/component.ts',
setupNodeEvents (on, config) {
return require('./cypress/plugins')(on, config)
},

View File

@@ -40,6 +40,6 @@ module.exports = (on, config) => {
`
exports['Injected overridden webpack template support/index.js'] = `
exports['Injected overridden webpack template support/component.js'] = `
import "./commands.js";
`

View File

@@ -71,7 +71,7 @@ describe('init component tests script', () => {
)
const supportFile = fs.readFileSync(
path.join(e2eTestOutputPath, 'cypress', 'support', 'index.js'),
path.join(e2eTestOutputPath, 'cypress', 'support', 'component.js'),
{ encoding: 'utf-8' },
)
@@ -81,9 +81,9 @@ describe('init component tests script', () => {
}
snapshot(
`${name} support/index.js`,
`${name} support/component.js`,
fs.readFileSync(
path.join(e2eTestOutputPath, 'cypress', 'support', 'index.js'),
path.join(e2eTestOutputPath, 'cypress', 'support', 'component.js'),
{ encoding: 'utf-8' },
),
)
@@ -92,7 +92,7 @@ describe('init component tests script', () => {
it('determines more presumable configuration to suggest', async () => {
createTempFiles({
'/cypress.config.ts': 'export default {}',
'/cypress/support/index.js': '',
'/cypress/support/component.js': '',
'/cypress/plugins/index.js': 'module.exports = (on, config) => {}',
// For next.js user will have babel config, but we want to suggest to use the closest config for the application code
'/babel.config.js': 'module.exports = { }',
@@ -115,7 +115,7 @@ describe('init component tests script', () => {
it('automatically suggests to the user which config to use', async () => {
createTempFiles({
'/cypress.config.ts': 'export default {}',
'/cypress/support/index.js': 'import "./commands.js";',
'/cypress/support/component.js': 'import "./commands.js";',
'/cypress/plugins/index.js': 'module.exports = () => {}',
'/package.json': JSON.stringify({
dependencies: {

View File

@@ -2,7 +2,7 @@ import { defineConfig } from 'cypress'
export default defineConfig({
'integrationFolder': '<%= root%>cypress/integration',
'supportFile': '<%= root%>cypress/support/index.ts',
'supportFile': '<%= root%>cypress/support/component.ts',
'videosFolder': '<%= root%>cypress/videos',
'screenshotsFolder': '<%= root%>cypress/screenshots',
'pluginsFile': '<%= root%>cypress/plugins/index.ts',

View File

@@ -1,5 +1,5 @@
// ***********************************************************
// This example support/index.js is processed and
// This example support/component.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and

View File

@@ -32,7 +32,7 @@ describe('@cypress/schematic: ng-add', () => {
})
it('should create cypress files', async () => {
const files = ['cypress/integration/spec.ts', 'cypress/plugins/index.ts', 'cypress/support/commands.ts', 'cypress/support/index.ts', 'cypress/tsconfig.json', 'cypress.config.ts']
const files = ['cypress/integration/spec.ts', 'cypress/plugins/index.ts', 'cypress/support/commands.ts', 'cypress/tsconfig.json', 'cypress.config.ts']
const homePath = '/projects/sandbox/'
return schematicRunner.runSchematicAsync('ng-add', {}, appTree).toPromise().then((tree) => {

View File

@@ -1,5 +1,5 @@
// ***********************************************************
// This example support/index.js is processed and
// This example support/component.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and

View File

@@ -0,0 +1,20 @@
// ***********************************************************
// This example support/component.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')

View File

@@ -5,6 +5,7 @@ export default defineConfig({
'projectId': 'jq5xpp',
'component': {
'specPattern': 'src/**/*.spec.{js,ts,jsx,tsx}',
'supportFile': 'cypress/support/component.ts',
devServer (cypressConfig) {
const findReactScriptsWebpackConfig = require('@cypress/react/plugins/react-scripts/findReactScriptsWebpackConfig')
const { startDevServer } = require('@cypress/webpack-dev-server')

View File

@@ -3,6 +3,7 @@ module.exports = {
'viewportWidth': 500,
'viewportHeight': 800,
'component': {
'supportFile': 'cypress/support/component.ts',
'specPattern': 'src/**/*cy-spec.tsx',
setupNodeEvents (on, config) {
const devServer = require('@cypress/react/plugins/react-scripts')

View File

@@ -6,7 +6,7 @@ module.exports = {
'env': {
'coverage': true,
},
config: {
component: {
'specPattern': 'src/**/*cy-spec.js',
setupNodeEvents (on, config) {
// load file devServer that comes with this plugin

View File

@@ -5,6 +5,7 @@ export default defineConfig({
'video': false,
'fixturesFolder': false,
'component': {
'supportFile': 'cypress/support.js',
'specPattern': 'cypress/components/**/*.spec.*',
devServer (cypressConfig) {
const path = require('path')

View File

@@ -9,6 +9,7 @@ export default defineConfig({
'experimentalFetchPolyfill': true,
'e2e': {
'specPattern': 'cypress/integration/**/*',
'supportFile': false,
},
'component': {
'specPattern': 'cypress/component/**/*spec.{js,ts,tsx}',

View File

@@ -19,7 +19,7 @@ module.exports = (on, config) => {
}
```
3. Include the support file from your project's `cypress/support/index.js` file
3. Include the support file from your project's `cypress/support/component.js` file
```js
import '@cypress/vue/dist/support'

View File

@@ -33,7 +33,7 @@ You should obtain
`yarn add -D babel-plugin-istanbul @cypress/code-coverage`
- Add the istanbul plugin to your `babel.config.js`
- Install `@cypress/code-coverage/task` in `cypress/plugins/index.js`
- Install `@cypress/code-coverage/support` in `cypress/support/index.js`
- Install `@cypress/code-coverage/support` in `cypress/support/component.js`
- Enjoy
**NOTE** Code coverage has been added to the vue-cli example. If you are using `vue-cli`, use the same steps described above to install coverage.

View File

@@ -1,5 +1,5 @@
// ***********************************************************
// This example support/index.js is processed and
// This example support/e2e.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and

View File

@@ -1,6 +1,8 @@
module.exports = {
'baseUrl': 'http://localhost:3000',
'fixturesFolder': false,
'supportFile': false,
'viewportWidth': 600,
'e2e': {
'supportFile': false,
},
}

View File

@@ -1,7 +1,7 @@
module.exports = {
'fixturesFolder': false,
'supportFile': false,
'e2e': {
'supportFile': false,
'specPattern': 'cypress/integration/**/*',
setupNodeEvents (on, config) {
const webpackPreprocessor = require('../..')

View File

@@ -2,8 +2,8 @@ import { defineConfig } from 'cypress'
export default defineConfig({
'fixturesFolder': false,
'supportFile': false,
'e2e': {
'supportFile': false,
async setupNodeEvents (on, config) {
const webpackPreprocessor = await import('../..')

View File

@@ -1,6 +1,6 @@
import { registerMountFn } from '@packages/frontend-shared/cypress/support/common'
// ***********************************************************
// This example support/index.js is processed and
// This example support/index.ts is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and

View File

@@ -57,7 +57,7 @@ exports['src/index .getDefaultValues returns list of public config keys 1'] = {
"screenshotsFolder": "cypress/screenshots",
"slowTestThreshold": 10000,
"scrollBehavior": "top",
"supportFile": "cypress/support",
"supportFile": "cypress/support/e2e.js",
"supportFolder": false,
"taskTimeout": 60000,
"trashAssetsBeforeRuns": true,

View File

@@ -1,7 +1,7 @@
const _ = require('lodash')
const debug = require('debug')('cypress:config:validator')
const { options, breakingOptions } = require('./options')
const { options, breakingOptions, breakingRootOptions } = require('./options')
const dashesOrUnderscoresRe = /^(_-)+/
@@ -24,6 +24,40 @@ const testConfigOverrideOptions = createIndex(options, 'name', 'canUpdateDuringT
const issuedWarnings = new Set()
const validateNoBreakingOptions = (breakingCfgOptions, cfg, onWarning, onErr) => {
breakingCfgOptions.forEach(({ name, errorKey, newName, isWarning, value }) => {
if (cfg.hasOwnProperty(name)) {
if (value && cfg[name] !== value) {
// Bail if a value is specified but the config does not have that value.
return
}
if (isWarning) {
if (issuedWarnings.has(errorKey)) {
return
}
// avoid re-issuing the same warning more than once
issuedWarnings.add(errorKey)
return onWarning(errorKey, {
name,
newName,
value,
configFile: cfg.configFile,
})
}
return onErr(errorKey, {
name,
newName,
value,
configFile: cfg.configFile,
})
}
})
}
module.exports = {
allowed: (obj = {}) => {
const propertyNames = publicConfigKeys.concat(breakingKeys)
@@ -78,38 +112,12 @@ module.exports = {
})
},
validateNoBreakingConfigRoot: (cfg, onWarning, onErr) => {
return validateNoBreakingOptions(breakingRootOptions, cfg, onWarning, onErr)
},
validateNoBreakingConfig: (cfg, onWarning, onErr) => {
breakingOptions.forEach(({ name, errorKey, newName, isWarning, value }) => {
if (cfg.hasOwnProperty(name)) {
if (value && cfg[name] !== value) {
// Bail if a value is specified but the config does not have that value.
return
}
if (isWarning) {
if (issuedWarnings.has(errorKey)) {
return
}
// avoid re-issuing the same warning more than once
issuedWarnings.add(errorKey)
return onWarning(errorKey, {
name,
newName,
value,
configFile: cfg.configFile,
})
}
return onErr(errorKey, {
name,
newName,
value,
configFile: cfg.configFile,
})
}
})
return validateNoBreakingOptions(breakingOptions, cfg, onWarning, onErr)
},
validateNoReadOnlyConfig: (config, onErr) => {

View File

@@ -299,7 +299,7 @@ const resolvedOptions: Array<ResolvedConfigOption> = [
canUpdateDuringTestTime: true,
}, {
name: 'supportFile',
defaultValue: 'cypress/support',
defaultValue: (options: Record<string, any> = {}) => options.testingType === 'component' ? 'cypress/support/component.js' : 'cypress/support/e2e.js',
validation: validate.isStringOrFalse,
isFolder: true,
canUpdateDuringTestTime: false,
@@ -512,3 +512,11 @@ export const breakingOptions: Array<BreakingOption> = [
isWarning: true,
},
]
export const breakingRootOptions: Array<BreakingOption> = [
{
name: 'supportFile',
errorKey: 'SUPPORT_FILE_ROOT_NOT_SUPPORTED',
isWarning: false,
},
]

View File

@@ -52,6 +52,7 @@ export interface InternalDataContextOptions {
export interface ErrorApiShape {
error: (type: string, ...args: any) => Error & { type: string, details: string, code?: string, isCypressErr: boolean}
message: (type: string, ...args: any) => string
warning: (type: string, ...args: any) => null
}
export interface DataContextConfig {
@@ -449,6 +450,10 @@ export class DataContext {
return this._apis.errorApi.error(type, ...args)
}
warning (type: string, ...args: any[]) {
return this._apis.errorApi.error(type, ...args)
}
private async initializeOpenMode () {
if (IS_DEV_ENV && !process.env.CYPRESS_INTERNAL_E2E_TESTING_SELF) {
this.actions.dev.watchForRelaunch()

View File

@@ -78,9 +78,10 @@ export class ProjectActions {
}
// Temporary: remove after other refactor lands
setCurrentProjectForTestSetup (projectRoot: string) {
setCurrentProjectAndTestingTypeForTestSetup (projectRoot: string) {
this.ctx.lifecycleManager.clearCurrentProject()
this.ctx.lifecycleManager.setCurrentProject(projectRoot)
this.ctx.lifecycleManager.setCurrentTestingType('e2e')
// @ts-expect-error - we are setting this as a convenience for our integration tests
this.ctx._modeOptions = {}
}

View File

@@ -123,13 +123,15 @@ export class WizardActions {
])
}
private async scaffoldSupport (directory: 'e2e' | 'component', language: CodeLanguageEnum): Promise<NexusGenObjects['ScaffoldedFile']> {
const supportFile = path.join(this.projectRoot, `cypress/${directory}/support.${language}`)
private async scaffoldSupport (fileName: 'e2e' | 'component', language: CodeLanguageEnum): Promise<NexusGenObjects['ScaffoldedFile']> {
const supportFile = path.join(this.projectRoot, `cypress/support/${fileName}.${language}`)
const supportDir = path.dirname(supportFile)
await this.ensureDir(directory)
await this.ctx.fs.writeFile(supportFile, dedent`
// @ts-ignore
await this.ctx.fs.mkdir(supportDir, { recursive: true })
await this.scaffoldFile(supportFile, dedent`
// TODO: source the example support file
`)
`, 'Scaffold default support file')
return {
status: 'valid',
@@ -192,7 +194,10 @@ export class WizardActions {
codeBlocks.push(lang === 'ts' ? 'import { defineConfig } from "cypress"' : `const { defineConfig } = require("cypress")`)
codeBlocks.push(lang === 'ts' ? `export default defineConfig({` : `module.exports = defineConfig({`)
codeBlocks.push(E2E_SCAFFOLD_BODY)
codeBlocks.push(E2E_SCAFFOLD_BODY({
lang,
}))
codeBlocks.push('})\n')
return codeBlocks.join('\n')
@@ -311,16 +316,23 @@ export class WizardActions {
}
}
const E2E_SCAFFOLD_BODY = `
e2e: {
specPattern: 'cypress/e2e/**/*.cy.{js,ts}',
viewportHeight: 660,
viewportWidth: 1000,
setupNodeEvents(on, config) {
//
},
}
`
interface E2eScaffoldOpts {
lang: CodeLanguageEnum
}
const E2E_SCAFFOLD_BODY = (opts: E2eScaffoldOpts) => {
return `
e2e: {
supportFile: 'cypress/support/e2e.${opts.lang}',
specPattern: 'cypress/e2e/**/*.cy.{js,ts}',
viewportHeight: 660,
viewportWidth: 1000,
setupNodeEvents(on, config) {
//
},
}
`
}
interface ComponentScaffoldOpts {
lang: CodeLanguageEnum
@@ -332,6 +344,7 @@ interface ComponentScaffoldOpts {
const COMPONENT_SCAFFOLD_BODY = (opts: ComponentScaffoldOpts) => {
return `
component: {
supportFile: 'cypress/support/component.${opts.lang}',
specPattern: 'cypress/**/*.cy.{js,jsx,ts,tsx}',
devServer: import('${opts.requirePath}'),
devServerConfig: ${opts.configOptionsString}

View File

@@ -49,6 +49,7 @@ export interface InjectedConfigApi {
allowedConfig(config: Cypress.ConfigOptions): Cypress.ConfigOptions
updateWithPluginValues(config: FullConfig, modifiedConfig: Partial<Cypress.ConfigOptions>): FullConfig
setupFullConfigWithDefaults(config: SetupFullConfigOptions): Promise<FullConfig>
validateRootConfigBreakingChanges<T extends Cypress.ConfigOptions>(config: Partial<T>, onWarning: (warningMsg: string) => void, onErr: (errMsg: string) => never): T
}
type State<S, V = undefined> = V extends undefined ? {state: S, value?: V} : {state: S, value: V}
@@ -407,6 +408,8 @@ export class ProjectLifecycleManager {
}
private async buildBaseFullConfig (configFileContents: Cypress.ConfigOptions, envFile: Cypress.ConfigOptions, options: Partial<AllModeOptions>, withBrowsers = true) {
this.validateConfigRoot(configFileContents)
if (this._currentTestingType) {
const testingTypeOverrides = configFileContents[this._currentTestingType] ?? {}
@@ -532,6 +535,18 @@ export class ProjectLifecycleManager {
return promise.then((v) => v.initialConfig)
}
private validateConfigRoot (config: Cypress.ConfigOptions) {
return this.ctx._apis.configApi.validateRootConfigBreakingChanges(
config,
(warning, ...args) => {
return this.ctx.warning(warning, ...args)
},
(err, ...args) => {
throw this.ctx.error(err, ...args)
},
)
}
private validateConfigFile (file: string | false, config: Cypress.ConfigOptions) {
this.ctx._apis.configApi.validateConfig(config, (errMsg) => {
if (!file) {
@@ -740,15 +755,28 @@ export class ProjectLifecycleManager {
}
private async setupNodeEvents (): Promise<SetupNodeEventsReply> {
const config = await this.getFullInitialConfig()
assert(this._eventsIpc)
const ipc = this._eventsIpc
let config
try {
config = await this.getFullInitialConfig()
} catch (err) {
debug(`catch %o`, err)
this._cleanupIpc(ipc)
this._eventsIpcResult = { state: 'errored', value: err }
this._pendingInitialize?.reject(err)
this.ctx.emitter.toLaunchpad()
return Promise.reject(err)
}
assert(config)
assert(this._currentTestingType)
this._registeredEventsTarget = this._currentTestingType
const ipc = this._eventsIpc
for (const handler of this._handlers) {
handler(ipc)
}

View File

@@ -1,5 +1,5 @@
// ***********************************************************
// This example support/index.js is processed and
// This example support/e2e.js is processed and
// loaded automatically before your other test files.
//
// This is a great place to put global configuration and

View File

@@ -2,7 +2,6 @@ declare const example: {
getPathToExamples(): Promise<string[]>;
getPathToIntegration(): string;
getPathToPlugins(): string;
getPathToSupportFiles(): Promise<string[]>;
getPathToTsConfig(): string;
getPathToFixture(): string;
}

View File

@@ -28,19 +28,6 @@ module.exports = {
return path.resolve(__dirname, '..', 'cypress', 'plugins', 'index.js')
},
getPathToSupportFiles() {
return glob(
path.join(
__dirname,
'..',
'cypress',
'support',
'**',
'*'
)
)
},
getPathToTsConfig() {
return path.resolve(__dirname, '..', 'cypress', 'tsconfig.json')
},

View File

@@ -28,7 +28,7 @@
"devDependencies": {
"chai": "3.5.0",
"cross-env": "6.0.3",
"cypress-example-kitchensink": "cypress-io/cypress-example-kitchensink#feat/use-config-file",
"cypress-example-kitchensink": "cypress-io/cypress-example-kitchensink#feat/use-supportFiles",
"gulp": "4.0.2",
"gulp-clean": "0.4.0",
"gulp-gh-pages": "0.6.0-6",

View File

@@ -18,6 +18,7 @@ export default defineConfig({
},
'component': {
'specPattern': 'src/**/*.spec.{js,ts,tsx,jsx}',
'supportFile': 'cypress/support/component.ts',
devServer (cypressConfig, devServerConfig) {
const { startDevServer } = require('@cypress/vite-dev-server')

View File

@@ -27,7 +27,7 @@ describe('Config files error handling', () => {
.should('not.contain.text', 'Something went wrong')
})
it('it shows the upgrade screen if there is a legacy config file', () => {
it('shows the upgrade screen if there is a legacy config file', () => {
cy.openProject('pristine-with-config-file')
cy.withCtx(async (ctx) => {
await ctx.actions.file.writeFileInProject('cypress.json', '{}')
@@ -42,7 +42,7 @@ describe('Config files error handling', () => {
cy.get('body').should('contain.text', defaultMessages.migration.wizard.description)
})
it('it handles config files with legacy config file in same project', () => {
it('handles config files with legacy config file in same project', () => {
cy.openProject('pristine-with-config-file')
cy.withCtx(async (ctx) => {
await ctx.actions.file.writeFileInProject('cypress.json', '{}')
@@ -59,4 +59,36 @@ describe('Config files error handling', () => {
cy.get('body').should('not.contain.text', 'Cypress no longer supports')
})
it('handles deprecated config fields', () => {
cy.openProject('pristine')
cy.withCtx(async (ctx) => {
await ctx.actions.file.writeFileInProject('cypress.config.js', 'module.exports = { experimentalComponentTesting: true }')
})
cy.openProject('pristine')
cy.visitLaunchpad()
cy.get('[data-cy-testingType=e2e]').click()
cy.get('body').should('contain.text', 'Something went wrong')
cy.get('body').should('contain.text', 'It looks like there\'s some issues that need to be resolved before we continue.')
cy.findByText('Error Loading Config')
})
it('handles deprecated fields on root config', () => {
cy.openProject('pristine')
cy.withCtx(async (ctx) => {
await ctx.actions.file.writeFileInProject('cypress.config.js', `module.exports = { supportFile: 'cypress/support.ts' }`)
})
cy.openProject('pristine')
cy.visitLaunchpad()
cy.get('[data-cy-testingType=e2e]').click()
cy.get('body').should('contain.text', 'Something went wrong')
cy.get('body').should('contain.text', 'It looks like there\'s some issues that need to be resolved before we continue.')
cy.findByText('Error Loading Config')
})
})

View File

@@ -100,10 +100,12 @@ describe('Launchpad: Onboarding Flow', () => {
const { defineConfig } = require("cypress")
module.exports = defineConfig({
component: {
supportFile: 'cypress/support/component.js',
devServer: require('@cypress/webpack-dev-server'),
devServerConfig: {}
},
e2e: {
supportFile: 'cypress/support/e2e.js',
specPattern: 'cypress/e2e/**/*.cy.{js,ts}',
viewportHeight: 660,
viewportWidth: 1000,

View File

@@ -13,7 +13,7 @@ describe('Plugin error handling', () => {
.and('contain.text', 'The function exported by the plugins file threw an error')
cy.withCtx(async (ctx) => {
await ctx.actions.file.writeFileInProject('cypress.config.js', `module.exports = { e2e: { baseUrl: 'https://cypress.com' } }`)
await ctx.actions.file.writeFileInProject('cypress.config.js', `module.exports = { e2e: { baseUrl: 'https://cypress.com', supportFile: false } }`)
})
cy.get('body')

View File

@@ -14,7 +14,8 @@ export default defineConfig({
'openMode': 0,
},
'e2e': {
specPattern: 'cypress/integration/**/*.{js,ts}',
'supportFile': 'cypress/support/e2e.ts',
'specPattern': 'cypress/integration/**/*.{js,ts}',
setupNodeEvents (on, config) {
const express = require('express')
@@ -22,7 +23,7 @@ export default defineConfig({
return config
},
viewportHeight: 660,
viewportWidth: 1000,
'viewportHeight': 660,
'viewportWidth': 1000,
},
})

View File

@@ -1,5 +1,5 @@
// ***********************************************************
// This example support/index.js is processed and
// This example support/component.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and

View File

@@ -87,7 +87,10 @@ exports['lib/scaffold .fileTree returns tree-like structure of scaffolded 1'] =
"name": "commands.js"
},
{
"name": "index.js"
"name": "component.js"
},
{
"name": "e2e.js"
}
]
}
@@ -184,7 +187,10 @@ exports['lib/scaffold .fileTree leaves out integration tests if using component
"name": "commands.js"
},
{
"name": "index.js"
"name": "component.js"
},
{
"name": "e2e.js"
}
]
}
@@ -273,7 +279,10 @@ exports['lib/scaffold .fileTree leaves out fixtures if configured to false 1'] =
"name": "commands.js"
},
{
"name": "index.js"
"name": "component.js"
},
{
"name": "e2e.js"
}
]
}
@@ -367,59 +376,6 @@ exports['lib/scaffold .fileTree leaves out support if configured to false 1'] =
}
]
exports['lib/scaffold .support creates supportFolder and commands.js and index.js when supportFolder does not exist 1'] = `
// ***********************************************
// This example commands.js shows you how to
// create various custom commands and overwrite
// existing commands.
//
// For more comprehensive examples of custom
// commands please read more here:
// https://on.cypress.io/custom-commands
// ***********************************************
//
//
// -- This is a parent command --
// Cypress.Commands.add('login', (email, password) => { ... })
//
//
// -- This is a child command --
// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... })
//
//
// -- This is a dual command --
// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... })
//
//
// -- This will overwrite an existing command --
// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... })
`
exports['lib/scaffold .support creates supportFolder and commands.js and index.js when supportFolder does not exist 2'] = `
// ***********************************************************
// This example support/index.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and
// behavior that modifies Cypress.
//
// You can change the location of this file or turn off
// automatically serving support files with the
// 'supportFile' configuration option.
//
// You can read more here:
// https://on.cypress.io/configuration
// ***********************************************************
// Import commands.js using ES2015 syntax:
import './commands'
// Alternatively you can use CommonJS syntax:
// require('./commands')
`
exports['lib/scaffold .fileTree leaves out plugins if configured to false 1'] = [
{
"name": "tests",
@@ -509,7 +465,10 @@ exports['lib/scaffold .fileTree leaves out plugins if configured to false 1'] =
"name": "commands.js"
},
{
"name": "index.js"
"name": "component.js"
},
{
"name": "e2e.js"
}
]
}

View File

@@ -46,59 +46,26 @@ export const utils = {
return require.resolve(name)
},
// tries to find support or plugins file
// returns:
// false - if the file should not be set
// string - found filename
// null - if there is an error finding the file
discoverModuleFile (options) {
debug('discover module file %o', options)
const { filename, isDefault } = options
if (!isDefault) {
// they have it explicitly set, so it should be there
return fs.pathExists(filename)
.then((found) => {
if (found) {
debug('file exists, assuming it will load')
return filename
}
debug('could not find %o', { filename })
return null
})
}
// support or plugins file doesn't exist on disk?
debug(`support file is default, check if ${path.dirname(filename)} exists`)
const { filename } = options
// they have it explicitly set, so it should be there
return fs.pathExists(filename)
.then((found) => {
if (found) {
debug('is there index.ts in the support or plugins folder %s?', filename)
const tsFilename = path.join(filename, 'index.ts')
debug('file exists, assuming it will load')
return fs.pathExists(tsFilename)
.then((foundTsFile) => {
if (foundTsFile) {
debug('found index TS file %s', tsFilename)
return tsFilename
}
// if the directory exists, set it to false so it's ignored
debug('setting support or plugins file to false')
return false
})
return filename
}
debug('folder does not exist, set to default index.js')
debug('could not find %o', { filename })
// otherwise, set it up to be scaffolded later
return path.join(filename, 'index.js')
return null
})
},
}
@@ -426,11 +393,8 @@ export function setSupportFileAndFolder (obj, defaults) {
}).catch({ code: 'MODULE_NOT_FOUND' }, () => {
debug('support JS module %s does not load', sf)
const loadingDefaultSupportFile = sf === path.resolve(obj.projectRoot, defaults.supportFile)
return utils.discoverModuleFile({
filename: sf,
isDefault: loadingDefaultSupportFile,
projectRoot: obj.projectRoot,
})
.then((result) => {

View File

@@ -1039,6 +1039,11 @@ const getMsgByType = function (type, ...args) {
Deprecation Warning: ${chalk.yellow(`\`${arg1.name}\``)} is currently set to ${chalk.yellow(`\`${arg1.value}\``)} in the ${chalk.yellow(`\`${arg1.configFile}\``)} configuration file. As of Cypress version \`9.0.0\` the default behavior of ${chalk.yellow(`\`${arg1.name}\``)} has changed to always use the version of Node used to start cypress via the cli. When ${chalk.yellow(`\`${arg1.name}\``)} is set to ${chalk.yellow(`\`${arg1.value}\``)}, Cypress will use the version of Node bundled with electron. This can cause problems running certain plugins or integrations.
As the ${chalk.yellow(`\`${arg1.name}\``)} configuration option will be removed in a future release, it is recommended to remove the ${chalk.yellow(`\`${arg1.name}\``)} configuration option from ${chalk.yellow(`\`${arg1.configFile}\``)}.
`
case 'SUPPORT_FILE_ROOT_NOT_SUPPORTED':
return stripIndent`\
The ${chalk.yellow(`\`supportFile\``)} configuration option was removed from the root in Cypress version \`10.0.0\`. Please update this option under each testing type property.
https://on.cypress.io/migration-guide`
default:
}
}

View File

@@ -54,6 +54,7 @@ export function makeDataContext (options: MakeDataContextOptions): DataContext {
errorApi: {
error: errors.get,
message: errors.getMsgByType,
warning: errors.warning,
},
configApi: {
getServerPluginHandlers: plugins.getServerPluginHandlers,
@@ -62,6 +63,7 @@ export function makeDataContext (options: MakeDataContextOptions): DataContext {
validateConfig: configUtils.validate,
updateWithPluginValues: config.updateWithPluginValues,
setupFullConfigWithDefaults: config.setupFullConfigWithDefaults,
validateRootConfigBreakingChanges: configUtils.validateNoBreakingConfigRoot,
},
appApi: {
appData,

View File

@@ -18,7 +18,6 @@ import errors from './errors'
import Reporter from './reporter'
import runEvents from './plugins/run_events'
import * as savedState from './saved_state'
import scaffold from './scaffold'
import { ServerE2E } from './server-e2e'
import system from './util/system'
import { ensureProp } from './util/class-helpers'
@@ -246,10 +245,7 @@ export class ProjectBase<TServer extends Server> extends EE {
projectRoot: this.projectRoot,
})
await Promise.all([
this.scaffold(cfg),
this.saveState(stateToSave),
])
await this.saveState(stateToSave)
await Promise.all([
checkSupportFile({ configFile: cfg.configFile, supportFile: cfg.supportFile }),
@@ -530,6 +526,7 @@ export class ProjectBase<TServer extends Server> extends EE {
}
async initializeConfig (): Promise<Cfg> {
this.ctx.lifecycleManager.setCurrentTestingType(this.testingType)
let theCfg: Cfg = await this.ctx.lifecycleManager.getFullInitialConfig() as Cfg // ?? types are definitely wrong here I think
theCfg = this.testingType === 'e2e'
@@ -596,26 +593,6 @@ export class ProjectBase<TServer extends Server> extends EE {
fs.writeFileSync(path.resolve(this.projectRoot, configFilename), code)
}
scaffold (cfg: Cfg) {
debug('scaffolding project %s', this.projectRoot)
const scaffolds = []
const push = scaffolds.push.bind(scaffolds) as any
// TODO: we are currently always scaffolding support
// even when headlessly - this is due to a major breaking
// change of 0.18.0
// we can later force this not to always happen when most
// of our users go beyond 0.18.0
//
// ensure support dir is created
// and example support file if dir doesnt exist
push(scaffold.support(cfg.supportFolder, cfg))
return Promise.all(scaffolds)
}
// These methods are not related to start server/sockets/runners
async getProjectId () {

View File

@@ -109,28 +109,6 @@ module.exports = {
})
},
support (folder, config) {
debug(`support folder ${folder}, support file ${config.supportFile}`)
// skip if user has explicitly set supportFile
if (!config.supportFile || !isDefault(config, 'supportFile')) {
return Promise.resolve()
}
return this.verifyScaffolding(folder, () => {
debug(`copying commands.js and index.js to ${folder}`)
return cypressEx.getPathToSupportFiles()
.then((supportFiles) => {
return Promise.all(
supportFiles.map((supportFilePath) => {
return this._copy(supportFilePath, folder)
}),
)
})
})
},
plugins (folder, config) {
debug(`plugins folder ${folder}`)
// skip if user has explicitly set pluginsFile
@@ -232,13 +210,6 @@ module.exports = {
])
}
if (config.supportFolder && (config.supportFile !== false)) {
files = files.concat([
getFilePath(config.supportFolder, 'commands.js'),
getFilePath(config.supportFolder, 'index.js'),
])
}
if (config.pluginsFile) {
files = files.concat([
getFilePath(path.dirname(config.pluginsFile), 'index.js'),

View File

@@ -427,7 +427,7 @@ describe('lib/cypress', () => {
// NOTE: We no longer do this in the new flow
it.skip('scaffolds out integration and example specs if they do not exist when not runMode', function () {
ctx.actions.project.setCurrentProjectForTestSetup(this.pristineWithConfigPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.pristineWithConfigPath)
return config.get(this.pristineWithConfigPath)
.then((cfg) => {
@@ -479,28 +479,30 @@ describe('lib/cypress', () => {
it.skip('scaffolds out support + files if they do not exist', function () {
const supportFolder = path.join(this.pristineWithConfigPath, 'cypress/support')
ctx.actions.project.setCurrentProjectForTestSetup(this.pristineWithConfigPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.pristineWithConfigPath)
return config.get(this.pristineWithConfigPath)
.then(() => {
return fs.rmdir(supportFolder, { recursive: true })
}).then(() => {
return fs.statAsync(supportFolder)
.then(() => {
throw new Error('supportFolder should not exist!')
}).catch({ code: 'ENOENT' }, () => {
return cypress.start([`--run-project=${this.pristineWithConfigPath}`, '--no-run-mode'])
}).then(() => {
return fs.statAsync(supportFolder)
}).then(() => {
return fs.statAsync(path.join(supportFolder, 'index.js'))
}).then(() => {
return fs.statAsync(path.join(supportFolder, 'commands.js'))
})
})
.then(() => {
throw new Error('supportFolder should not exist!')
}).catch({ code: 'ENOENT' }, () => {
return cypress.start([`--run-project=${this.pristineWithConfigPath}`])
}).then(() => {
return fs.statAsync(supportFolder)
}).then(() => {
throw new Error('supportFolder should not exist!')
}).catch((err) => {
expect(err.code).eq('ENOENT')
})
})
// NOTE: Removal of fixtures is not supported in new flow
it.skip('removes fixtures when they exist and fixturesFolder is false', function (done) {
ctx.actions.project.setCurrentProjectForTestSetup(this.idsPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.idsPath)
config.get(this.idsPath)
.then((cfg) => {
@@ -560,7 +562,7 @@ describe('lib/cypress', () => {
it('can change the reporter with cypress.config.js', function () {
sinon.spy(Reporter, 'create')
ctx.actions.project.setCurrentProjectForTestSetup(this.idsPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.idsPath)
return config.get(this.idsPath)
.then((cfg) => {
@@ -628,7 +630,7 @@ describe('lib/cypress', () => {
})
it(`logs error when supportFile doesn't exist`, function () {
return settings.writeForTesting(this.idsPath, { supportFile: '/does/not/exist' })
return settings.writeForTesting(this.idsPath, { e2e: { supportFile: '/does/not/exist' } })
.then(() => {
return cypress.start([`--run-project=${this.idsPath}`])
}).then(() => {
@@ -799,7 +801,7 @@ describe('lib/cypress', () => {
return fs.mkdirAsync(permissionsPath)
.then(() => {
return fs.outputFileAsync(cypressConfig, 'module.exports = {}')
return fs.outputFileAsync(cypressConfig, 'module.exports = { e2e: { supportFile: false } }')
}).then(() => {
// read only
return fs.chmodAsync(permissionsPath, '555')
@@ -1649,15 +1651,17 @@ describe('lib/cypress', () => {
process.env.CYPRESS_responseTimeout = '5555'
process.env.CYPRESS_watch_for_file_changes = 'false'
ctx.actions.project.setCurrentProjectForTestSetup(this.todosPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.todosPath)
return user.set({ name: 'brian', authToken: 'auth-token-123' })
.then(() => settings.read(this.todosPath))
.then(() => ctx.lifecycleManager.getFullInitialConfig())
.then((json) => {
// this should be overriden by the env argument
json.baseUrl = 'http://localhost:8080'
return settings.writeForTesting(this.todosPath, json)
const { supportFile, ...rest } = json
return settings.writeForTesting(this.todosPath, rest)
}).then(() => {
// TODO(tim): this shouldn't be needed when we refactor the ctx setup
process.env.LAUNCHPAD = '0'

View File

@@ -103,7 +103,7 @@ describe('Routes', () => {
obj.projectRoot = Fixtures.projectPath('e2e')
}
ctx.actions.project.setCurrentProjectForTestSetup(obj.projectRoot)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(obj.projectRoot)
// get all the config defaults
// and allow us to override them
@@ -573,6 +573,9 @@ describe('Routes', () => {
return this.setup({
projectRoot: Fixtures.projectPath('failures'),
config: {
supportFile: false,
},
})
})
@@ -801,6 +804,7 @@ describe('Routes', () => {
config: {
integrationFolder: 'tests',
fixturesFolder: 'tests/_fixtures',
supportFile: false,
},
})
})
@@ -3108,6 +3112,7 @@ describe('Routes', () => {
config: {
fileServerFolder: 'dev',
integrationFolder: 'my-tests',
supportFile: false,
},
})
.then(() => {

View File

@@ -135,6 +135,7 @@ describe('Server', () => {
config: {
port: 2000,
fileServerFolder: 'dev',
supportFile: false,
},
})
})
@@ -332,6 +333,7 @@ describe('Server', () => {
projectRoot: '/foo/bar/',
config: {
port: 2000,
supportFile: false,
},
})
})
@@ -918,6 +920,7 @@ describe('Server', () => {
config: {
port: 2000,
fileServerFolder: 'dev',
supportFile: false,
},
})
})

View File

@@ -32,7 +32,7 @@ describe('Web Sockets', () => {
this.idsPath = Fixtures.projectPath('ids')
ctx.actions.project.setCurrentProjectForTestSetup(this.idsPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.idsPath)
return config.get(this.idsPath, { port: cyPort })
.then((cfg) => {

View File

@@ -349,6 +349,9 @@ describe('Proxy Performance', function () {
Config.setupFullConfigWithDefaults({
projectRoot: '/tmp/a',
config: {
supportFile: false,
},
}).then((config) => {
config.port = CY_PROXY_PORT

View File

@@ -13,7 +13,7 @@
if (!Cypress) {
throw new Error("Tests cannot run without a reference to Cypress!");
}
return Cypress.onSpecWindow(window, [{"absolute":"/<path-to-project>/ids/cypress/support/index.js","relative":"cypress/support/index.js","relativeUrl":"/__cypress/tests?p=cypress/support/index.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/bar.js","relative":"cypress/integration/bar.js","relativeUrl":"/__cypress/tests?p=cypress/integration/bar.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/baz.js","relative":"cypress/integration/baz.js","relativeUrl":"/__cypress/tests?p=cypress/integration/baz.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/dom.jsx","relative":"cypress/integration/dom.jsx","relativeUrl":"/__cypress/tests?p=cypress/integration/dom.jsx"},{"absolute":"/<path-to-project>/ids/cypress/integration/es6.js","relative":"cypress/integration/es6.js","relativeUrl":"/__cypress/tests?p=cypress/integration/es6.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/foo.coffee","relative":"cypress/integration/foo.coffee","relativeUrl":"/__cypress/tests?p=cypress/integration/foo.coffee"},{"absolute":"/<path-to-project>/ids/cypress/integration/nested/tmp.js","relative":"cypress/integration/nested/tmp.js","relativeUrl":"/__cypress/tests?p=cypress/integration/nested/tmp.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/noop.coffee","relative":"cypress/integration/noop.coffee","relativeUrl":"/__cypress/tests?p=cypress/integration/noop.coffee"}]);
return Cypress.onSpecWindow(window, [{"absolute":"/<path-to-project>/ids/cypress/support/e2e.js","relative":"cypress/support/e2e.js","relativeUrl":"/__cypress/tests?p=cypress/support/e2e.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/bar.js","relative":"cypress/integration/bar.js","relativeUrl":"/__cypress/tests?p=cypress/integration/bar.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/baz.js","relative":"cypress/integration/baz.js","relativeUrl":"/__cypress/tests?p=cypress/integration/baz.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/dom.jsx","relative":"cypress/integration/dom.jsx","relativeUrl":"/__cypress/tests?p=cypress/integration/dom.jsx"},{"absolute":"/<path-to-project>/ids/cypress/integration/es6.js","relative":"cypress/integration/es6.js","relativeUrl":"/__cypress/tests?p=cypress/integration/es6.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/foo.coffee","relative":"cypress/integration/foo.coffee","relativeUrl":"/__cypress/tests?p=cypress/integration/foo.coffee"},{"absolute":"/<path-to-project>/ids/cypress/integration/nested/tmp.js","relative":"cypress/integration/nested/tmp.js","relativeUrl":"/__cypress/tests?p=cypress/integration/nested/tmp.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/noop.coffee","relative":"cypress/integration/noop.coffee","relativeUrl":"/__cypress/tests?p=cypress/integration/noop.coffee"}]);
})(window.opener || window.parent);
</script>
</body>

View File

@@ -13,7 +13,7 @@
if (!Cypress) {
throw new Error("Tests cannot run without a reference to Cypress!");
}
return Cypress.onSpecWindow(window, [{"absolute":"/<path-to-project>/ids/cypress/support/index.js","relative":"cypress/support/index.js","relativeUrl":"/__cypress/tests?p=cypress/support/index.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/foo.coffee","relative":"cypress/integration/foo.coffee","relativeUrl":"/__cypress/tests?p=cypress/integration/foo.coffee"}]);
return Cypress.onSpecWindow(window, [{"absolute":"/<path-to-project>/ids/cypress/support/e2e.js","relative":"cypress/support/e2e.js","relativeUrl":"/__cypress/tests?p=cypress/support/e2e.js"},{"absolute":"/<path-to-project>/ids/cypress/integration/foo.coffee","relative":"cypress/integration/foo.coffee","relativeUrl":"/__cypress/tests?p=cypress/integration/foo.coffee"}]);
})(window.opener || window.parent);
</script>
</body>

View File

@@ -60,10 +60,11 @@ describe('lib/config', () => {
this.projectRoot = '/_test-output/path/to/project'
ctx.lifecycleManager.setCurrentTestingType('e2e')
sinon.stub(ctx.lifecycleManager, 'verifyProjectRoot').returns(undefined)
this.setup = (cypressJson = {}, cypressEnvJson = {}) => {
sinon.stub(ctx.lifecycleManager, 'getConfigFileContents').resolves(cypressJson)
sinon.stub(ctx.lifecycleManager, 'getConfigFileContents').resolves({ ...cypressJson, e2e: cypressJson.e2e ?? { supportFile: false } })
sinon.stub(ctx.lifecycleManager, 'loadCypressEnvFile').resolves(cypressEnvJson)
}
})
@@ -580,23 +581,23 @@ describe('lib/config', () => {
})
context('supportFile', () => {
it('passes if a string', function () {
this.setup({ supportFile: 'cypress/support' })
return this.expectValidationPasses()
})
it('passes if false', function () {
this.setup({ supportFile: false })
this.setup({ e2e: { supportFile: false } })
return this.expectValidationPasses()
})
it('fails if not a string or false', function () {
this.setup({ supportFile: true })
this.setup({ e2e: { supportFile: true } })
return this.expectValidationFails('be a string or false')
})
it('fails if is set at root level', function () {
this.setup({ supportFile: false })
return this.expectValidationFails('was removed from the root in Cypress version `10.0.0`')
})
})
context('trashAssetsBeforeRuns', () => {
@@ -1054,7 +1055,7 @@ describe('lib/config', () => {
this.defaults = (prop, value, cfg = {}, options = {}) => {
cfg.projectRoot = '/foo/bar/'
return config.mergeDefaults(cfg, options)
return config.mergeDefaults({ ...cfg, supportFile: cfg.supportFile ?? false }, options)
.then((mergedConfig) => {
expect(mergedConfig[prop]).to.deep.eq(value)
})
@@ -1258,35 +1259,35 @@ describe('lib/config', () => {
})
it('resets numTestsKeptInMemory to 0 when runMode', () => {
return config.mergeDefaults({ projectRoot: '/foo/bar/' }, { isTextTerminal: true })
return config.mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { isTextTerminal: true })
.then((cfg) => {
expect(cfg.numTestsKeptInMemory).to.eq(0)
})
})
it('resets watchForFileChanges to false when runMode', () => {
return config.mergeDefaults({ projectRoot: '/foo/bar/' }, { isTextTerminal: true })
return config.mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { isTextTerminal: true })
.then((cfg) => {
expect(cfg.watchForFileChanges).to.be.false
})
})
it('can override morgan in options', () => {
return config.mergeDefaults({ projectRoot: '/foo/bar/' }, { morgan: false })
return config.mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { morgan: false })
.then((cfg) => {
expect(cfg.morgan).to.be.false
})
})
it('can override isTextTerminal in options', () => {
return config.mergeDefaults({ projectRoot: '/foo/bar/' }, { isTextTerminal: true })
return config.mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { isTextTerminal: true })
.then((cfg) => {
expect(cfg.isTextTerminal).to.be.true
})
})
it('can override socketId in options', () => {
return config.mergeDefaults({ projectRoot: '/foo/bar/' }, { socketId: '1234' })
return config.mergeDefaults({ projectRoot: '/foo/bar/', supportFile: false }, { socketId: '1234' })
.then((cfg) => {
expect(cfg.socketId).to.eq('1234')
})
@@ -1295,6 +1296,7 @@ describe('lib/config', () => {
it('deletes envFile', () => {
const obj = {
projectRoot: '/foo/bar/',
supportFile: false,
env: {
foo: 'bar',
version: '0.5.2',
@@ -1322,6 +1324,7 @@ describe('lib/config', () => {
it('merges env into @config.env', () => {
const obj = {
projectRoot: '/foo/bar/',
supportFile: false,
env: {
host: 'localhost',
user: 'brian',
@@ -1404,6 +1407,7 @@ describe('lib/config', () => {
it('sets reporter and port to cli', () => {
const obj = {
projectRoot: '/foo/bar',
supportFile: false,
}
const options = {
@@ -1456,7 +1460,7 @@ describe('lib/config', () => {
screenshotOnRunFailure: { value: true, from: 'default' },
screenshotsFolder: { value: 'cypress/screenshots', from: 'default' },
slowTestThreshold: { value: 10000, from: 'default' },
supportFile: { value: 'cypress/support', from: 'default' },
supportFile: { value: false, from: 'config' },
supportFolder: { value: false, from: 'default' },
taskTimeout: { value: 60000, from: 'default' },
specPattern: { value: '**/*.*', from: 'default' },
@@ -1484,6 +1488,7 @@ describe('lib/config', () => {
const obj = {
projectRoot: '/foo/bar',
supportFile: false,
baseUrl: 'http://localhost:8080',
port: 2020,
env: {
@@ -1566,7 +1571,7 @@ describe('lib/config', () => {
screenshotOnRunFailure: { value: true, from: 'default' },
screenshotsFolder: { value: 'cypress/screenshots', from: 'default' },
slowTestThreshold: { value: 10000, from: 'default' },
supportFile: { value: 'cypress/support', from: 'default' },
supportFile: { value: false, from: 'config' },
supportFolder: { value: false, from: 'default' },
taskTimeout: { value: 60000, from: 'default' },
specPattern: { value: '**/*.*', from: 'default' },
@@ -1992,7 +1997,7 @@ describe('lib/config', () => {
context('.setSupportFileAndFolder', () => {
const mockSupportDefaults = {
supportFile: 'cypress/support',
supportFile: 'cypress/support/e2e.ts',
supportFolder: false,
configFile: 'cypress.json',
}
@@ -2031,14 +2036,14 @@ describe('lib/config', () => {
const obj = config.setAbsolutePaths({
projectRoot,
supportFile: 'cypress/support',
supportFile: 'cypress/support/e2e.js',
})
return config.setSupportFileAndFolder(obj, mockSupportDefaults)
.then((result) => {
expect(result).to.eql({
projectRoot,
supportFile: `${projectRoot}/cypress/support/index.js`,
supportFile: `${projectRoot}/cypress/support/e2e.js`,
supportFolder: `${projectRoot}/cypress/support`,
})
})
@@ -2049,7 +2054,7 @@ describe('lib/config', () => {
const obj = config.setAbsolutePaths({
projectRoot,
supportFile: 'cypress/support',
supportFile: false,
})
return config.setSupportFileAndFolder(obj, mockSupportDefaults)
@@ -2083,11 +2088,11 @@ describe('lib/config', () => {
const e = new Error('Cannot resolve TS file by default')
e.code = 'MODULE_NOT_FOUND'
sinon.stub(config.utils, 'resolveModule').withArgs(supportFolder).throws(e)
sinon.stub(config.utils, 'resolveModule').withArgs(supportFilename).throws(e)
const obj = config.setAbsolutePaths({
projectRoot,
supportFile: 'cypress/support',
supportFile: 'cypress/support/index.ts',
})
return config.setSupportFileAndFolder(obj, mockSupportDefaults)

View File

@@ -14,12 +14,12 @@ describe('lib/files', () => {
this.todosPath = FixturesHelper.projectPath('todos')
ctx.actions.project.setCurrentProjectForTestSetup(this.todosPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.todosPath)
return config.get(this.todosPath).then((cfg) => {
this.config = cfg;
({ projectRoot: this.projectRoot } = cfg)
ctx.actions.project.setCurrentProjectForTestSetup(this.projectRoot)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.projectRoot)
})
})

View File

@@ -26,7 +26,7 @@ describe('lib/fixture', () => {
return fs.readFileAsync(path.join(folder, image), encoding)
}
ctx.actions.project.setCurrentProjectForTestSetup(this.todosPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.todosPath)
return config.get(this.todosPath)
.then((cfg) => {
@@ -179,7 +179,7 @@ Expecting 'EOF', '}', ':', ',', ']', got 'STRING'\
it('can load a fixture with no extension when a same-named folder also exists', () => {
const projectPath = FixturesHelper.projectPath('folder-same-as-fixture')
ctx.actions.project.setCurrentProjectForTestSetup(projectPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(projectPath)
return config.get(projectPath)
.then((cfg) => {

View File

@@ -33,7 +33,7 @@ describe.skip('lib/plugins/index', () => {
configFile: `${todosPath}/cypress.config.js`,
}
ctx.setCurrentProjectForTestSetup(todosPath)
ctx.setCurrentProjectAndTestingTypeForTestSetup(todosPath)
getOptions = (overrides = {}) => {
return {

View File

@@ -1,6 +1,5 @@
require('../spec_helper')
const mockedEnv = require('mocked-env')
const path = require('path')
const chokidar = require('chokidar')
const pkg = require('@packages/root')
@@ -40,7 +39,7 @@ describe.skip('lib/project-base', () => {
sinon.stub(runEvents, 'execute').resolves()
ctx.actions.project.setCurrentProjectForTestSetup(this.todosPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.todosPath)
return settings.read(this.todosPath)
.then((obj = {}) => {
@@ -300,7 +299,7 @@ This option will not have an effect in Some-other-name. Tests that rely on web s
return this.project.open().then(() => {
expect(this.checkSupportFileStub).to.be.calledWith({
configFile: 'cypress.config.js',
supportFile: '/foo/bar/cypress/support/index.js',
supportFile: false,
})
})
})
@@ -532,72 +531,6 @@ This option will not have an effect in Some-other-name. Tests that rely on web s
})
})
context('#scaffold', () => {
beforeEach(function () {
this.project = new ProjectBase({ projectRoot: '/_test-output/path/to/project-e2e', testingType: 'e2e' })
sinon.stub(scaffold, 'integration').resolves()
sinon.stub(scaffold, 'fixture').resolves()
sinon.stub(scaffold, 'support').resolves()
sinon.stub(scaffold, 'plugins').resolves()
this.obj = { projectRoot: 'pr', fixturesFolder: 'ff', integrationFolder: 'if', supportFolder: 'sf', pluginsFile: 'pf/index.js' }
})
it('calls support.scaffold with supportFolder', function () {
return this.project.scaffold(this.obj).then(() => {
expect(scaffold.support).to.be.calledWith(this.obj.supportFolder)
})
})
it('does not call support.plugins if config.pluginsFile is falsey', function () {
this.obj.pluginsFile = false
return this.project.scaffold(this.obj).then(() => {
expect(scaffold.plugins).not.to.be.called
})
})
describe('forced', () => {
let resetEnv
beforeEach(function () {
this.obj.isTextTerminal = true
resetEnv = mockedEnv({
CYPRESS_INTERNAL_FORCE_SCAFFOLD: '1',
})
})
afterEach(() => {
resetEnv()
})
})
describe('not forced', () => {
let resetEnv
beforeEach(function () {
this.obj.isTextTerminal = true
resetEnv = mockedEnv({
CYPRESS_INTERNAL_FORCE_SCAFFOLD: undefined,
})
})
afterEach(() => {
resetEnv()
})
it('does not scaffold integration folder', function () {
return this.project.scaffold(this.obj).then(() => {
expect(scaffold.integration).to.not.be.calledWith(this.obj.integrationFolder)
expect(scaffold.fixture).to.not.be.calledWith(this.obj.fixturesFolder)
// still scaffolds support folder due to old logic
expect(scaffold.support).to.be.calledWith(this.obj.supportFolder)
})
})
})
})
context('#startWebsockets', () => {
beforeEach(function () {
this.project = new ProjectBase({ projectRoot: '/_test-output/path/to/project-e2e', testingType: 'e2e' })

View File

@@ -143,7 +143,7 @@ describe('lib/project_utils', () => {
try {
await checkSupportFile({
configFile: 'cypress.config.ts',
supportFile: '/this/file/does/not/exist/foo/bar/cypress/support/index.js',
supportFile: '/this/file/does/not/exist/foo/bar/cypress/support/e2e.js',
})
} catch (e) {
expect(e.message).to.include('The support file is missing or invalid.')

View File

@@ -60,7 +60,7 @@ describe('lib/screenshots', () => {
Jimp.prototype.composite = sinon.stub()
// Jimp.prototype.getBuffer = sinon.stub().resolves(@buffer)
ctx.actions.project.setCurrentProjectForTestSetup(this.todosPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.todosPath)
return config.get(this.todosPath)
.then((config1) => {

View File

@@ -22,7 +22,7 @@ describe('lib/server', () => {
beforeEach(function () {
this.server = new ServerE2E()
return config.setupFullConfigWithDefaults({ projectRoot: '/foo/bar/' })
return config.setupFullConfigWithDefaults({ projectRoot: '/foo/bar/', config: { supportFile: false } })
.then((cfg) => {
this.config = cfg
})

View File

@@ -32,7 +32,7 @@ describe('lib/socket', () => {
this.server = new ServerE2E(ctx)
ctx.actions.project.setCurrentProjectForTestSetup(this.todosPath)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.todosPath)
return config.get(this.todosPath)
.then((cfg) => {

View File

@@ -18,7 +18,7 @@ describe.skip('lib/util/settings', () => {
context('with default configFile option', () => {
beforeEach(function () {
this.setup = (obj = {}) => {
ctx.actions.project.setCurrentProjectForTestSetup(projectRoot)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(projectRoot)
return fs.writeFileAsync('cypress.config.js', `module.exports = ${JSON.stringify(obj)}`)
}
@@ -98,7 +98,7 @@ describe.skip('lib/util/settings', () => {
it('.read returns from configFile when its a JavaScript file', function () {
this.projectRoot = path.join(projectRoot, '_test-output/path/to/project/')
ctx.actions.project.setCurrentProjectForTestSetup(this.projectRoot)
ctx.actions.project.setCurrentProjectAndTestingTypeForTestSetup(this.projectRoot)
return fs.ensureDirAsync(this.projectRoot)
.then(() => {

View File

@@ -18,12 +18,12 @@ exports['e2e busted support file passes 1'] = `
Oops...we found an error preparing this test file:
cypress/support/index.js
cypress/support/e2e.js
The error was:
Error: Webpack Compilation Error
./cypress/support/index.js
./cypress/support/e2e.js
Module not found: Error: Can't resolve './does/not/exist' in '/foo/bar/.projects/busted-support-file/cypress/support'
Looked for and couldn't find the file at the following paths:
[/foo/bar/.projects/busted-support-file/cypress/support/package.json]
@@ -36,7 +36,7 @@ Looked for and couldn't find the file at the following paths:
[/foo/bar/.projects/busted-support-file/cypress/support/does/not/exist.coffee]
[/foo/bar/.projects/busted-support-file/cypress/support/does/not/exist.ts]
[/foo/bar/.projects/busted-support-file/cypress/support/does/not/exist.tsx]
@ ./cypress/support/index.js 3:0-27
@ ./cypress/support/e2e.js 3:0-27
[stack trace lines]

View File

@@ -2,6 +2,7 @@ const path = require('path')
module.exports = {
'e2e': {
'supportFile': false,
setupNodeEvents (on, config) {
on('before:browser:launch', (browser, options) => {
options.extensions.push(path.join(__dirname, '../plugin-extension/ext'))

View File

@@ -5,6 +5,7 @@ const path = require('path')
module.exports = {
'e2e': {
'supportFile': false,
setupNodeEvents (on, config) {
const parentPid = process.ppid
let { PATH_TO_CHROME_PROFILE } = config.env

View File

@@ -3,6 +3,7 @@ const { defineConfig } = require('cypress')
module.exports = defineConfig({
pageLoadTimeout: 10000,
e2e: {
supportFile: false,
specPattern: 'cypress/integration/**/*',
defaultCommandTimeout: 500,
videoCompression: 20,

View File

@@ -1,6 +1,7 @@
const config: Record<string, any> = {
pageLoadTimeout: 10000,
e2e: {
supportFile: false,
defaultCommandTimeout: 500,
videoCompression: 20,
},

View File

@@ -1,5 +1,5 @@
// ***********************************************************
// This example support/index.js is processed and
// This example support/e2e.js is processed and
// loaded automatically before your test files.
//
// This is a great place to put global configuration and

Some files were not shown because too many files have changed in this diff Show More