Skip to content

Commit c34e57b

Browse files
authored
misc: convert @cypress/webpack-dev-server tests to vitest. Additionally, uses tsx to import ESM only packages into @cypress/webpack-dev-server (#32878)
* chore: convert webpack-dev-server tests to vitest * Update npm/webpack-dev-server/test/devServer-e2e.spec.ts * Update npm/webpack-dev-server/src/helpers/angularHandler.ts
1 parent 7914233 commit c34e57b

17 files changed

+226
-305
lines changed

guides/esm-migration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ When migrating some of these projects away from the `ts-node` entry [see `@packa
8989
- [x] npm/puppeteer ✅ **COMPLETED**
9090
- [x] npm/vite-dev-server ✅ **COMPLETED**
9191
- [ ] npm/webpack-batteries-included-preprocessor
92-
- [ ] npm/webpack-dev-server
92+
- [x] npm/webpack-dev-server**COMPLETED**
9393
- [ ] npm/webpack-preprocessor
9494

9595
##### Binary Packages

npm/webpack-dev-server/__snapshots__/makeWebpackConfig.spec.ts.js

Lines changed: 0 additions & 25 deletions
This file was deleted.

npm/webpack-dev-server/package.json

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"cypress:run-cypress-in-cypress": "cross-env CYPRESS_INTERNAL_E2E_TESTING_SELF_PARENT_PROJECT=1 HTTP_PROXY_TARGET_FOR_ORIGIN_REQUESTS=http://localhost:4455 CYPRESS_REMOTE_DEBUGGING_PORT=6666 TZ=America/New_York",
1414
"dev": "tsc --watch",
1515
"lint": "eslint --ext .js,.ts,.json, .",
16-
"test": "yarn test-unit",
17-
"test-unit": "mocha -r ts-node/register/transpile-only --config ./test/.mocharc.js"
16+
"test": "vitest run",
17+
"test-debug": "vitest --inspect-brk --no-file-parallelism --test-timeout=0"
1818
},
1919
"dependencies": {
2020
"find-up": "6.3.0",
@@ -24,6 +24,7 @@
2424
"semver": "^7.7.1",
2525
"speed-measure-webpack-plugin": "1.4.2",
2626
"tslib": "^2.3.1",
27+
"tsx": "^4.20.6",
2728
"webpack-bundle-analyzer": "4.10.2",
2829
"webpack-dev-server": "^5.1.0",
2930
"webpack-merge": "^5.4.0"
@@ -32,13 +33,9 @@
3233
"@types/node": "22.18.7",
3334
"@types/speed-measure-webpack-plugin": "^1.3.4",
3435
"@types/webpack-bundle-analyzer": "4.7.0",
35-
"chai": "^4.3.6",
3636
"cross-env": "7.0.3",
3737
"dedent": "^0.7.0",
38-
"mocha": "^9.2.2",
39-
"sinon": "^13.0.1",
40-
"snap-shot-it": "^7.9.10",
41-
"ts-node": "^10.9.2",
38+
"vitest": "^3.2.4",
4239
"webpack": "npm:webpack@^5"
4340
},
4441
"peerDependencies": {

npm/webpack-dev-server/src/dynamic-import.ts

Lines changed: 0 additions & 13 deletions
This file was deleted.

npm/webpack-dev-server/src/helpers/angularHandler.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { tmpdir } from 'os'
33
import * as path from 'path'
44
import type { Configuration, RuleSetRule } from 'webpack'
55
import type { PresetHandlerResult, WebpackDevServerConfig } from '../devServer'
6-
import { dynamicAbsoluteImport, dynamicImport } from '../dynamic-import'
76
import { sourceDefaultWebpackDependencies } from './sourceRelativeWebpackModules'
87
import debugLib from 'debug'
98
import type { logging as AngularLogging } from '@angular-devkit/core'
@@ -182,11 +181,17 @@ export async function getAngularCliModules (projectRoot: string) {
182181
{ getCommonConfig },
183182
{ getStylesConfig },
184183
{ logging },
185-
] = await Promise.all(angularCLiModules.map((dep) => {
184+
] = await Promise.all(angularCLiModules.map(async (dep) => {
186185
try {
187186
const depPath = require.resolve(dep, { paths: [projectRoot] })
187+
// NOTE: @cypress/webpack-dev-server is a CJS package, but we need to import some ESM files and absolute imports.
188+
// since import statements in TypeScript will get transpiled down to CommonJS require statements, we want to use tsx to leverage
189+
// an ESM style import here, which supports CommonJS and ESM.
190+
const { tsImport } = require('tsx/esm/api')
188191

189-
return dynamicAbsoluteImport(depPath)
192+
const module = await tsImport(depPath, __filename)
193+
194+
return module
190195
} catch (e) {
191196
throw new Error(`Could not resolve "${dep}". Do you have "@angular-devkit/build-angular" and "@angular-devkit/core" installed?`)
192197
}
@@ -201,7 +206,12 @@ export async function getAngularCliModules (projectRoot: string) {
201206
}
202207

203208
export async function getAngularJson (projectRoot: string): Promise<AngularJson> {
204-
const { findUp } = await dynamicImport<typeof import('find-up')>('find-up')
209+
// NOTE: @cypress/webpack-dev-server is a CJS package, but find-up +6.0.0 is an ESM only package.
210+
// In order to dynamically import the find-up package, we need to use tsx to do so until @cypress/webpack-dev-server is an ESM-only package,
211+
// which would be a breaking change to @cypress/webpack-dev-server and cypress.
212+
const { tsImport } = require('tsx/esm/api')
213+
214+
const { findUp } = await tsImport('find-up', __filename) as typeof import('find-up')
205215

206216
const angularJsonPath = await findUp('angular.json', { cwd: projectRoot })
207217

npm/webpack-dev-server/src/makeWebpackConfig.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import type { Configuration, EntryObject } from 'webpack'
66
import { makeCypressWebpackConfig } from './makeDefaultWebpackConfig'
77
import type { CreateFinalWebpackConfig } from './createWebpackDevServer'
88
import { configFiles } from './constants'
9-
import { dynamicImport } from './dynamic-import'
109

1110
const debug = debugFn('cypress:webpack-dev-server:makeWebpackConfig')
1211

@@ -61,9 +60,16 @@ function modifyWebpackConfigForCypress (webpackConfig: Partial<Configuration>) {
6160
}
6261

6362
async function getWebpackConfigFromProjectRoot (projectRoot: string) {
64-
const { findUp } = await dynamicImport<typeof import('find-up')>('find-up')
63+
// NOTE: @cypress/webpack-dev-server is a CJS package, but find-up +6.0.0 is an ESM only package.
64+
// In order to dynamically import the find-up package, we need to use tsx to do so until @cypress/webpack-dev-server is an ESM-only package,
65+
// which would be a breaking change to @cypress/webpack-dev-server and cypress.
66+
const { tsImport } = require('tsx/esm/api')
6567

66-
return await findUp(configFiles, { cwd: projectRoot })
68+
const { findUp } = await tsImport('find-up', __filename) as typeof import('find-up')
69+
70+
const findUpResult = await findUp(configFiles, { cwd: projectRoot })
71+
72+
return findUpResult
6773
}
6874

6975
/**

npm/webpack-dev-server/test/.mocharc.js

Lines changed: 0 additions & 4 deletions
This file was deleted.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2+
3+
exports[`makeWebpackConfig > ignores userland webpack \`output.publicPath\` and \`devServer.overlay\` with webpack-dev-server v5 1`] = `
4+
{
5+
"devServer": {
6+
"client": {
7+
"overlay": false,
8+
"progress": false,
9+
},
10+
"port": undefined,
11+
},
12+
"devtool": "inline-source-map",
13+
"mode": "development",
14+
"optimization": {
15+
"emitOnErrors": true,
16+
"sideEffects": false,
17+
"splitChunks": {
18+
"chunks": "all",
19+
},
20+
},
21+
"output": {
22+
"filename": "[name].js",
23+
"publicPath": "/test-public-path/",
24+
},
25+
"plugins": [
26+
"HtmlWebpackPlugin",
27+
"CypressCTWebpackPlugin",
28+
],
29+
}
30+
`;

npm/webpack-dev-server/test/devServer-e2e.spec.ts

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1+
import { expect, it, describe, beforeEach, afterAll } from 'vitest'
12
import path from 'path'
2-
import { expect } from 'chai'
33
import { once, EventEmitter } from 'events'
44
import http from 'http'
55
import fs from 'fs-extra'
66

77
import { devServer } from '..'
88
import { restoreLoadHook } from '../src/helpers/sourceRelativeWebpackModules'
9-
import './support'
109
import type { ConfigHandler } from '../src/devServer'
1110

1211
const requestSpecFile = (file: string, port: number) => {
@@ -15,7 +14,7 @@ const requestSpecFile = (file: string, port: number) => {
1514
host: '127.0.0.1',
1615
port,
1716
path: encodeURI(file),
18-
}
17+
} as http.RequestOptions
1918

2019
const callback = (response: EventEmitter) => {
2120
let str = ''
@@ -29,7 +28,11 @@ const requestSpecFile = (file: string, port: number) => {
2928
})
3029
}
3130

