Skip to content

Commit

Permalink
Merge pull request #20370 from cypress-io/lmiller1990/UNIFY-1180-add-…
Browse files Browse the repository at this point in the history
…examples
  • Loading branch information
ZachJW34 authored Feb 25, 2022
2 parents 2ba40a0 + a304f80 commit 192632b
Show file tree
Hide file tree
Showing 281 changed files with 49,566 additions and 723 deletions.
21 changes: 21 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,24 @@ npm/cypress-schematic/src/**/*.js
/npm/create-cypress-tests/**/*.template.*

packages/data-context/test/unit/codegen/files

# community templates we test against, no need to lint
system-tests/projects/create-react-app-configured/**/*
system-tests/projects/create-react-app-unconfigured/**/*

system-tests/projects/vueclivue2-unconfigured/**/*
system-tests/projects/vueclivue2-configured/**/*

system-tests/projects/vueclivue3-unconfigured/**/*
system-tests/projects/vueclivue3-configured/**/*

system-tests/projects/vue3-vite-ts-unconfigured/**/*
system-tests/projects/vue3-vite-ts-configured/**/*

system-tests/projects/nextjs-unconfigured/**/*
system-tests/projects/nextjs-configured/**/*

system-tests/projects/nuxtjs-vue2-unconfigured/**/*
system-tests/projects/nuxtjs-vue2-configured/**/*

