Merge branch '10.0-release' of https://github.com/cypress-io/cypress into tbiethman/develop-into-10-with-electron

# Conflicts:
#	circle.yml
This commit is contained in:
Tyler Biethman
2022-05-13 11:20:51 -05:00
34 changed files with 220 additions and 236 deletions

View File

@@ -315,7 +315,7 @@ const util = {
// To be removed when the Cypress binary pulls in the @cypress/webpack-batteries-included-preprocessor
// version that has been updated to webpack >= 5.61, which no longer relies on
// Node's builtin crypto.hash function.
if (process.versions && semver.satisfies(process.versions.node, '>=17.0.0') && process.versions.openssl.startsWith('3.')) {
if (process.versions && semver.satisfies(process.versions.node, '>=17.0.0') && semver.satisfies(process.versions.openssl, '>=3', { includePrerelease: true })) {
opts.ORIGINAL_NODE_OPTIONS = `${opts.ORIGINAL_NODE_OPTIONS || ''} --openssl-legacy-provider`
}

View File

@@ -68,7 +68,7 @@ function webpackDevServer4 (
const { devServerConfig: { cypressConfig: { devServerPublicPathRoute } } } = config
const WebpackDevServer = config.sourceWebpackModulesResult.webpackDevServer.module
const webpackDevServerConfig = {
host: 'localhost',
host: '127.0.0.1',
port: 'auto',
// @ts-ignore
...finalWebpackConfig?.devServer,

View File

@@ -12,7 +12,7 @@ import './support'
const requestSpecFile = (file: string, port: number) => {
return new Promise((res) => {
const opts = {
host: 'localhost',
host: '127.0.0.1',
port,
path: encodeURI(file),
}

View File

@@ -208,8 +208,10 @@ describe('Cypress in Cypress', { viewportWidth: 1500, defaultCommandTimeout: 100
it(`resets selector playground validity when selecting element with playground selector in ${testingType}`, () => {
startAtSpecsPage(testingType)
cy.get('[data-cy="spec-item"]').first().click()
cy.get('#unified-reporter').should('be.visible')
const spec = testingType === 'e2e' ? 'dom-content.spec.js' : 'TestComponent.spec.jsx'
cy.get('[data-cy="spec-item"]').contains(spec).click()
cy.get('.passed > .num').should('contain', 1)
cy.get('[data-cy="playground-activator"]').click()
cy.get('[data-cy="playground-selector"]').clear()

View File

@@ -251,8 +251,6 @@ describe('Sidebar Navigation', () => {
it('resize nav sends the correct value on the mutation', () => {
cy.contains('fixture.js').click()
cy.get('.toggle-specs-text').click()
cy.withCtx((ctx, o) => {
o.sinon.stub(ctx.actions.localSettings, 'setPreferences').resolves()
})

View File

@@ -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()
@@ -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()
@@ -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()

View File

@@ -10,6 +10,8 @@ describe('Spec List - Git Status', () => {
})
it('shows correct git status for files using real git repo', () => {
cy.wait(500)
// newly created, not yet committed
// this is performed by the task `initGitRepoForTestProject`
cy.get('[data-cy-row="foo.spec.js"] [data-cy="git-info-row"] svg')
@@ -34,6 +36,7 @@ describe('Spec List - Git Status', () => {
)
})
cy.wait(500)
// should update via GraphQL subscription, now the status is modified.
cy.get('[data-cy-row="dom-container.spec.js"] [data-cy="git-info-row"] svg')
.should('have.class', 'icon-light-orange-50')
@@ -46,13 +49,21 @@ describe('Spec List - Git Status', () => {
)
})
cy.wait(500)
// even if a created file is updated, the status should stay created
cy.get('[data-cy-row="foo.spec.js"] [data-cy="git-info-row"] svg')
.should('have.class', 'icon-light-jade-50')
cy.withCtx((ctx) => {
ctx.fs.writeFileSync(
ctx.path.join(ctx.currentProject!, 'cypress', 'e2e', 'dom-container.spec.js'),
if (Cypress.platform !== 'win32') {
// skip this test in Windows because of possible divergence in git behavior related to file permissions/stats
// TLDR: git config value `core.filemode` should be set to false
// See https://stackoverflow.com/questions/14564946/git-status-shows-changed-files-but-git-diff-doesnt and
// https://github.com/microsoft/WSL/issues/184 for reference
cy.withCtx((ctx) => {
ctx.fs.writeFileSync(
ctx.path.join(ctx.currentProject!, 'cypress', 'e2e', 'dom-container.spec.js'),
`describe('Dom Content', () => {
it('renders a container', () => {
cy.get('.container')
@@ -60,10 +71,13 @@ describe('Spec List - Git Status', () => {
})
`,
'utf-8',
)
})
)
})
cy.get('[data-cy-row="dom-container.spec.js"] [data-cy="git-info-row"] svg')
.should('have.class', 'icon-light-gray-500')
cy.wait(500)
cy.get('[data-cy-row="dom-container.spec.js"] [data-cy="git-info-row"] svg')
.should('have.class', 'icon-light-gray-500')
}
})
})

View File

@@ -14,11 +14,6 @@ describe('<CreateSpecModal />', () => {
gql={{
currentProject: {
id: 'id',
codeGenGlobs: {
id: 'super-unique-id',
__typename: 'CodeGenGlobs',
component: '**.vue',
},
currentTestingType: 'component',
configFile: 'cypress.config.js',
configFileAbsolutePath: '/path/to/cypress.config.js',
@@ -79,11 +74,6 @@ describe('playground', () => {
gql={{
currentProject: {
id: 'id',
codeGenGlobs: {
id: 'super-unique-id',
__typename: 'CodeGenGlobs',
component: '**.vue',
},
currentTestingType: 'component',
configFile: 'cypress.config.js',
configFileAbsolutePath: '/path/to/cypress.config.js',

View File

@@ -20,7 +20,6 @@
v-if="generator"
:key="`${generator.id}-${iteration}`"
v-model:title="title"
:code-gen-glob="codeGenGlob"
:gql="props.gql.currentProject"
:type="props.gql.currentProject?.currentTestingType"
:spec-file-name="specFileName"
@@ -78,10 +77,6 @@ fragment CreateSpecModal on Query {
id
fileExtensionToUse
defaultSpecFileName
codeGenGlobs {
id
component
}
...EmptyGenerator
}
}
@@ -114,14 +109,6 @@ const specFileName = computed(() => {
return getPathForPlatform(fileName)
})
const codeGenGlob = computed(() => {
if (!generator.value) {
return null
}
return props.gql.currentProject?.codeGenGlobs[generator.value.id]
})
const filteredGenerators = getFilteredGeneratorList(props.gql.currentProject?.currentTestingType)
const singleGenerator = computed(() => filteredGenerators.value.length === 1 ? filteredGenerators.value[0] : null)

View File

@@ -23,7 +23,6 @@
"@urql/exchange-graphcache": "4.3.6",
"chokidar": "3.5.1",
"common-path-prefix": "3.0.0",
"create-cypress-tests": "0.0.0-development",
"cross-fetch": "^3.1.4",
"dataloader": "^2.0.0",
"dayjs": "^1.9.3",

View File

@@ -260,9 +260,11 @@ export class MigrationActions {
throw error
})
// @ts-ignore configFile needs to be updated with the new one, so it finds the correct one
// with the new file, instead of the deleted one which is not supported anymore
this.ctx.modeOptions.configFile = this.ctx.migration.configFileNameAfterMigration
if (this.ctx.modeOptions.configFile) {
// @ts-ignore configFile needs to be updated with the new one, so it finds the correct one
// with the new file, instead of the deleted one which is not supported anymore
this.ctx.modeOptions.configFile = this.ctx.migration.configFileNameAfterMigration
}
}
async setLegacyConfigForMigration (config: LegacyCypressConfigJson) {

View File

@@ -333,7 +333,7 @@ export class GitDataSource {
}
async #getInfoWindows (absolutePaths: readonly string[]) {
const paths = absolutePaths.map((x) => path.resolve(x)).join(',')
const paths = absolutePaths.map((x) => `"${path.resolve(x)}"`).join(',')
const cmd = `FOR %x in (${paths}) DO (${GIT_LOG_COMMAND} %x)`
const result = await execa(cmd, { shell: true, cwd: this.config.projectRoot })

View File

@@ -1,8 +1,6 @@
import os from 'os'
import chokidar from 'chokidar'
import type { ResolvedFromConfig, RESOLVED_FROM, FoundSpec } from '@packages/types'
import { WIZARD_FRAMEWORKS } from '@packages/scaffold-config'
import { scanFSForAvailableDependency } from 'create-cypress-tests'
import type { ResolvedFromConfig, RESOLVED_FROM, FoundSpec, TestingType } from '@packages/types'
import minimatch from 'minimatch'
import { debounce, isEqual } from 'lodash'
import path from 'path'
@@ -104,7 +102,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)
}
@@ -121,7 +119,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, '')
@@ -282,13 +280,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}`
try {
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()
@@ -300,7 +300,11 @@ 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
@@ -308,7 +312,7 @@ export class ProjectDataSource {
return specFileName
} catch {
return defaultFileName
return getDefaultFileName(this.ctx.coreData.currentTestingType ?? 'e2e')
}
}
@@ -359,31 +363,6 @@ export class ProjectDataSource {
return preferences[projectTitle] ?? null
}
private guessFramework (projectRoot: string) {
const guess = WIZARD_FRAMEWORKS.find((framework) => {
const lookingForDeps = framework.detectors.map((x) => x.package).reduce(
(acc, dep) => ({ ...acc, [dep]: '*' }),
{},
)
return scanFSForAvailableDependency(projectRoot, lookingForDeps)
})
return guess ?? null
}
async getCodeGenGlobs () {
assert(this.ctx.currentProject, `Cannot find glob without currentProject.`)
const looseComponentGlob = '*.{js,jsx,ts,tsx,.vue}'
const framework = this.guessFramework(this.ctx.currentProject)
return {
component: framework?.glob ?? looseComponentGlob,
}
}
async getResolvedConfigFields (): Promise<ResolvedFromConfig[]> {
const config = this.ctx.lifecycleManager.loadedFullConfig?.resolved ?? {}

View File

@@ -1,10 +1,8 @@
import { parse } from '@babel/parser'
import { WIZARD_FRAMEWORKS } from '@packages/scaffold-config'
import { expect } from 'chai'
import dedent from 'dedent'
import fs from 'fs-extra'
import path from 'path'
import sinon from 'sinon'
import { DataContext } from '../../../src'
import {
Action, codeGenerator, CodeGenResult, CodeGenResults,
@@ -221,9 +219,6 @@ describe('code-generator', () => {
target,
}
// @ts-ignore
sinon.stub(ctx.project, 'guessFramework').returns(WIZARD_FRAMEWORKS[0])
const newSpecCodeGenOptions = new SpecOptions(ctx, {
codeGenPath: path.join(__dirname, 'files', 'react', 'Button.jsx'),
codeGenType: 'component',
@@ -244,9 +239,6 @@ describe('code-generator', () => {
target,
}
// @ts-ignore
sinon.stub(ctx.project, 'guessFramework').returns(WIZARD_FRAMEWORKS[1])
const newSpecCodeGenOptions = new SpecOptions(ctx, {
codeGenPath: path.join(__dirname, 'files', 'vue', 'Button.vue'),
codeGenType: 'component',

View File

@@ -192,31 +192,31 @@ 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')
})
@@ -224,13 +224,13 @@ describe('getDefaultSpecFileName', () => {
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')
})
@@ -238,13 +238,13 @@ describe('getDefaultSpecFileName', () => {
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')
})
@@ -252,25 +252,25 @@ describe('getDefaultSpecFileName', () => {
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')
})
@@ -278,43 +278,43 @@ describe('getDefaultSpecFileName', () => {
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']
@@ -322,7 +322,7 @@ describe('getDefaultSpecFileName', () => {
})
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']
@@ -330,7 +330,7 @@ describe('getDefaultSpecFileName', () => {
})
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')
})

View File

@@ -1,8 +1,9 @@
import gulp from 'gulp'
import rimraf from 'rimraf'
import webpack from 'webpack'
import * as cypressIcons from '@packages/icons'
import webpackConfig from './webpack.config.js'
import cp from 'child_process'
import util from 'util'
const exec = util.promisify(cp.exec)
const clean = (done) => {
rimraf('dist', done)
@@ -14,9 +15,7 @@ const manifest = () => {
}
const background = (cb) => {
const compiler = webpack(webpackConfig as webpack.Configuration)
compiler.run(cb)
exec('node ../../scripts/run-webpack.js').then(() => cb()).catch(cb)
}
const html = () => {

View File

@@ -13,7 +13,7 @@
"test-debug": "yarn test-unit --inspect-brk=5566",
"test-unit": "cross-env NODE_ENV=test mocha -r @packages/ts/register --reporter mocha-multi-reporters --reporter-options configFile=../../mocha-reporter-config.json",
"test-watch": "yarn test-unit --watch",
"watch": "webpack --watch --progress"
"watch": "node ../../scripts/run-webpack --watch --progress"
},
"dependencies": {
"bluebird": "3.5.3",

View File

@@ -43,11 +43,6 @@ export const createTestCurrentProject = (title: string, currentProject: Partial<
],
config,
cloudProject: CloudProjectStubs.componentProject,
codeGenGlobs: {
id: 'super-unique-id',
__typename: 'CodeGenGlobs',
component: '**/*.vue',
},
activeBrowser: stubBrowsers[0],
browsers: stubBrowsers,
isDefaultSpecPattern: true,

View File

@@ -357,14 +357,6 @@ type CodeFrame {
line: Int
}
"""Glob patterns for detecting files for code gen."""
type CodeGenGlobs implements Node {
component: String!
"""Relay style Node ID field for the CodeGenGlobs field"""
id: ID!
}
enum CodeGenType {
component
e2e
@@ -397,7 +389,6 @@ type CurrentProject implements Node & ProjectLike {
"""List of all code generation candidates stories"""
codeGenCandidates(glob: String!): [FileParts]
codeGenGlobs: CodeGenGlobs!
"""Project configuration"""
config: JSON!

View File

@@ -1,10 +0,0 @@
import { objectType } from 'nexus'
export const CodeGenGlobs = objectType({
name: 'CodeGenGlobs',
description: 'Glob patterns for detecting files for code gen.',
node: 'component',
definition (t) {
t.nonNull.string('component')
},
})

View File

@@ -4,7 +4,6 @@ import path from 'path'
import { BrowserStatusEnum, FileExtensionEnum } from '..'
import { TestingTypeEnum } from '../enumTypes/gql-WizardEnums'
import { Browser } from './gql-Browser'
import { CodeGenGlobs } from './gql-CodeGenGlobs'
import { FileParts } from './gql-FileParts'
import { ProjectPreferences } from './gql-ProjectPreferences'
import { Spec } from './gql-Spec'
@@ -194,11 +193,6 @@ export const CurrentProject = objectType({
},
})
t.nonNull.field('codeGenGlobs', {
type: CodeGenGlobs,
resolve: (src, args, ctx) => ctx.project.getCodeGenGlobs(),
})
t.list.field('codeGenCandidates', {
type: FileParts,
description: 'List of all code generation candidates stories',

View File

@@ -5,7 +5,6 @@ export * from './gql-AuthState'
export * from './gql-Browser'
export * from './gql-CachedUser'
export * from './gql-CodeFrame'
export * from './gql-CodeGenGlobs'
export * from './gql-CurrentProject'
export * from './gql-DevState'
export * from './gql-Editor'

View File

@@ -78,6 +78,51 @@ function renameSupport (lang: 'js' | 'ts' | 'coffee' = 'js') {
}, { lang })
}
describe('global mode', () => {
it('migrates 2 projects in global mode', () => {
cy.openGlobalMode()
cy.addProject('migration-e2e-export-default')
cy.addProject('migration-e2e-custom-integration-with-projectId')
cy.visitLaunchpad()
cy.withCtx((ctx, o) => {
o.sinon.stub(ctx.actions.migration, 'locallyInstalledCypressVersion').returns('10.0.0')
})
cy.contains('migration-e2e-export-default').click()
// rename integration->e2e
cy.get(renameAutoStep).should('exist')
cy.get(renameManualStep).should('not.exist')
// cypress/support/index.ts -> cypress/support/e2e.ts
cy.get(renameSupportStep).should('exist')
// no component specs
cy.get(setupComponentStep).should('not.exist')
cy.get(configFileStep).should('exist')
runAutoRename()
renameSupport('ts')
migrateAndVerifyConfig('cypress.config.ts')
checkOutcome()
cy.contains('Projects').click()
cy.contains('migration-e2e-custom-integration-with-projectId').click()
// default testFiles but custom integration - can rename automatically
cy.get(renameAutoStep).should('not.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')
renameSupport()
migrateAndVerifyConfig()
checkOutcome()
})
})
describe('Opening unmigrated project', () => {
it('legacy project with --e2e', () => {
cy.scaffoldProject('migration')

View File

@@ -4,7 +4,7 @@
"private": true,
"browser": "src/main.tsx",
"scripts": {
"build-for-tests": "webpack",
"build-for-tests": "node ../../scripts/run-webpack",
"clean-deps": "rimraf node_modules",
"cypress:open": "node ../../scripts/cypress open --project .",
"cypress:run": "node ../../scripts/cypress run --project .",

View File

@@ -4,7 +4,7 @@
"private": true,
"browser": "src/index.js",
"scripts": {
"build": "webpack",
"build": "node ../../scripts/run-webpack",
"build-prod": "cross-env NODE_ENV=production yarn build && tsc",
"clean-deps": "rimraf node_modules",
"cypress:open": "ts-node ../../scripts/cypress.js open --component --project .",
@@ -12,7 +12,7 @@
"postinstall": "echo '@packages/runner needs: yarn build'",
"lint": "eslint --ext .js,.jsx,.ts,.tsx,.json src",
"test": "ts-node ../../scripts/cypress.js run --component --project .",
"watch": "webpack --watch --progress --config webpack.config.ts"
"watch": "node ../../scripts/run-webpack --watch --progress --config webpack.config.ts"
},
"dependencies": {},
"devDependencies": {

View File

@@ -4,7 +4,7 @@
"private": true,
"browser": "src/index.js",
"scripts": {
"build": "webpack",
"build": "node ../../scripts/run-webpack",
"build-prod": "cross-env NODE_ENV=production yarn build",
"clean-deps": "rimraf node_modules",
"cypress:open": "node ../../scripts/cypress open",
@@ -14,7 +14,7 @@
"test-debug": "yarn test-unit --inspect-brk=5566",
"test-unit": "mocha --config test/.mocharc.json src/**/*.spec.* --exit",
"test-watch": "yarn test-unit --watch",
"watch": "webpack --watch --progress"
"watch": "node ../../scripts/run-webpack --watch --progress"
},
"devDependencies": {
"@cypress/react-tooltip": "0.5.3",

View File

@@ -73,7 +73,6 @@ export const WIZARD_FRAMEWORKS = [
]
},
codeGenFramework: 'react',
glob: '*.{js,jsx,tsx}',
mountModule: 'cypress/react',
supportStatus: 'full',
componentIndexHtml: componentIndexHtmlGenerator(),
@@ -93,7 +92,6 @@ export const WIZARD_FRAMEWORKS = [
]
},
codeGenFramework: 'vue',
glob: '*.vue',
mountModule: 'cypress/vue2',
supportStatus: 'full',
componentIndexHtml: componentIndexHtmlGenerator(),
@@ -113,7 +111,6 @@ export const WIZARD_FRAMEWORKS = [
]
},
codeGenFramework: 'vue',
glob: '*.vue',
mountModule: 'cypress/vue',
supportStatus: 'full',
componentIndexHtml: componentIndexHtmlGenerator(),
@@ -132,7 +129,6 @@ export const WIZARD_FRAMEWORKS = [
]
},
codeGenFramework: 'react',
glob: '*.{js,jsx,tsx}',
mountModule: 'cypress/react',
supportStatus: 'alpha',
componentIndexHtml: componentIndexHtmlGenerator('<div id="__next_css__DO_NOT_USE__"></div>'),
@@ -151,7 +147,6 @@ export const WIZARD_FRAMEWORKS = [
]
},
codeGenFramework: 'vue',
glob: '*.vue',
mountModule: 'cypress/vue2',
supportStatus: 'alpha',
componentIndexHtml: componentIndexHtmlGenerator(),
@@ -170,7 +165,6 @@ export const WIZARD_FRAMEWORKS = [
]
},
codeGenFramework: 'vue',
glob: '*.vue',
mountModule: 'cypress/vue2',
supportStatus: 'full',
componentIndexHtml: componentIndexHtmlGenerator(),
@@ -189,7 +183,6 @@ export const WIZARD_FRAMEWORKS = [
]
},
codeGenFramework: 'vue',
glob: '*.vue',
mountModule: 'cypress/vue',
supportStatus: 'full',
componentIndexHtml: componentIndexHtmlGenerator(),
@@ -208,7 +201,6 @@ export const WIZARD_FRAMEWORKS = [
]
},
codeGenFramework: 'react',
glob: '*.{js,jsx,tsx}',
mountModule: 'cypress/react',
supportStatus: 'full',
componentIndexHtml: componentIndexHtmlGenerator(),

View File

@@ -4,7 +4,7 @@
"private": true,
"main": "src/index.tsx",
"scripts": {
"build-for-tests": "webpack",
"build-for-tests": "node ../../scripts/run-webpack",
"check-deps": "node ../../scripts/check-deps.js --verbose",
"check-deps-pre": "npm run check-deps -- --prescript",
"clean-deps": "rimraf node_modules",
@@ -39,6 +39,6 @@
"react-dom": "16.8.6",
"rimraf": "3.0.2",
"webpack": "^4.44.2",
"webpack-cli": "3.3.11"
"webpack-cli": "3.3.2"
}
}

View File

@@ -39,7 +39,7 @@
"sass-loader": "10.1.0",
"sinon-chai": "3.3.0",
"webpack": "^4.44.2",
"webpack-cli": "3.3.11",
"webpack-cli": "3.3.2",
"webpack-livereload-plugin": "2.3.0"
}
}

View File

@@ -3,6 +3,9 @@ import pDefer from 'p-defer'
import { monorepoPaths } from '../monorepoPaths'
import { universalSpawn } from '../utils/childProcessUtils'
import { addChildProcess } from './gulpRegistry'
import semver from 'semver'
type Env = typeof process.env
export function webpackRunner () {
return runWebpack({
@@ -16,10 +19,27 @@ type RunWebpackCfg = {
cwd: string
prefix: string
args?: string[]
env?: object
env?: Env
devServer?: boolean
}
// https://github.com/cypress-io/cypress/issues/18914
// Node 17+ ships with OpenSSL 3 by default, so we may need the option
// --openssl-legacy-provider so that webpack@4 can use the legacy MD4 hash
// function. This option doesn't exist on Node <17 or when it is built
// against OpenSSL 1, so we have to detect Node's major version and check
// which version of OpenSSL it was built against before spawning the process.
//
// Can be removed once the webpack version is upgraded to >= 5.61,
// which no longer relies on Node's builtin crypto.hash function.
function useLegacyOpenSSLProvider (env: Env) {
if (process.versions && semver.satisfies(process.versions.node, '>=17.0.0') && semver.satisfies(process.versions.openssl, '>=3', { includePrerelease: true })) {
return { NODE_OPTIONS: `${env.NODE_OPTIONS ?? ''} --openssl-legacy-provider` }
}
return {}
}
export async function runWebpack (cfg: RunWebpackCfg) {
const { cwd, args = [], env = process.env, devServer = false, prefix } = cfg
const dfd = pDefer()
@@ -32,6 +52,7 @@ export async function runWebpack (cfg: RunWebpackCfg) {
cwd,
env: {
...(env || process.env),
...useLegacyOpenSSLProvider(env),
FORCE_COLOR: '1',
},
},

23
scripts/run-webpack.js Normal file
View File

@@ -0,0 +1,23 @@
const cp = require('child_process')
const path = require('path')
const semver = require('semver')
const webpackCli = path.join(__dirname, '..', 'node_modules', 'webpack-cli', 'bin', 'cli.js')
// https://github.com/cypress-io/cypress/issues/18914
// Node 17+ ships with OpenSSL 3 by default, so we may need the option
// --openssl-legacy-provider so that webpack@4 can use the legacy MD4 hash
// function. This option doesn't exist on Node <17 or when it is built
// against OpenSSL 1, so we have to detect Node's major version and check
// which version of OpenSSL it was built against before spawning the process.
//
// Can be removed once the webpack version is upgraded to >= 5.61,
// which no longer relies on Node's builtin crypto.hash function.
let NODE_OPTIONS = process.env.NODE_OPTIONS || ''
if (process.versions && semver.satisfies(process.versions.node, '>=17.0.0') && semver.satisfies(process.versions.openssl, '>=3', { includePrerelease: true })) {
NODE_OPTIONS = `${NODE_OPTIONS} --openssl-legacy-provider`
}
cp.execSync(`node ${webpackCli} ${process.argv.slice(2).join(' ')}`, { stdio: 'inherit', env: { ...process.env, NODE_OPTIONS } })

View File

@@ -818,6 +818,7 @@ const systemTests = {
const args = options.withBinary ? [
`run`,
`--project=${projectPath}`,
options.testingType === 'component' ? '--component' : '--e2e',
] : [
require.resolve('@packages/server'),
// hides a user warning to go through NPM module

View File

@@ -1,17 +1,30 @@
import systemTests from '../lib/system-tests'
function smokeTestDockerImage (dockerImage: string) {
systemTests.it(`can run in ${dockerImage}`, {
withBinary: true,
browser: 'electron',
dockerImage,
spec: 'test1.js',
specDir: 'tests',
project: 'todos',
context('e2e', () => {
systemTests.it(`can run in ${dockerImage}`, {
withBinary: true,
browser: 'electron',
dockerImage,
spec: 'test1.js',
specDir: 'tests',
project: 'todos',
})
})
context('component', () => {
systemTests.it(`can run in ${dockerImage}`, {
withBinary: true,
browser: 'electron',
dockerImage,
testingType: 'component',
project: 'simple-ct',
spec: 'src/simple_passing_component.cy.js',
})
})
}
describe('e2e binary node versions', () => {
describe('binary node versions', () => {
[
'cypress/base:12',
'cypress/base:14',

View File

@@ -16440,15 +16440,6 @@ engine.io@~5.0.0:
engine.io-parser "~4.0.0"
ws "~7.4.2"
enhanced-resolve@4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f"
integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==
dependencies:
graceful-fs "^4.1.2"
memory-fs "^0.4.0"
tapable "^1.0.0"
enhanced-resolve@5.7.0:
version "5.7.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.7.0.tgz#525c5d856680fbd5052de453ac83e32049958b5c"
@@ -18517,16 +18508,6 @@ find-yarn-workspace-root@^2.0.0:
dependencies:
micromatch "^4.0.2"
findup-sync@3.0.0, findup-sync@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1"
integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==
dependencies:
detect-file "^1.0.0"
is-glob "^4.0.0"
micromatch "^3.0.4"
resolve-dir "^1.0.1"
findup-sync@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-2.0.0.tgz#9326b1488c22d1a6088650a86901b2d9a90a2cbc"
@@ -18537,6 +18518,16 @@ findup-sync@^2.0.0:
micromatch "^3.0.4"
resolve-dir "^1.0.1"
findup-sync@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1"
integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==
dependencies:
detect-file "^1.0.0"
is-glob "^4.0.0"
micromatch "^3.0.4"
resolve-dir "^1.0.1"
fined@^1.0.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b"
@@ -21106,7 +21097,7 @@ import-lazy@^2.1.0:
resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43"
integrity sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=
import-local@2.0.0, import-local@^2.0.0:
import-local@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d"
integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==
@@ -21371,11 +21362,6 @@ internal-slot@^1.0.3:
has "^1.0.3"
side-channel "^1.0.4"
interpret@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296"
integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==
interpret@^1.0.0, interpret@^1.1.0, interpret@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e"
@@ -25348,7 +25334,7 @@ memfs@^3.4.1:
dependencies:
fs-monkey "1.0.3"
memory-fs@^0.4.0, memory-fs@^0.4.1:
memory-fs@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552"
integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=
@@ -35087,13 +35073,6 @@ supports-color@6.0.0:
dependencies:
has-flag "^3.0.0"
supports-color@6.1.0, supports-color@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
dependencies:
has-flag "^3.0.0"
supports-color@8.1.1, supports-color@^8.0.0, supports-color@^8.1.0, supports-color@^8.1.1:
version "8.1.1"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
@@ -35113,6 +35092,13 @@ supports-color@^5.3.0, supports-color@^5.4.0, supports-color@^5.5.0:
dependencies:
has-flag "^3.0.0"
supports-color@^6.1.0:
version "6.1.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3"
integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==
dependencies:
has-flag "^3.0.0"
supports-color@^7.0.0, supports-color@^7.1.0, supports-color@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
@@ -37066,7 +37052,7 @@ v8-compile-cache-lib@^3.0.0:
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz#0582bcb1c74f3a2ee46487ceecf372e46bce53e8"
integrity sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==
v8-compile-cache@2.0.3, v8-compile-cache@^2.0.2, v8-compile-cache@^2.0.3:
v8-compile-cache@^2.0.2, v8-compile-cache@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe"
integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==
@@ -37751,23 +37737,6 @@ webidl-conversions@^4.0.2:
watchpack "^1.7.4"
webpack-sources "^1.4.1"
webpack-cli@3.3.11:
version "3.3.11"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.11.tgz#3bf21889bf597b5d82c38f215135a411edfdc631"
integrity sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==
dependencies:
chalk "2.4.2"
cross-spawn "6.0.5"
enhanced-resolve "4.1.0"
findup-sync "3.0.0"
global-modules "2.0.0"
import-local "2.0.0"
interpret "1.2.0"
loader-utils "1.2.3"
supports-color "6.1.0"
v8-compile-cache "2.0.3"
yargs "13.2.4"
webpack-cli@3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.2.tgz#aed2437b0db0a7faa2ad28484e166a5360014a91"
@@ -38982,7 +38951,7 @@ yargs-parser@13.1.1:
camelcase "^5.0.0"
decamelize "^1.2.0"
yargs-parser@13.1.2, yargs-parser@^13.1.0, yargs-parser@^13.1.1, yargs-parser@^13.1.2:
yargs-parser@13.1.2, yargs-parser@^13.1.1, yargs-parser@^13.1.2:
version "13.1.2"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"
integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==
@@ -39097,23 +39066,6 @@ yargs@12.0.2:
y18n "^3.2.1 || ^4.0.0"
yargs-parser "^10.1.0"
yargs@13.2.4:
version "13.2.4"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83"
integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==
dependencies:
cliui "^5.0.0"
find-up "^3.0.0"
get-caller-file "^2.0.1"
os-locale "^3.1.0"
require-directory "^2.1.1"
require-main-filename "^2.0.0"
set-blocking "^2.0.0"
string-width "^3.0.0"
which-module "^2.0.0"
y18n "^4.0.0"
yargs-parser "^13.1.0"
yargs@13.3.0:
version "13.3.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83"