mirror of
https://github.com/cypress-io/cypress.git
synced 2026-01-29 10:29:27 -06:00
* removing vite-dev-server local dependency from react-vite-ts-configured system test * moving some CRA examples over to use the object api for setup * fixing issue where function API was broken by object API for cy config + devservers * adding deeply nested react import to project-fixtures for cra * finishes cutting over cypress/react for sys tests * chore: adding circle for this feature branch * chore: moving over many vue + vite system tests to use object API instead of function API (#21080) * doing webpack-dev-server cutovers * removing more webpack-dev-server refrences * fixing snapshots * bumping yarn.lock * wip * fix test * fix assertion Co-authored-by: Lachlan Miller <lachlan.miller.1990@outlook.com> * feat: removing all references for "fresh" dev servers (webpack-dev-server-fresh and vite-dev-server-fresh) (#21094) Co-authored-by: Lachlan Miller <lachlan.miller.1990@outlook.com> Co-authored-by: Zachary Williams <ZachJW34@gmail.com> * chore: add dev-servers as deps to server to be included in the binary (#21091) * fix bad merge * fix next types and webpack-dev-server- resolve Co-authored-by: Lachlan Miller <lachlan.miller.1990@outlook.com> Co-authored-by: Zachary Williams <ZachJW34@gmail.com>
281 lines
7.2 KiB
TypeScript
281 lines
7.2 KiB
TypeScript
import path from 'path'
|
|
import sinon from 'sinon'
|
|
import { expect } from 'chai'
|
|
import { once, EventEmitter } from 'events'
|
|
import http from 'http'
|
|
import fs from 'fs'
|
|
|
|
import { devServer } from '..'
|
|
import { restoreLoadHook } from '../src/helpers/sourceRelativeWebpackModules'
|
|
import './support'
|
|
|
|
const requestSpecFile = (file: string, port: number) => {
|
|
return new Promise((res) => {
|
|
const opts = {
|
|
host: 'localhost',
|
|
port,
|
|
path: encodeURI(file),
|
|
}
|
|
|
|
const callback = (response: EventEmitter) => {
|
|
let str = ''
|
|
|
|
response.on('data', (chunk) => {
|
|
str += chunk
|
|
})
|
|
|
|
response.on('end', () => {
|
|
res(str)
|
|
})
|
|
}
|
|
|
|
http.request(opts, callback).end()
|
|
})
|
|
}
|
|
|
|
const root = path.join(__dirname, '..')
|
|
|
|
const webpackConfig = {
|
|
devServer: { static: { directory: root } },
|
|
}
|
|
|
|
const createSpecs = (name: string): Cypress.Cypress['spec'][] => {
|
|
return [
|
|
{
|
|
name: `${root}/test/fixtures/${name}`,
|
|
relative: `${root}/test/fixtures/${name}`,
|
|
absolute: `${root}/test/fixtures/${name}`,
|
|
},
|
|
]
|
|
}
|
|
|
|
const cypressConfig = {
|
|
projectRoot: root,
|
|
supportFile: '',
|
|
isTextTerminal: true,
|
|
devServerPublicPathRoute: root,
|
|
indexHtmlFile: path.join(__dirname, 'component-index.html'),
|
|
} as any as Cypress.PluginConfigOptions
|
|
|
|
describe('#devServer', () => {
|
|
beforeEach(() => {
|
|
delete require.cache
|
|
restoreLoadHook()
|
|
})
|
|
|
|
after(() => {
|
|
restoreLoadHook()
|
|
})
|
|
|
|
it('serves specs via a webpack dev server', async () => {
|
|
const { port, close } = await devServer({
|
|
cypressConfig,
|
|
webpackConfig,
|
|
specs: createSpecs('foo.spec.js'),
|
|
devServerEvents: new EventEmitter(),
|
|
})
|
|
|
|
const response = await requestSpecFile('/test/fixtures/foo.spec.js', port as number)
|
|
|
|
expect(response).to.eq('const foo = () => {}\n')
|
|
|
|
await new Promise<void>((resolve, reject) => {
|
|
close((err) => {
|
|
if (err) {
|
|
return reject(err)
|
|
}
|
|
|
|
resolve()
|
|
})
|
|
})
|
|
})
|
|
|
|
it('serves specs in directory with [] chars via a webpack dev server', async () => {
|
|
const { port, close } = await devServer({
|
|
cypressConfig,
|
|
webpackConfig,
|
|
specs: createSpecs('[foo]/bar.spec.js'),
|
|
devServerEvents: new EventEmitter(),
|
|
})
|
|
|
|
const response = await requestSpecFile('/test/fixtures/[foo]/bar.spec.js', port as number)
|
|
|
|
expect(response).to.eq(`it('this is a spec with a path containing []', () => {})\n`)
|
|
|
|
return new Promise((res) => {
|
|
close(() => res())
|
|
})
|
|
})
|
|
|
|
it('serves specs in directory with non English chars via a webpack dev server', async () => {
|
|
const { port, close } = await devServer({
|
|
webpackConfig,
|
|
cypressConfig,
|
|
specs: createSpecs('サイプレス.spec.js'),
|
|
devServerEvents: new EventEmitter(),
|
|
})
|
|
|
|
const response = await requestSpecFile('/test/fixtures/サイプレス.spec.js', port as number)
|
|
|
|
expect(response).to.eq(`it('サイプレス', () => {})\n`)
|
|
|
|
return new Promise((res) => {
|
|
close(() => res())
|
|
})
|
|
})
|
|
|
|
it('serves specs in directory with ... in the file name via a webpack dev server', async () => {
|
|
const { port, close } = await devServer({
|
|
webpackConfig,
|
|
cypressConfig,
|
|
specs: createSpecs('[...bar].spec.js'),
|
|
devServerEvents: new EventEmitter(),
|
|
})
|
|
|
|
const response = await requestSpecFile('/test/fixtures/[...bar].spec.js', port as number)
|
|
|
|
expect(response).to.eq(`it('...bar', () => {})\n`)
|
|
|
|
return new Promise((res) => {
|
|
close(() => res())
|
|
})
|
|
})
|
|
|
|
it('serves a file with spaces via a webpack dev server', async () => {
|
|
const { port, close } = await devServer({
|
|
webpackConfig,
|
|
cypressConfig,
|
|
specs: createSpecs('foo bar.spec.js'),
|
|
devServerEvents: new EventEmitter(),
|
|
})
|
|
|
|
const response = await requestSpecFile('/test/fixtures/foo bar.spec.js', port as number)
|
|
|
|
expect(response).to.eq(`it('this is a spec with a path containing a space', () => {})\n`)
|
|
|
|
return new Promise((res) => {
|
|
close(() => res())
|
|
})
|
|
})
|
|
|
|
it('emits dev-server:compile:success event on successful compilation', async () => {
|
|
const devServerEvents = new EventEmitter()
|
|
const { close } = await devServer({
|
|
webpackConfig,
|
|
cypressConfig,
|
|
specs: createSpecs('foo.spec.js'),
|
|
devServerEvents,
|
|
})
|
|
|
|
await once(devServerEvents, 'dev-server:compile:success')
|
|
await new Promise<void>((resolve, reject) => {
|
|
close((err) => {
|
|
if (err) {
|
|
return reject(err)
|
|
}
|
|
|
|
resolve()
|
|
})
|
|
})
|
|
})
|
|
|
|
it('emits dev-server:compile:error event on error compilation', async () => {
|
|
const devServerEvents = new EventEmitter()
|
|
const exitSpy = sinon.stub(process, 'exit')
|
|
|
|
const badSpec = `${root}/test/fixtures/compilation-fails.spec.js`
|
|
const { close } = await devServer({
|
|
webpackConfig,
|
|
cypressConfig,
|
|
specs: [
|
|
{
|
|
name: badSpec,
|
|
relative: badSpec,
|
|
absolute: badSpec,
|
|
},
|
|
],
|
|
devServerEvents,
|
|
})
|
|
|
|
const [err] = await once(devServerEvents, 'dev-server:compile:error')
|
|
|
|
expect(err).to.contain('Module parse failed: Unexpected token (1:5)')
|
|
expect(err).to.contain('You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders')
|
|
expect(err).to.contain('> this is an invalid spec file')
|
|
expect(exitSpy.calledOnce).to.be.true
|
|
|
|
await new Promise<void>((resolve, reject) => {
|
|
close((err) => {
|
|
if (err) {
|
|
return reject(err)
|
|
}
|
|
|
|
resolve()
|
|
})
|
|
})
|
|
})
|
|
|
|
it('touches browser.js when a spec file is added and recompile', async function () {
|
|
const devServerEvents = new EventEmitter()
|
|
const { close } = await devServer({
|
|
webpackConfig,
|
|
cypressConfig,
|
|
specs: createSpecs('foo.spec.js'),
|
|
devServerEvents,
|
|
})
|
|
|
|
const newSpec: Cypress.Cypress['spec'] = {
|
|
name: `${root}/test/fixtures/bar.spec.js`,
|
|
relative: `${root}/test/fixtures/bar.spec.js`,
|
|
absolute: `${root}/test/fixtures/bar.spec.js`,
|
|
}
|
|
|
|
const oldmtime = fs.statSync('./dist/browser.js').mtimeMs
|
|
|
|
await once(devServerEvents, 'dev-server:compile:success')
|
|
devServerEvents.emit('dev-server:specs:changed', [newSpec])
|
|
|
|
await once(devServerEvents, 'dev-server:compile:success')
|
|
const updatedmtime = fs.statSync('./dist/browser.js').mtimeMs
|
|
|
|
expect(oldmtime).to.not.equal(updatedmtime)
|
|
|
|
await new Promise<void>((resolve, reject) => {
|
|
close((err) => {
|
|
if (err) {
|
|
return reject(err)
|
|
}
|
|
|
|
resolve()
|
|
})
|
|
})
|
|
})
|
|
|
|
it('accepts the devServer signature', async function () {
|
|
const devServerEvents = new EventEmitter()
|
|
const { port, close } = await devServer(
|
|
{
|
|
cypressConfig,
|
|
specs: createSpecs('foo.spec.js'),
|
|
devServerEvents,
|
|
webpackConfig,
|
|
},
|
|
)
|
|
|
|
const response = await requestSpecFile('/test/fixtures/foo.spec.js', port as number)
|
|
|
|
expect(response).to.eq('const foo = () => {}\n')
|
|
|
|
await new Promise<void>((resolve, reject) => {
|
|
close((err) => {
|
|
if (err) {
|
|
return reject(err)
|
|
}
|
|
|
|
resolve()
|
|
})
|
|
})
|
|
})
|
|
})
|
|
.timeout(5000)
|