system-tests/projects/react-app-webpack-5-unconfigured/**/*
3 changes: 2 additions & 1 deletion autobarrel.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"prefix": "/* eslint-disable padding-line-between-statements */",
"paths": [
"packages/graphql/src/**/*",
"packages/data-context/src/**/*"
"packages/data-context/src/**/*",
"packages/scaffold-config/src/**"
],
"ignore": [
"packages/data-context/src/gen",
Expand Down
24 changes: 12 additions & 12 deletions packages/app/cypress/e2e/index.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -561,8 +561,8 @@ describe('App: Index', () => {
it('shows input for file extension filter', () => {
cy.get('@CreateFromComponentDialog').within(() => {
cy.log('testing builds')
cy.findByTestId('file-match-indicator').should('contain', '2 Matches')
cy.findByRole('button', { name: '*.{jsx,tsx}' }).click()
cy.findByTestId('file-match-indicator').should('contain', '4 Matches')
cy.findByRole('button', { name: '*.{js,jsx,tsx}' }).click()
cy.findByPlaceholderText(defaultMessages.components.fileSearch.byExtensionInput)
.as('ExtensionInput')
.clear()
Expand All @@ -572,9 +572,9 @@ describe('App: Index', () => {

cy.findByTestId('no-results-clear').click()

cy.get('@ExtensionInput').should('have.value', '*.{jsx,tsx}')
cy.get('@ExtensionInput').should('have.value', '*.{js,jsx,tsx}')

cy.findByTestId('file-match-indicator').should('contain', '2 Matches')
cy.findByTestId('file-match-indicator').should('contain', '4 Matches')
})
})

Expand All @@ -583,7 +583,7 @@ describe('App: Index', () => {
cy.findByLabelText('file-name-input').as('FileNameInput')
.should('have.value', '')

cy.findByTestId('file-match-indicator').should('contain', '2 Matches')
cy.findByTestId('file-match-indicator').should('contain', '4 Matches')

cy.get('@FileNameInput')
.type('foobar')
Expand All @@ -592,18 +592,18 @@ describe('App: Index', () => {

cy.findByTestId('no-results-clear').click()

cy.findByTestId('file-match-indicator').should('contain', '2 Matches')
cy.findByTestId('file-match-indicator').should('contain', '4 Matches')

cy.get('@FileNameInput')
.type('App.jsx')

cy.findByTestId('file-match-indicator').should('contain', '1 of 2 Matches')
cy.findByTestId('file-match-indicator').should('contain', '1 of 4 Matches')
})
})

it('shows success modal when spec is created from component', () => {
cy.get('@CreateFromComponentDialog').within(() => {
cy.findAllByTestId('file-list-row').eq(0).as('NewSpecFile')
cy.findAllByTestId('file-list-row').contains('App.jsx').as('NewSpecFile')

// TODO: assert visibility of secondary text on hover/focus when
// item is made keyboard accessible
Expand Down Expand Up @@ -732,7 +732,7 @@ describe('App: Index', () => {
.and('contain', defaultMessages.createSpec.component.importFromComponent.description).click()
})

cy.get('[data-cy=file-list-row]').first().click()
cy.get('[data-cy=file-list-row]').contains('App.jsx').click()

cy.get('input').invoke('val').should('eq', getPathForPlatform('src/App.cy.jsx'))
cy.contains(defaultMessages.createSpec.component.importEmptySpec.header)
Expand All @@ -750,7 +750,7 @@ describe('App: Index', () => {
.and('contain', defaultMessages.createSpec.component.importFromComponent.description).click()
})

cy.get('[data-cy=file-list-row]').first().click()
cy.get('[data-cy=file-list-row]').contains('App.jsx').click()

cy.get('input').invoke('val').should('eq', getPathForPlatform('src/App.cy.jsx'))
cy.contains(defaultMessages.createSpec.component.importEmptySpec.header)
Expand Down Expand Up @@ -824,11 +824,11 @@ describe('App: Index', () => {
})

cy.contains('Create from component').click()
const componentGlob = '*.{jsx,tsx}'
const componentGlob = '*.{js,jsx,tsx}'

cy.findByTestId('file-match-button').contains(componentGlob)
cy.percySnapshot('Component Generator')
checkCodeGenCandidates(['App.cy.jsx', 'App.jsx', 'index.jsx', 'Button.jsx', 'Button.stories.jsx'])
checkCodeGenCandidates(['cypress.config.js', 'App.cy.jsx', 'App.jsx', 'index.jsx', 'support.js', 'Button.jsx', 'Button.stories.jsx'])

cy.intercept('query-ComponentGeneratorStepOne').as('code-gen-candidates')
cy.findByTestId('file-match-button').click()
Expand Down
21 changes: 21 additions & 0 deletions packages/data-context/src/actions/MigrationActions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import path from 'path'
import assert from 'assert'
import type { DataContext } from '..'
import {
cleanUpIntegrationFolder,
Expand Down Expand Up @@ -127,4 +128,24 @@ export class MigrationActions {
throw Error(`Expected ${actual} to equal ${expected}`)
}
}

async assertSuccessfulConfigScaffold (configFile: `cypress.config.${'js'|'ts'}`) {
assert(this.ctx.currentProject)

// we assert the generated configuration file against one from a project that has
// been verified to run correctly.
// each project has an `unconfigured` and `configured` variant in `system-tests/projects`
// for example vueclivue2-configured and vueclivue2-unconfigured.
// after setting the project up with the launchpad, the two projects should contain the same files.

const configuredProject = this.ctx.project.projectTitle(this.ctx.currentProject).replace('unconfigured', 'configured')
const expectedProjectConfig = path.join(__dirname, '..', '..', '..', '..', 'system-tests', 'projects', configuredProject, configFile)

const actual = formatConfig(await this.ctx.actions.file.readFileInProject(configFile))
const expected = formatConfig(await this.ctx.fs.readFile(expectedProjectConfig, 'utf8'))

if (actual !== expected) {
throw Error(`Expected ${actual} to equal ${expected}`)
}
}
}
166 changes: 47 additions & 119 deletions packages/data-context/src/actions/WizardActions.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import type { CodeLanguageEnum, NexusGenEnums, NexusGenObjects } from '@packages/graphql/src/gen/nxs.gen'
import { Bundler, CodeLanguage, CODE_LANGUAGES, FrontendFramework, FRONTEND_FRAMEWORKS } from '@packages/types'
import { CodeLanguage, CODE_LANGUAGES } from '@packages/types'
import { Bundler, FrontendFramework, FRONTEND_FRAMEWORKS, detect } from '@packages/scaffold-config'
import assert from 'assert'
import dedent from 'dedent'
import path from 'path'
import fs from 'fs-extra'
import Debug from 'debug'

const debug = Debug('cypress:data-context:wizard-actions')
Expand All @@ -12,7 +14,6 @@ import type { DataContext } from '..'
interface WizardGetCodeComponent {
chosenLanguage: CodeLanguage
chosenFramework: FrontendFramework
chosenBundler: Bundler
}

export class WizardActions {
Expand All @@ -28,28 +29,33 @@ export class WizardActions {
return this.ctx.wizardData
}

setFramework (framework: NexusGenEnums['FrontendFrameworkEnum'] | null) {
const prevFramework = this.ctx.coreData.wizard.chosenFramework || ''
setFramework (framework: typeof FRONTEND_FRAMEWORKS[number]['type'] | null): void {
const next = FRONTEND_FRAMEWORKS.find((x) => x.type === framework)

this.ctx.coreData.wizard.chosenFramework = framework

if (framework !== 'react' && framework !== 'vue') {
return this.setBundler('webpack')
if (next?.supportedBundlers?.length === 1) {
this.setBundler(next?.supportedBundlers?.[0].type)

return
}

const { chosenBundler } = this.ctx.coreData.wizard

// if the previous bundler was incompatible with the
// new framework, we need to reset it
if ((chosenBundler && !this.ctx.wizard.chosenFramework?.supportedBundlers.includes(chosenBundler))
|| !['react', 'vue'].includes(prevFramework)) {
return this.setBundler(null)
}
// new framework that was selected, we need to reset it
const doesNotSupportChosenBundler = (chosenBundler && !new Set(
this.ctx.wizard.chosenFramework?.supportedBundlers.map((x) => x.type) || [],
).has(chosenBundler)) ?? false

return
const prevFramework = this.ctx.coreData.wizard.chosenFramework || ''

if (doesNotSupportChosenBundler || !['react', 'vue'].includes(prevFramework)) {
this.setBundler(null)
}
}

setBundler (bundler: NexusGenEnums['SupportedBundlers'] | null) {
setBundler (bundler: Bundler | null) {
this.ctx.coreData.wizard.chosenBundler = bundler

return this.data
Expand Down Expand Up @@ -83,76 +89,40 @@ export class WizardActions {
}

async initialize () {
if (this.ctx.currentProject) {
this.data.detectedFramework = null
this.data.detectedBundler = null
this.data.detectedLanguage = null

await this.detectLanguage()
debug('detectedLanguage %s', this.data.detectedLanguage)
this.data.chosenLanguage = this.data.detectedLanguage || 'js'

let hasPackageJson = true

try {
await this.ctx.fs.access(path.join(this.ctx.currentProject, 'package.json'), this.ctx.fs.constants.R_OK)
} catch (e) {
debug('Could not read or find package.json: %O', e)
hasPackageJson = false
}
const packageJson: {
dependencies?: { [key: string]: string }
devDependencies?: { [key: string]: string }
} = hasPackageJson ? await this.ctx.fs.readJson(path.join(this.ctx.currentProject, 'package.json')) : {}

debug('packageJson %O', packageJson)
const dependencies = [
...Object.keys(packageJson.dependencies || {}),
...Object.keys(packageJson.devDependencies || {}),
]

this.detectFramework(dependencies)
debug('detectedFramework %s', this.data.detectedFramework)
this.detectBundler(dependencies)
debug('detectedBundler %s', this.data.detectedBundler)

this.data.chosenFramework = this.data.detectedFramework || null
this.data.chosenBundler = this.data.detectedBundler || null
if (!this.ctx.currentProject) {
return
}
}

private detectFramework (dependencies: string[]) {
// Detect full featured frameworks
if (dependencies.includes('next')) {
this.ctx.wizardData.detectedFramework = 'nextjs'
} else if (dependencies.includes('react-scripts')) {
this.ctx.wizardData.detectedFramework = 'cra'
} else if (dependencies.includes('nuxt')) {
this.ctx.wizardData.detectedFramework = 'nuxtjs'
} else if (dependencies.includes('@vue/cli-service')) {
this.ctx.wizardData.detectedFramework = 'vuecli'
} else if (dependencies.includes('react')) {
this.ctx.wizardData.detectedFramework = 'react'
} else if (dependencies.includes('vue')) {
this.ctx.wizardData.detectedFramework = 'vue'
}
}
this.ctx.update((coreData) => {
coreData.wizard.detectedFramework = null
coreData.wizard.detectedBundler = null
coreData.wizard.detectedLanguage = null
})

private detectBundler (dependencies: string[]) {
const detectedFrameworkObject = FRONTEND_FRAMEWORKS.find((f) => f.type === this.ctx.wizardData.detectedFramework)
await this.detectLanguage()
debug('detectedLanguage %s', this.data.detectedLanguage)
this.data.chosenLanguage = this.data.detectedLanguage || 'js'

if (detectedFrameworkObject && detectedFrameworkObject.supportedBundlers.length === 1) {
this.ctx.wizardData.detectedBundler = detectedFrameworkObject.supportedBundlers[0] ?? null
try {
const detected = detect(await fs.readJson(path.join(this.ctx.currentProject, 'package.json')))

return
}
debug('detected %o', detected)

if (dependencies.includes('webpack')) {
this.ctx.wizardData.detectedBundler = 'webpack'
}
if (detected) {
this.ctx.update((coreData) => {
coreData.wizard.detectedFramework = detected.framework?.type ?? null
coreData.wizard.chosenFramework = detected.framework?.type ?? null

if (!detected.framework?.supportedBundlers[0]) {
return
}

if (dependencies.includes('vite')) {
this.ctx.wizardData.detectedBundler = 'vite'
coreData.wizard.detectedBundler = detected.bundler || detected.framework.supportedBundlers[0].type
coreData.wizard.chosenBundler = detected.bundler || detected.framework.supportedBundlers[0].type
})
}
} catch {
// Could not detect anything - no problem, no need to do anything.
}
}

Expand Down Expand Up @@ -218,7 +188,6 @@ export class WizardActions {
this.scaffoldFixtures(),
this.scaffoldSupport('component', chosenLanguage.type),
this.getComponentIndexHtml({
chosenBundler,
chosenFramework,
chosenLanguage,
}),
Expand Down Expand Up @@ -252,11 +221,7 @@ export class WizardActions {

assert(chosenFramework && chosenLanguage && chosenBundler)

return this.wizardGetConfigCodeComponent({
chosenLanguage,
chosenFramework,
chosenBundler,
})
return chosenFramework.config[chosenLanguage.type](chosenBundler.type)
}

return this.wizardGetConfigCodeE2E(language)
Expand Down Expand Up @@ -315,28 +280,6 @@ export class WizardActions {
return codeBlocks.join('\n')
}

private wizardGetConfigCodeComponent (opts: WizardGetCodeComponent): string {
const codeBlocks: string[] = []
const { chosenBundler, chosenFramework, chosenLanguage } = opts

const requirePath = chosenFramework.defaultPackagePath ?? chosenBundler.package

codeBlocks.push(chosenLanguage.type === 'ts' ? `import { defineConfig } from 'cypress'` : `const { defineConfig } = require('cypress')`)
codeBlocks.push(chosenLanguage.type === 'ts' ? `import { devServer } from '${requirePath}'` : `const { devServer } = require('${requirePath}')`)
codeBlocks.push('')
codeBlocks.push(chosenLanguage.type === 'ts' ? `export default defineConfig({` : `module.exports = defineConfig({`)
codeBlocks.push(` // Component testing, ${chosenLanguage.name}, ${chosenFramework.name}, ${chosenBundler.name}`)

codeBlocks.push(` ${COMPONENT_SCAFFOLD_BODY({
lang: chosenLanguage.type,
configOptionsString: '{}',
}).replace(/\n/g, '\n ')}`)

codeBlocks.push(`})\n`)

return codeBlocks.join('\n')
}

private async getComponentIndexHtml (opts: WizardGetCodeComponent): Promise<NexusGenObjects['ScaffoldedFile']> {
const [storybookInfo] = await Promise.all([
this.ctx.storybook.loadStorybookInfo(),
Expand Down Expand Up @@ -442,21 +385,6 @@ const E2E_SCAFFOLD_BODY = dedent`
},
`

interface ComponentScaffoldOpts {
lang: CodeLanguageEnum
configOptionsString: string
specPattern?: string
}

const COMPONENT_SCAFFOLD_BODY = (opts: ComponentScaffoldOpts) => {
return dedent`
component: {
devServer,
devServerConfig: ${opts.configOptionsString}
},
`
}

const FIXTURE_DATA = {
'name': 'Using fixtures to represent data',
'email': 'hello@cypress.io',
Expand Down
Loading

3 comments on commit 192632b

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 192632b Feb 25, 2022

Choose a reason for hiding this comment

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

Circle has built the linux x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.0.0/linux-x64/circle-10.0-release-192632be1f634f0e8300863e9b283757bc1947ca/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 192632b Feb 25, 2022

Choose a reason for hiding this comment

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

Circle has built the win32 x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.0.0/win32-x64/circle-10.0-release-192632be1f634f0e8300863e9b283757bc1947ca/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 192632b Feb 25, 2022

Choose a reason for hiding this comment

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

Circle has built the darwin x64 version of the Test Runner.

Learn more about this pre-release platform-specific build at https://on.cypress.io/installing-cypress#Install-pre-release-version.

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/10.0.0/darwin-x64/circle-10.0-release-192632be1f634f0e8300863e9b283757bc1947ca/cypress.tgz

Please sign in to comment.