mirror of
https://github.com/cypress-io/cypress.git
synced 2026-02-26 10:59:23 -06:00
feat: vue-cli and nuxt preset for CT object API architecture (#20956)
This commit is contained in:
@@ -4,9 +4,10 @@
|
||||
// in the render options are directly passed through to the Utils mount().
|
||||
|
||||
/// <reference types="cypress" />
|
||||
import { mount } from '@cypress/vue'
|
||||
|
||||
import { h } from 'vue'
|
||||
import Card from './Card.vue'
|
||||
import { mount } from '@cypress/vue'
|
||||
|
||||
describe('Card', () => {
|
||||
it('skipped slots', () => {
|
||||
@@ -15,10 +16,18 @@ describe('Card', () => {
|
||||
})
|
||||
|
||||
it('renders slots', () => {
|
||||
// TODO: use HTML syntax (not render function with `h`)
|
||||
// when it's working.
|
||||
// Blocked by upstream bug in Test Utils: https://github.com/vuejs/test-utils/issues/1166
|
||||
// mount(Card, {
|
||||
// slots: {
|
||||
// header: `<h1>HEADER</h1>`
|
||||
// },
|
||||
// })
|
||||
mount(Card, {
|
||||
slots: {
|
||||
header: '<h1>HEADER</h1>',
|
||||
footer: '<div>FOOTER</div>',
|
||||
header: () => h('h1', 'HEADER'),
|
||||
footer: () => h('div', 'FOOTER'),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -29,9 +38,7 @@ describe('Card', () => {
|
||||
it('renders scopedSlots', () => {
|
||||
mount(Card, {
|
||||
slots: {
|
||||
default: `<template #default="props">
|
||||
<p>Yay! {{props.content}}</p>
|
||||
</template>`,
|
||||
default: ({ content }) => h('div', {}, h('p', `Yay! ${content}`)),
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import { h } from 'vue'
|
||||
import Card from './Card.vue'
|
||||
import { mount } from '@cypress/vue'
|
||||
|
||||
@@ -15,10 +16,18 @@ describe('Card', () => {
|
||||
})
|
||||
|
||||
it('renders slots', () => {
|
||||
// TODO: use HTML syntax (not render function with `h`)
|
||||
// when it's working.
|
||||
// Blocked by upstream bug in Test Utils: https://github.com/vuejs/test-utils/issues/1166
|
||||
// mount(Card, {
|
||||
// slots: {
|
||||
// header: `<h1>HEADER</h1>`
|
||||
// },
|
||||
// })
|
||||
mount(Card, {
|
||||
slots: {
|
||||
header: '<h1>HEADER</h1>',
|
||||
footer: '<div>FOOTER</div>',
|
||||
header: () => h('h1', 'HEADER'),
|
||||
footer: () => h('div', 'FOOTER'),
|
||||
},
|
||||
})
|
||||
|
||||
@@ -29,7 +38,7 @@ describe('Card', () => {
|
||||
it('renders scopedSlots', () => {
|
||||
mount(Card, {
|
||||
slots: {
|
||||
default: '<template #default="props"><p>Yay! {{props.content}}</p></template>',
|
||||
default: ({ content }) => h('div', {}, h('p', `Yay! ${content}`)),
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import { h } from 'vue'
|
||||
import AppInput from './AppInput.vue'
|
||||
import { mount } from '@cypress/vue'
|
||||
|
||||
@@ -11,7 +12,15 @@ it('renders label', () => {
|
||||
},
|
||||
// passing slots to the component #364
|
||||
slots: {
|
||||
label: `<label for="username">Enter Username</label>`,
|
||||
// TODO: use HTML syntax (not render function with `h`)
|
||||
// when it's working.
|
||||
// Blocked by upstream bug in Test Utils: https://github.com/vuejs/test-utils/issues/1166
|
||||
// mount(AppInput, {
|
||||
// slots: {
|
||||
// label: `<label for="username">Enter Username<label>`
|
||||
// },
|
||||
// })
|
||||
label: () => h('label', { for: 'username' }, 'Enter Username'),
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@cypress/mount-utils": "*",
|
||||
"@vue/test-utils": "^2.0.0-rc.10"
|
||||
"@vue/test-utils": "2.0.0-rc.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "7.9.0",
|
||||
|
||||
31
npm/webpack-dev-server-fresh/cypress/e2e/nuxt.cy.ts
Normal file
31
npm/webpack-dev-server-fresh/cypress/e2e/nuxt.cy.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
// <reference types="cypress" />
|
||||
/// <reference path="../support/e2e.ts" />
|
||||
import type { ProjectFixtureDir } from '@tooling/system-tests/lib/fixtureDirs'
|
||||
|
||||
const PROJECTS: ProjectFixtureDir[] = ['nuxtjs2']
|
||||
|
||||
// Add to this list to focus on a particular permutation
|
||||
// TODO: run vuecli4-vue2 tests once cypress/vue-2 is bundled
|
||||
const ONLY_PROJECTS: ProjectFixtureDir[] = []
|
||||
|
||||
for (const project of PROJECTS) {
|
||||
if (ONLY_PROJECTS.length && !ONLY_PROJECTS.includes(project)) {
|
||||
continue
|
||||
}
|
||||
|
||||
// TODO: This will work once `cypress/vue2` is bundled in the binary
|
||||
// Since Nuxt.js 2 is based on `vue@2`.
|
||||
describe.skip(`Working with ${project}`, () => {
|
||||
beforeEach(() => {
|
||||
cy.scaffoldProject(project)
|
||||
cy.openProject(project)
|
||||
cy.startAppServer('component')
|
||||
})
|
||||
|
||||
it('should mount a passing test', () => {
|
||||
cy.visitApp()
|
||||
cy.contains('Tutorial.cy.js').click()
|
||||
cy.get('.passed > .num').should('contain', 1)
|
||||
})
|
||||
})
|
||||
}
|
||||
29
npm/webpack-dev-server-fresh/cypress/e2e/vue-cli.cy.ts
Normal file
29
npm/webpack-dev-server-fresh/cypress/e2e/vue-cli.cy.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
// <reference types="cypress" />
|
||||
/// <reference path="../support/e2e.ts" />
|
||||
import type { ProjectFixtureDir } from '@tooling/system-tests/lib/fixtureDirs'
|
||||
|
||||
const PROJECTS: ProjectFixtureDir[] = ['vuecli4-vue2', 'vuecli4-vue3', 'vuecli5-vue3']
|
||||
|
||||
// Add to this list to focus on a particular permutation
|
||||
// TODO: run vuecli4-vue2 tests once cypress/vue-2 is bundled
|
||||
const ONLY_PROJECTS: ProjectFixtureDir[] = ['vuecli4-vue3', 'vuecli5-vue3']
|
||||
|
||||
for (const project of PROJECTS) {
|
||||
if (ONLY_PROJECTS.length && !ONLY_PROJECTS.includes(project)) {
|
||||
continue
|
||||
}
|
||||
|
||||
describe(`Working with ${project}`, () => {
|
||||
beforeEach(() => {
|
||||
cy.scaffoldProject(project)
|
||||
cy.openProject(project)
|
||||
cy.startAppServer('component')
|
||||
})
|
||||
|
||||
it('should mount a passing test', () => {
|
||||
cy.visitApp()
|
||||
cy.contains('HelloWorld.cy.js').click()
|
||||
cy.get('.passed > .num').should('contain', 1)
|
||||
})
|
||||
})
|
||||
}
|
||||
@@ -1,13 +1,15 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import type WebpackDevServer from 'webpack-dev-server'
|
||||
import type { Compiler } from 'webpack'
|
||||
import type { Compiler, Configuration } from 'webpack'
|
||||
|
||||
import { createWebpackDevServer } from './createWebpackDevServer'
|
||||
import { sourceRelativeWebpackModules } from './helpers/sourceRelativeWebpackModules'
|
||||
import type { AddressInfo } from 'net'
|
||||
import debugLib from 'debug'
|
||||
import type { Server } from 'http'
|
||||
import { vueCliHandler } from './helpers/vueCliHandler'
|
||||
import { nuxtHandler } from './helpers/nuxtHandler'
|
||||
|
||||
const debug = debugLib('cypress:webpack-dev-server-fresh:devServer')
|
||||
|
||||
@@ -20,7 +22,7 @@ export type WebpackDevServerConfig = {
|
||||
webpackConfig?: unknown // Derived from the user's webpack
|
||||
}
|
||||
|
||||
const ALL_FRAMEWORKS = ['create-react-app', 'nuxt', 'react'] as const
|
||||
const ALL_FRAMEWORKS = ['create-react-app', 'nuxt', 'react', 'vue-cli'] as const
|
||||
|
||||
/**
|
||||
* @internal
|
||||
@@ -48,8 +50,8 @@ const normalizeError = (error: Error | string) => {
|
||||
* @param config
|
||||
*/
|
||||
export function devServer (devServerConfig: WebpackDevServerConfig): Promise<Cypress.ResolvedDevServerConfig> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const result = devServer.create(devServerConfig) as DevServerCreateResult
|
||||
return new Promise(async (resolve, reject) => {
|
||||
const result = await devServer.create(devServerConfig) as DevServerCreateResult
|
||||
|
||||
// When compiling in run mode
|
||||
// Stop the clock early, no need to run all the tests on a failed build
|
||||
@@ -114,10 +116,10 @@ export function devServer (devServerConfig: WebpackDevServerConfig): Promise<Cyp
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
devServer.create = function (devServerConfig: WebpackDevServerConfig) {
|
||||
devServer.create = async function (devServerConfig: WebpackDevServerConfig) {
|
||||
const sourceWebpackModulesResult = sourceRelativeWebpackModules(devServerConfig)
|
||||
|
||||
let frameworkConfig: object | undefined
|
||||
let frameworkConfig: Configuration | undefined
|
||||
|
||||
// If we have a framework specified, source the associated config
|
||||
if (typeof devServerConfig.framework === 'string') {
|
||||
@@ -128,6 +130,11 @@ devServer.create = function (devServerConfig: WebpackDevServerConfig) {
|
||||
case 'react':
|
||||
break
|
||||
case 'nuxt':
|
||||
frameworkConfig = await nuxtHandler({ devServerConfig, sourceWebpackModulesResult })
|
||||
break
|
||||
|
||||
case 'vue-cli':
|
||||
frameworkConfig = vueCliHandler({ devServerConfig, sourceWebpackModulesResult })
|
||||
break
|
||||
default:
|
||||
throw new Error(`Unexpected framework ${devServerConfig.framework}, expected one of ${ALL_FRAMEWORKS.join(', ')}`)
|
||||
|
||||
26
npm/webpack-dev-server-fresh/src/helpers/nuxtHandler.ts
Normal file
26
npm/webpack-dev-server-fresh/src/helpers/nuxtHandler.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { CreateFinalWebpackConfig } from '../createWebpackDevServer'
|
||||
import debugLib from 'debug'
|
||||
import type { Configuration } from 'webpack'
|
||||
|
||||
type PresetHandler = Omit<CreateFinalWebpackConfig, 'frameworkConfig'>
|
||||
|
||||
const debug = debugLib('cypress:webpack-dev-server-fresh:nuxtHandler')
|
||||
|
||||
export async function nuxtHandler ({ devServerConfig }: PresetHandler): Promise<Configuration> {
|
||||
try {
|
||||
const nuxt = require.resolve('nuxt', {
|
||||
paths: [devServerConfig.cypressConfig.projectRoot],
|
||||
})
|
||||
|
||||
const { getWebpackConfig } = require(nuxt)
|
||||
|
||||
const webpackConfig = await getWebpackConfig()
|
||||
|
||||
debug('webpack config %o', webpackConfig)
|
||||
|
||||
return webpackConfig
|
||||
} catch (e) {
|
||||
console.error(e) // eslint-disable-line no-console
|
||||
throw Error(`Error loading nuxt. Looked in ${require.resolve.paths(devServerConfig.cypressConfig.projectRoot)}`)
|
||||
}
|
||||
}
|
||||
@@ -189,7 +189,20 @@ export function sourceRelativeWebpackModules (config: WebpackDevServerConfig) {
|
||||
result.htmlWebpackPlugin.importPath = path.dirname(htmlWebpackPluginJsonPath)
|
||||
result.htmlWebpackPlugin.packageJson = require(htmlWebpackPluginJsonPath)
|
||||
result.htmlWebpackPlugin.module = require(result.htmlWebpackPlugin.importPath)
|
||||
result.htmlWebpackPlugin.majorVersion = getMajorVersion(result.htmlWebpackPlugin.packageJson, [4, 5])
|
||||
try {
|
||||
result.htmlWebpackPlugin.majorVersion = getMajorVersion(result.htmlWebpackPlugin.packageJson, [4, 5])
|
||||
} catch (e) {
|
||||
// html-webpack-plugin@4 works fine with webpack 4, in place of html-webpack-plugin@3.
|
||||
// This combination of dependencies is commonly found in Vue CLI 4.x.
|
||||
// In fact, the version of html-webpack-plugin is pegged to the version webpack.
|
||||
// Vue CLI is technically incorrect.
|
||||
// In this case, just use 4.x, which we ship as part of the binary.
|
||||
if (result.webpack.majorVersion === 4 && (e as Error).message.includes('3.2')) {
|
||||
result.htmlWebpackPlugin.majorVersion = 4
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
24
npm/webpack-dev-server-fresh/src/helpers/vueCliHandler.ts
Normal file
24
npm/webpack-dev-server-fresh/src/helpers/vueCliHandler.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import type { CreateFinalWebpackConfig } from '../createWebpackDevServer'
|
||||
import debugLib from 'debug'
|
||||
import type { Configuration } from 'webpack'
|
||||
|
||||
type PresetHandler = Omit<CreateFinalWebpackConfig, 'frameworkConfig'>
|
||||
|
||||
const debug = debugLib('cypress:webpack-dev-server-fresh:vueCliHandler')
|
||||
|
||||
export function vueCliHandler ({ devServerConfig }: PresetHandler): Configuration {
|
||||
try {
|
||||
const config = require.resolve('@vue/cli-service/webpack.config', {
|
||||
paths: [devServerConfig.cypressConfig.projectRoot],
|
||||
})
|
||||
|
||||
const webpackConfig = require(config)
|
||||
|
||||
debug('webpack config %o', webpackConfig)
|
||||
|
||||
return webpackConfig
|
||||
} catch (e) {
|
||||
console.error(e) // eslint-disable-line no-console
|
||||
throw Error(`Error loading @vue/cli-service/webpack.config.js. Looked in ${require.resolve.paths(devServerConfig.cypressConfig.projectRoot)}`)
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,35 @@ const posixSeparator = '/'
|
||||
|
||||
const CYPRESS_WEBPACK_ENTRYPOINT = path.resolve(__dirname, 'browser.js')
|
||||
|
||||
/**
|
||||
* Removes and/or modifies certain plugins known to conflict
|
||||
* when used with cypress/webpack-dev-server.
|
||||
*/
|
||||
function modifyWebpackConfigForCypress (webpackConfig: Partial<Configuration>) {
|
||||
if (webpackConfig?.plugins) {
|
||||
webpackConfig.plugins = webpackConfig.plugins.filter((plugin) => {
|
||||
if (removeList.includes(plugin.constructor.name)) {
|
||||
/* eslint-disable no-console */
|
||||
console.warn(`[@cypress/webpack-dev-server]: removing ${plugin.constructor.name} from configuration.`)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
if (typeof webpackConfig?.module?.unsafeCache === 'function') {
|
||||
const originalCachePredicate = webpackConfig.module.unsafeCache
|
||||
|
||||
webpackConfig.module.unsafeCache = (module: any) => {
|
||||
return originalCachePredicate(module) && !/[\\/]webpack-dev-server[\\/]dist[\\/]browser\.js/.test(module.resource)
|
||||
}
|
||||
}
|
||||
|
||||
return webpackConfig
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a webpack 4/5 compatible webpack "configuration"
|
||||
* to pass to the sourced webpack function
|
||||
@@ -51,6 +80,9 @@ export function makeWebpackConfig (
|
||||
const { module: webpack } = config.sourceWebpackModulesResult.webpack
|
||||
const userWebpackConfig = config.devServerConfig.webpackConfig as Partial<Configuration>
|
||||
const frameworkWebpackConfig = config.frameworkConfig as Partial<Configuration>
|
||||
const userAndFrameworkWebpackConfig = modifyWebpackConfigForCypress(
|
||||
merge(frameworkWebpackConfig ?? {}, userWebpackConfig ?? {}),
|
||||
)
|
||||
|
||||
const {
|
||||
cypressConfig: {
|
||||
@@ -62,7 +94,7 @@ export function makeWebpackConfig (
|
||||
devServerEvents,
|
||||
} = config.devServerConfig
|
||||
|
||||
debug(`User passed in webpack config with values %o`, userWebpackConfig)
|
||||
debug(`User passed in user and framework webpack config with values %o`, userAndFrameworkWebpackConfig)
|
||||
debug(`New webpack entries %o`, files)
|
||||
debug(`Project root`, projectRoot)
|
||||
debug(`Support file`, supportFile)
|
||||
@@ -89,30 +121,8 @@ export function makeWebpackConfig (
|
||||
],
|
||||
}
|
||||
|
||||
if (userWebpackConfig?.plugins) {
|
||||
userWebpackConfig.plugins = userWebpackConfig.plugins.filter((plugin) => {
|
||||
if (removeList.includes(plugin.constructor.name)) {
|
||||
/* eslint-disable no-console */
|
||||
console.warn(`[@cypress/webpack-dev-server]: removing ${plugin.constructor.name} from configuration.`)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
if (typeof userWebpackConfig?.module?.unsafeCache === 'function') {
|
||||
const originalCachePredicate = userWebpackConfig.module.unsafeCache
|
||||
|
||||
userWebpackConfig.module.unsafeCache = (module: any) => {
|
||||
return originalCachePredicate(module) && !/[\\/]webpack-dev-server[\\/]dist[\\/]browser\.js/.test(module.resource)
|
||||
}
|
||||
}
|
||||
|
||||
const mergedConfig = merge(
|
||||
userWebpackConfig ?? {},
|
||||
frameworkWebpackConfig ?? {},
|
||||
userAndFrameworkWebpackConfig,
|
||||
makeDefaultWebpackConfig(config),
|
||||
dynamicWebpackConfig,
|
||||
)
|
||||
|
||||
@@ -11,8 +11,10 @@ const cypressConfig = {
|
||||
indexHtmlFile: path.join(__dirname, 'component-index.html'),
|
||||
} as Cypress.PluginConfigOptions
|
||||
|
||||
describe('devServer', () => {
|
||||
it('creates a new devServer webpack4, webpackDevServer3', () => {
|
||||
describe('devServer', function () {
|
||||
this.timeout(10 * 1000)
|
||||
|
||||
it('creates a new devServer webpack4, webpackDevServer3', async () => {
|
||||
const { devServer } = proxyquire('../src/devServer', {
|
||||
'./helpers/sourceRelativeWebpackModules': {
|
||||
sourceRelativeWebpackModules: () => {
|
||||
@@ -23,7 +25,7 @@ describe('devServer', () => {
|
||||
} },
|
||||
}) as typeof import('../src/devServer')
|
||||
|
||||
const result = devServer.create({
|
||||
const result = await devServer.create({
|
||||
specs: [],
|
||||
cypressConfig,
|
||||
devServerEvents: new EventEmitter(),
|
||||
@@ -33,7 +35,7 @@ describe('devServer', () => {
|
||||
expect(result.version).to.eq(3)
|
||||
})
|
||||
|
||||
it('creates a new devServer webpack4, webpackDevServer4', () => {
|
||||
it('creates a new devServer webpack4, webpackDevServer4', async () => {
|
||||
const { devServer } = proxyquire('../src/devServer', {
|
||||
'./helpers/sourceRelativeWebpackModules': {
|
||||
sourceRelativeWebpackModules: () => {
|
||||
@@ -44,7 +46,7 @@ describe('devServer', () => {
|
||||
} },
|
||||
}) as typeof import('../src/devServer')
|
||||
|
||||
const result = devServer.create({
|
||||
const result = await devServer.create({
|
||||
specs: [],
|
||||
cypressConfig,
|
||||
devServerEvents: new EventEmitter(),
|
||||
@@ -54,7 +56,7 @@ describe('devServer', () => {
|
||||
expect(result.version).to.eq(4)
|
||||
})
|
||||
|
||||
it('creates a new devServer webpack5, webpackDevServer4', () => {
|
||||
it('creates a new devServer webpack5, webpackDevServer4', async () => {
|
||||
const { devServer } = proxyquire('../src/devServer', {
|
||||
'./helpers/sourceRelativeWebpackModules': {
|
||||
sourceRelativeWebpackModules: () => {
|
||||
@@ -65,7 +67,7 @@ describe('devServer', () => {
|
||||
} },
|
||||
}) as typeof import('../src/devServer')
|
||||
|
||||
const result = devServer.create({
|
||||
const result = await devServer.create({
|
||||
specs: [],
|
||||
cypressConfig,
|
||||
devServerEvents: new EventEmitter(),
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
import { scaffoldMigrationProject } from '../test-helpers/scaffoldProject'
|
||||
import { expect } from 'chai'
|
||||
import { nuxtHandler } from '../../src/helpers/nuxtHandler'
|
||||
|
||||
describe('nuxtHandler', function () {
|
||||
// can take a while since we install node_modules
|
||||
this.timeout(1000 * 60)
|
||||
|
||||
it('sources from a nuxtjs 2 project', async () => {
|
||||
const projectRoot = await scaffoldMigrationProject('nuxtjs2')
|
||||
|
||||
process.chdir(projectRoot)
|
||||
|
||||
const config = await nuxtHandler({
|
||||
devServerConfig: {
|
||||
cypressConfig: { projectRoot } as Cypress.PluginConfigOptions,
|
||||
},
|
||||
} as any)
|
||||
|
||||
// Verify it's a Vue-specific webpack config by seeing if VueLoader is present.
|
||||
expect(config.plugins.find((plug) => plug.constructor.name === 'VueLoader'))
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,38 @@
|
||||
import { scaffoldMigrationProject } from '../test-helpers/scaffoldProject'
|
||||
import { expect } from 'chai'
|
||||
import { vueCliHandler } from '../../src/helpers/vueCliHandler'
|
||||
|
||||
describe('vueCliHandler', function () {
|
||||
// can take a while since we install node_modules
|
||||
this.timeout(1000 * 60)
|
||||
|
||||
it('sources from a @vue/cli-service@5.x project with Vue 3', async () => {
|
||||
const projectRoot = await scaffoldMigrationProject('vuecli5-vue3')
|
||||
|
||||
process.chdir(projectRoot)
|
||||
|
||||
const config = vueCliHandler({
|
||||
devServerConfig: {
|
||||
cypressConfig: { projectRoot } as Cypress.PluginConfigOptions,
|
||||
},
|
||||
} as any)
|
||||
|
||||
// Verify it's a Vue-specific webpack config by seeing if VueLoader is present.
|
||||
expect(config.plugins.find((plug) => plug.constructor.name === 'VueLoader'))
|
||||
})
|
||||
|
||||
it('sources from a @vue/cli-service@4.x project with Vue 2', async () => {
|
||||
const projectRoot = await scaffoldMigrationProject('vuecli4-vue2')
|
||||
|
||||
process.chdir(projectRoot)
|
||||
|
||||
const config = vueCliHandler({
|
||||
devServerConfig: {
|
||||
cypressConfig: { projectRoot } as Cypress.PluginConfigOptions,
|
||||
},
|
||||
} as any)
|
||||
|
||||
// Verify it's a Vue-specific webpack config by seeing if VueLoader is present.
|
||||
expect(config.plugins.find((plug) => plug.constructor.name === 'VueLoader'))
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,13 @@
|
||||
import { e2eProjectDirs } from '@packages/frontend-shared/cypress/e2e/support/e2eProjectDirs'
|
||||
import Fixtures from '@tooling/system-tests/lib/fixtures'
|
||||
import * as FixturesScaffold from '@tooling/system-tests/lib/dep-installer'
|
||||
|
||||
export async function scaffoldMigrationProject (project: typeof e2eProjectDirs[number]) {
|
||||
Fixtures.removeProject(project)
|
||||
|
||||
await Fixtures.scaffoldProject(project)
|
||||
|
||||
await FixturesScaffold.scaffoldProjectNodeModules(project)
|
||||
|
||||
return Fixtures.projectPath(project)
|
||||
}
|
||||
181
packages/frontend-shared/cypress/e2e/support/e2eProjectDirs.ts
Normal file
181
packages/frontend-shared/cypress/e2e/support/e2eProjectDirs.ts
Normal file
@@ -0,0 +1,181 @@
|
||||
/* eslint-disable */
|
||||
// Auto-generated by gulpE2ETestScaffold.ts
|
||||
export const e2eProjectDirs = [
|
||||
'browser-extensions',
|
||||
'busted-support-file',
|
||||
'chrome-browser-preferences',
|
||||
'component-tests',
|
||||
'config-cjs-and-esm',
|
||||
'config-update-non-migrated-value',
|
||||
'config-update-non-migrated-value-clone',
|
||||
'config-update-non-migrated-value-e2e',
|
||||
'config-with-base-url-warning',
|
||||
'config-with-custom-file-js',
|
||||
'config-with-custom-file-ts',
|
||||
'config-with-import-error',
|
||||
'config-with-invalid-browser',
|
||||
'config-with-invalid-viewport',
|
||||
'config-with-js',
|
||||
'config-with-short-timeout',
|
||||
'config-with-ts',
|
||||
'config-with-ts-syntax-error',
|
||||
'cookies',
|
||||
'create-react-app-configured',
|
||||
'create-react-app-custom-index-html',
|
||||
'create-react-app-unconfigured',
|
||||
'cypress-in-cypress',
|
||||
'default-layout',
|
||||
'devServer-dynamic-import',
|
||||
'downloads',
|
||||
'e2e',
|
||||
'empty-folders',
|
||||
'experimental-studio',
|
||||
'failures',
|
||||
'firefox-memory',
|
||||
'fixture-subfolder-of-integration',
|
||||
'folder-same-as-fixture',
|
||||
'hooks-after-rerun',
|
||||
'ids',
|
||||
'integration-outside-project-root',
|
||||
'invalid-root-level-config',
|
||||
'issue-8111-iframe-input',
|
||||
'kill-child-process',
|
||||
'launchpad',
|
||||
'max-listeners',
|
||||
'migration',
|
||||
'migration-component-testing',
|
||||
'migration-component-testing-customized',
|
||||
'migration-component-testing-defaults',
|
||||
'migration-custom-config-file-migration-already-ocurred',
|
||||
'migration-custom-config-file-respect-dirname',
|
||||
'migration-custom-config-file-respect-pathname',
|
||||
'migration-custom-config-file-root-level',
|
||||
'migration-custom-config-file-with-existing-v10-config-file',
|
||||
'migration-e2e-cjsx',
|
||||
'migration-e2e-coffeescript',
|
||||
'migration-e2e-component-default-everything',
|
||||
'migration-e2e-component-default-test-files',
|
||||
'migration-e2e-component-default-with-types',
|
||||
'migration-e2e-component-with-json-files',
|
||||
'migration-e2e-custom-integration',
|
||||
'migration-e2e-custom-test-files',
|
||||
'migration-e2e-defaults',
|
||||
'migration-e2e-defaults-no-specs',
|
||||
'migration-e2e-duplicated-spec-names',
|
||||
'migration-e2e-export-default',
|
||||
'migration-e2e-false-plugins-support-file',
|
||||
'migration-e2e-fully-custom',
|
||||
'migration-e2e-legacy-plugins-throws-error',
|
||||
'migration-e2e-no-plugins-support-file',
|
||||
'migration-e2e-plugins-modify-config',
|
||||
'migration-specs-already-migrated',
|
||||
'migration-typescript-project',
|
||||
'module-api',
|
||||
'multiple-config-files-with-json',
|
||||
'multiple-support-files',
|
||||
'multiple-task-registrations',
|
||||
'nextjs-configured',
|
||||
'nextjs-unconfigured',
|
||||
'no-scaffolding',
|
||||
'no-server',
|
||||
'no-specs',
|
||||
'no-specs-custom-pattern',
|
||||
'no-specs-no-storybook',
|
||||
'no-support-file',
|
||||
'non-existent-spec',
|
||||
'non-proxied',
|
||||
'nuxtjs-vue2-configured',
|
||||
'nuxtjs-vue2-unconfigured',
|
||||
'nuxtjs2',
|
||||
'odd-directory-name',
|
||||
'plugin-after-screenshot',
|
||||
'plugin-after-spec-deletes-video',
|
||||
'plugin-before-browser-launch-deprecation',
|
||||
'plugin-browser',
|
||||
'plugin-config',
|
||||
'plugin-config-version',
|
||||
'plugin-empty',
|
||||
'plugin-event-deprecated',
|
||||
'plugin-extension',
|
||||
'plugin-filter-browsers',
|
||||
'plugin-invalid-event-handler-error',
|
||||
'plugin-no-function-return',
|
||||
'plugin-retries',
|
||||
'plugin-returns-bad-config',
|
||||
'plugin-returns-empty-browsers-list',
|
||||
'plugin-returns-invalid-browser',
|
||||
'plugin-run-event-throws',
|
||||
'plugin-run-events',
|
||||
'plugin-validation-error',
|
||||
'plugins-absolute-path',
|
||||
'plugins-async-error',
|
||||
'plugins-function-sync-error',
|
||||
'plugins-root-async-error',
|
||||
'plugins-root-sync-error',
|
||||
'pristine',
|
||||
'pristine-npm',
|
||||
'pristine-pnpm',
|
||||
'pristine-with-ct-testing',
|
||||
'pristine-with-e2e-testing',
|
||||
'pristine-with-e2e-testing-and-storybook',
|
||||
'pristine-yarn',
|
||||
'react-a11y',
|
||||
'react-app-webpack-5-unconfigured',
|
||||
'react-code-gen',
|
||||
'react-tailwind',
|
||||
'react-vite-ts-configured',
|
||||
'react-vite-ts-unconfigured',
|
||||
'read-only-project-root',
|
||||
'record',
|
||||
'remote-debugging-disconnect',
|
||||
'remote-debugging-port-removed',
|
||||
'retries-2',
|
||||
'runner-e2e-specs',
|
||||
'same-fixtures-integration-folders',
|
||||
'screen-size',
|
||||
'selectFile',
|
||||
'shadow-dom-global-inclusion',
|
||||
'simple-ct',
|
||||
'spec-generation',
|
||||
'spec-name-special-characters',
|
||||
'studio',
|
||||
'studio-no-source-maps',
|
||||
'system-node',
|
||||
'task-not-registered',
|
||||
'todos',
|
||||
'ts-installed',
|
||||
'ts-proj',
|
||||
'ts-proj-4-5',
|
||||
'ts-proj-custom-names',
|
||||
'ts-proj-esmoduleinterop-true',
|
||||
'ts-proj-tsconfig-in-plugins',
|
||||
'ts-proj-with-module-esnext',
|
||||
'ts-proj-with-paths',
|
||||
'uncaught-support-file',
|
||||
'unify-plugin-errors',
|
||||
'various-file-types',
|
||||
'vite-ct',
|
||||
'vue3-vite-ts-configured',
|
||||
'vue3-vite-ts-custom-index-html',
|
||||
'vue3-vite-ts-unconfigured',
|
||||
'vuecli4-vue2',
|
||||
'vuecli5-vue3',
|
||||
'vuecli5vue3-configured',
|
||||
'vuecli5vue3-unconfigured',
|
||||
'vueclivue2-configured',
|
||||
'vueclivue2-unconfigured',
|
||||
'vueclivue3-configured',
|
||||
'vueclivue3-custom-index-html',
|
||||
'vueclivue3-unconfigured',
|
||||
'webpack-dev-server',
|
||||
'webpack-preprocessor',
|
||||
'webpack-preprocessor-awesome-typescript-loader',
|
||||
'webpack-preprocessor-ts-loader',
|
||||
'webpack-preprocessor-ts-loader-compiler-options',
|
||||
'webpack4_wds3-react',
|
||||
'webpack4_wds4-react',
|
||||
'webpack5_wds3-react',
|
||||
'webpack5_wds4-react',
|
||||
'working-preprocessor',
|
||||
'yarn-v3.1.1-pnp'
|
||||
] as const
|
||||
@@ -0,0 +1,7 @@
|
||||
import { mount } from 'cypress/vue2'
|
||||
import Tutorial from './Tutorial.vue'
|
||||
|
||||
it('works', () => {
|
||||
mount(Tutorial)
|
||||
cy.contains('Nuxt')
|
||||
})
|
||||
@@ -0,0 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
Nuxt
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'NuxtTutorial'
|
||||
}
|
||||
</script>
|
||||
8
system-tests/project-fixtures/nuxtjs2/cypress.config.js
Normal file
8
system-tests/project-fixtures/nuxtjs2/cypress.config.js
Normal file
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
component: {
|
||||
devServer: {
|
||||
framework: 'nuxt',
|
||||
bundler: 'webpack'
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Components App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="__cy_root"></div>
|
||||
</body>
|
||||
</html>
|
||||
1
system-tests/project-fixtures/nuxtjs2/nuxt.config.js
Normal file
1
system-tests/project-fixtures/nuxtjs2/nuxt.config.js
Normal file
@@ -0,0 +1 @@
|
||||
export default {}
|
||||
9
system-tests/project-fixtures/nuxtjs2/pages/index.vue
Normal file
9
system-tests/project-fixtures/nuxtjs2/pages/index.vue
Normal file
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<Tutorial/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'IndexPage'
|
||||
}
|
||||
</script>
|
||||
8
system-tests/project-fixtures/vue-cli/cypress.config.js
Normal file
8
system-tests/project-fixtures/vue-cli/cypress.config.js
Normal file
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
component: {
|
||||
devServer: {
|
||||
framework: 'vue-cli',
|
||||
bundler: 'webpack'
|
||||
}
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<title>Components App</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="__cy_root"></div>
|
||||
</body>
|
||||
</html>
|
||||
17
system-tests/project-fixtures/vue-cli/public/index.html
Normal file
17
system-tests/project-fixtures/vue-cli/public/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,16 @@
|
||||
import { mount } from 'cypress/vue'
|
||||
import HelloWorld from './HelloWorld.vue'
|
||||
|
||||
describe('<Logo />', () => {
|
||||
it('contains the default slot in its h1', () => {
|
||||
const slotContent = 'Welcome to testing in Vue CLI'
|
||||
|
||||
mount(HelloWorld, {
|
||||
propsData: {
|
||||
msg: slotContent,
|
||||
},
|
||||
})
|
||||
|
||||
cy.contains('h1', slotContent)
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br>
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped>
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
||||
11
system-tests/projects/nuxtjs2/package.json
Normal file
11
system-tests/projects/nuxtjs2/package.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"core-js": "^3.19.3",
|
||||
"nuxt": "^2.15.8",
|
||||
"vue": "^2.6.14",
|
||||
"vue-server-renderer": "^2.6.14",
|
||||
"vue-template-compiler": "^2.6.14",
|
||||
"webpack": "^4.46.0"
|
||||
},
|
||||
"projectFixtureDirectory": "nuxtjs2"
|
||||
}
|
||||
7908
system-tests/projects/nuxtjs2/yarn.lock
Normal file
7908
system-tests/projects/nuxtjs2/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
10
system-tests/projects/vuecli4-vue2/package.json
Normal file
10
system-tests/projects/vuecli4-vue2/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"vue": "^2.6.11"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-service": "~4.5.17",
|
||||
"vue-template-compiler": "^2.6.11"
|
||||
},
|
||||
"projectFixtureDirectory": "vue-cli"
|
||||
}
|
||||
6768
system-tests/projects/vuecli4-vue2/yarn.lock
Normal file
6768
system-tests/projects/vuecli4-vue2/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
10
system-tests/projects/vuecli4-vue3/package.json
Normal file
10
system-tests/projects/vuecli4-vue3/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"vue": "^3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-service": "~4.5.17",
|
||||
"@vue/compiler-sfc": "^3.0.0"
|
||||
},
|
||||
"projectFixtureDirectory": "vue-cli"
|
||||
}
|
||||
6897
system-tests/projects/vuecli4-vue3/yarn.lock
Normal file
6897
system-tests/projects/vuecli4-vue3/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
9
system-tests/projects/vuecli5-vue3/package.json
Normal file
9
system-tests/projects/vuecli5-vue3/package.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"vue": "^3.2.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-service": "~5.0.0"
|
||||
},
|
||||
"projectFixtureDirectory": "vue-cli"
|
||||
}
|
||||
4205
system-tests/projects/vuecli5-vue3/yarn.lock
Normal file
4205
system-tests/projects/vuecli5-vue3/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -11189,10 +11189,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.31.tgz#c90de7126d833dcd3a4c7534d534be2fb41faa4e"
|
||||
integrity sha512-ymN2pj6zEjiKJZbrf98UM2pfDd6F2H7ksKw7NDt/ZZ1fh5Ei39X5tABugtT03ZRlWd9imccoK0hE8hpjpU7irQ==
|
||||
|
||||
"@vue/test-utils@^2.0.0-rc.10":
|
||||
version "2.0.0-rc.10"
|
||||
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.0.0-rc.10.tgz#9ed689cd7d5a1c9ef6693806010e464d2ecc13b2"
|
||||
integrity sha512-Z8jY+askU08svsI37NcJSLmWrfkZ/1ATA1DENWezRUX2uv3QyEj7idwx+rfeNSOrlNNBh4NTzypBKOUOklxBRA==
|
||||
"@vue/test-utils@2.0.0-rc.19":
|
||||
version "2.0.0-rc.19"
|
||||
resolved "https://registry.yarnpkg.com/@vue/test-utils/-/test-utils-2.0.0-rc.19.tgz#cd10480b695027481981085c3f705081495a7ca0"
|
||||
integrity sha512-vQ/34z9NH/pqJzl9YTWtTq/vrx5JzLbMojcBB0qydeb7FtGqxp11nLYCgVso+pa8ZOSn2j+OQfjc5aBnb32uzw==
|
||||
|
||||
"@vue/web-component-wrapper@^1.2.0":
|
||||
version "1.3.0"
|
||||
|
||||
Reference in New Issue
Block a user