32-
http.request(opts, callback).end()
31+
// give webpack a little time (200ms) to compile before sending the request so the spec is available in the file system.
32+
// alternative would be to listen to a compile event or check stdout to see if webpack compiled successfully
33+
setTimeout(() => {
34+
http.request(opts, callback).end()
35+
}, 200)
3336
})
3437
}
3538

@@ -71,13 +74,13 @@ const cypressConfig = {
7174
indexHtmlFile: 'test/component-index.html',
7275
} as any as Cypress.PluginConfigOptions
7376

74-
describe('#devServer', () => {
77+
describe('#devServer', { timeout: 5000 }, () => {
7578
beforeEach(() => {
7679
delete require.cache
7780
restoreLoadHook()
7881
})
7982

80-
after(() => {
83+
afterAll(() => {
8184
restoreLoadHook()
8285
})
8386

@@ -91,7 +94,7 @@ describe('#devServer', () => {
9194

9295
const response = await requestSpecFile('/test/fixtures/foo.spec.js', port as number)
9396

94-
expect(response).to.eq('const foo = () => {}\n')
97+
expect(response).toEqual('const foo = () => {}\n')
9598

9699
await closeServer(close)
97100
})
@@ -106,9 +109,9 @@ describe('#devServer', () => {
106109

107110
const response = await requestSpecFile('/test/fixtures/[foo]/bar.spec.js', port as number)
108111

109-
expect(response).to.eq(`it('this is a spec with a path containing []', () => {})\n`)
112+
expect(response).toEqual(`it('this is a spec with a path containing []', () => {})\n`)
110113

111-
return closeServer(close)
114+
await closeServer(close)
112115
})
113116

114117
it('serves specs in directory with non English chars via a webpack dev server', async () => {
@@ -121,9 +124,9 @@ describe('#devServer', () => {
121124

122125
const response = await requestSpecFile('/test/fixtures/サイプレス.spec.js', port as number)
123126

124-
expect(response).to.eq(`it('サイプレス', () => {})\n`)
127+
expect(response).toEqual(`it('サイプレス', () => {})\n`)
125128

126-
return closeServer(close)
129+
await closeServer(close)
127130
})
128131

129132
it('serves specs in directory with ... in the file name via a webpack dev server', async () => {
@@ -136,9 +139,9 @@ describe('#devServer', () => {
136139

137140
const response = await requestSpecFile('/test/fixtures/[...bar].spec.js', port as number)
138141

139-
expect(response).to.eq(`it('...bar', () => {})\n`)
142+
expect(response).toEqual(`it('...bar', () => {})\n`)
140143

141-
return closeServer(close)
144+
await closeServer(close)
142145
})
143146

144147
it('serves a file with spaces via a webpack dev server', async () => {
@@ -151,9 +154,9 @@ describe('#devServer', () => {
151154

152155
const response = await requestSpecFile('/test/fixtures/foo bar.spec.js', port as number)
153156

154-
expect(response).to.eq(`it('this is a spec with a path containing a space', () => {})\n`)
157+
expect(response).toEqual(`it('this is a spec with a path containing a space', () => {})\n`)
155158

156-
return closeServer(close)
159+
await closeServer(close)
157160
})
158161

159162
it('emits dev-server:compile:success event on successful compilation', async () => {
@@ -197,7 +200,7 @@ describe('#devServer', () => {
197200
await once(devServerEvents, 'dev-server:compile:success')
198201
const updatedmtime = fs.statSync(cypressConfig.indexHtmlFile).mtimeMs
199202

200-
expect(oldmtime).to.not.equal(updatedmtime)
203+
expect(oldmtime).not.toEqual(updatedmtime)
201204

202205
await closeServer(close)
203206
})
@@ -242,9 +245,9 @@ describe('#devServer', () => {
242245
const updated = await requestSpecFile('/__cypress/src/spec-0.js', port)
243246

244247
if (updateExpected) {
245-
expect(original, message).not.to.equal(updated)
248+
expect(original, message).not.toEqual(updated)
246249
} else {
247-
expect(original, message).to.equal(updated)
250+
expect(original, message).toEqual(updated)
248251
}
249252

250253
await closeServer(close)
@@ -267,9 +270,8 @@ describe('#devServer', () => {
267270

268271
const response = await requestSpecFile('/test/fixtures/foo.spec.js', port as number)
269272

270-
expect(response).to.eq('const foo = () => {}\n')
273+
expect(response).toEqual('const foo = () => {}\n')
271274

272275
await closeServer(close)
273276
})
274277
})
275-
.timeout(5000)

0 commit comments

Comments
 (0)