Skip to content

Commit

Permalink
feat: support vite v5 [run ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
AtofStryker committed May 14, 2024
1 parent 4768d4e commit 8a913dd
Show file tree
Hide file tree
Showing 28 changed files with 2,693 additions and 885 deletions.
11 changes: 6 additions & 5 deletions .circleci/workflows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ mainBuildFilters: &mainBuildFilters
- /^release\/\d+\.\d+\.\d+$/
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- 'update-v8-snapshot-cache-on-develop'
- chore/fix_kitchen_sink
- 'publish-binary'
- 'feat/vite_5_support'

# usually we don't build Mac app - it takes a long time
# but sometimes we want to really confirm we are doing the right thing
Expand All @@ -41,7 +42,7 @@ macWorkflowFilters: &darwin-workflow-filters
- equal: [ develop, << pipeline.git.branch >> ]
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
- equal: [ 'bump-electron-27.3.10', << pipeline.git.branch >> ]
- equal: [ 'feat/vite_5_support', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
Expand All @@ -52,7 +53,7 @@ linuxArm64WorkflowFilters: &linux-arm64-workflow-filters
- equal: [ develop, << pipeline.git.branch >> ]
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
- equal: [ 'bump-electron-27.3.10', << pipeline.git.branch >> ]
- equal: [ 'feat/vite_5_support', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
Expand All @@ -75,7 +76,7 @@ windowsWorkflowFilters: &windows-workflow-filters
- equal: [ develop, << pipeline.git.branch >> ]
# use the following branch as well to ensure that v8 snapshot cache updates are fully tested
- equal: [ 'update-v8-snapshot-cache-on-develop', << pipeline.git.branch >> ]
- equal: [ 'chore/update_internal_browser_images', << pipeline.git.branch >> ]
- equal: [ 'feat/vite_5_support', << pipeline.git.branch >> ]
- matches:
pattern: /^release\/\d+\.\d+\.\d+$/
value: << pipeline.git.branch >>
Expand Down Expand Up @@ -151,7 +152,7 @@ commands:
name: Set environment variable to determine whether or not to persist artifacts
command: |
echo "Setting SHOULD_PERSIST_ARTIFACTS variable"
echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "bump-electron-27.3.10" ]]; then
echo 'if ! [[ "$CIRCLE_BRANCH" != "develop" && "$CIRCLE_BRANCH" != "release/"* && "$CIRCLE_BRANCH" != "feat/vite_5_support" ]]; then
export SHOULD_PERSIST_ARTIFACTS=true
fi' >> "$BASH_ENV"
# You must run `setup_should_persist_artifacts` command and be using bash before running this command
Expand Down
6 changes: 5 additions & 1 deletion cli/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
<!-- See the ../guides/writing-the-cypress-changelog.md for details on writing the changelog. -->
## 13.9.1
## 13.10.0

_Released 5/21/2024 (PENDING)_

**Features:**

- Added support for `vite` `v5` to `@cypress/vite-dev-server`. Addresses [#28347](https://github.com/cypress-io/cypress/issues/28347).

**Bugfixes:**

- Fixed an issue where Cypress was unable to search in the Specs list for files or folders containing numbers. Fixes [#29034](https://github.com/cypress-io/cypress/issues/29034).
Expand Down
23 changes: 19 additions & 4 deletions npm/vite-dev-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,25 @@ We then merge the sourced config with the user's vite config, and layer on our o

## Compatibility

| @cypress/vite-dev-server | cypress |
| ------------------------ | ------- |
| <= v2 | <= v9 |
| >= v3 | >= v10 |
| @cypress/vite-dev-server | cypress |
| ------------------------ | --------------- |
| <= v2 | <= v9 |
| v3, v4 | >=v10 <=13.10.0 |
| v5 | >= v13.10.0 |

#### `devServerPublicPathRoute` for Vite v5

If using Vite version 5, setting `devServerPublicPathRoute` to `''` is needed if directly referencing public path url assets in components under test. This can be configured within the `component` namespace below:

```ts
import { defineConfig } from 'cypress'

export default defineConfig({
component: {
devServerPublicPathRoute: ''
}
})
```

## License

Expand Down
5 changes: 3 additions & 2 deletions npm/vite-dev-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@
"mocha": "^9.2.2",
"sinon": "^13.0.1",
"ts-node": "^10.9.2",
"vite": "4.5.2",
"vite-plugin-inspect": "0.7.24"
"vite-4": "npm:vite@^4.5.2",
"vite-5": "npm:vite@^5.2.8",
"vite-plugin-inspect": "0.8.4"
},
"files": [
"dist",
Expand Down
13 changes: 11 additions & 2 deletions npm/vite-dev-server/src/devServer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import debugFn from 'debug'
import type { UserConfig } from 'vite'
import semverMajor from 'semver/functions/major'
import type { UserConfig } from 'vite-5'
import { getVite, Vite } from './getVite'
import { createViteDevServerConfig } from './resolveConfig'

Expand All @@ -8,7 +9,6 @@ const debug = debugFn('cypress:vite-dev-server:devServer')
const ALL_FRAMEWORKS = ['react', 'vue'] as const

type ConfigHandler = UserConfig | (() => UserConfig | Promise<UserConfig>)

export type ViteDevServerConfig = {
specs: Cypress.Spec[]
cypressConfig: Cypress.PluginConfigOptions
Expand All @@ -23,6 +23,15 @@ export async function devServer (config: ViteDevServerConfig): Promise<Cypress.R
// This has to be the first thing we do as we need to source vite from their project's dependencies
const vite = getVite(config)

let majorVersion: number | undefined = undefined

if (vite.version) {
majorVersion = semverMajor(vite.version)
debug(`Found vite version v${majorVersion}`)
} else {
debug(`vite version not found`)
}

debug('Creating Vite Server')
const server = await devServer.create(config, vite)

Expand Down
2 changes: 1 addition & 1 deletion npm/vite-dev-server/src/getVite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { ViteDevServerConfig } from './devServer'

const debug = debugFn('cypress:vite-dev-server:getVite')

export type Vite = typeof import('vite')
export type Vite = typeof import('vite-5')

// "vite-dev-server" is bundled in the binary, so we need to require.resolve "vite"
// from root of the active project since we don't bundle vite internally but rather
Expand Down
4 changes: 2 additions & 2 deletions npm/vite-dev-server/src/plugins/cypress.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import debugFn from 'debug'
import type { ModuleNode, Plugin, ViteDevServer } from 'vite'
import type { ModuleNode, PluginOption, ViteDevServer } from 'vite-5'
import type { Vite } from '../getVite'
import { parse, HTMLElement } from 'node-html-parser'
import fs from 'fs'
Expand Down Expand Up @@ -27,7 +27,7 @@ function getSpecsPathsSet (specs: Spec[]) {
export const Cypress = (
options: ViteDevServerConfig,
vite: Vite,
): Plugin => {
): PluginOption => {
let base = '/'

const projectRoot = options.cypressConfig.projectRoot
Expand Down
4 changes: 2 additions & 2 deletions npm/vite-dev-server/src/plugins/sourcemap.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import debugFn from 'debug'
import type { Plugin } from 'vite'
import type { PluginOption } from 'vite-5'
import type { Vite } from '../getVite'

import type { ViteDevServerConfig } from '../devServer'
Expand All @@ -9,7 +9,7 @@ const debug = debugFn('cypress:vite-dev-server:plugins:sourcemap')
export const CypressSourcemap = (
options: ViteDevServerConfig,
vite: Vite,
): Plugin => {
): PluginOption => {
return {
name: 'cypress:sourcemap',
enforce: 'post',
Expand Down
4 changes: 2 additions & 2 deletions npm/vite-dev-server/src/resolveConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* You can find it here https://github.com/vitest-dev/vitest/blob/main/packages/vitest/src/node/create.ts
*/
import debugFn from 'debug'
import type { InlineConfig } from 'vite'
import type { InlineConfig } from 'vite-5'
import path from 'path'
import semverGte from 'semver/functions/gte'

Expand Down Expand Up @@ -62,7 +62,7 @@ export const createViteDevServerConfig = async (config: ViteDevServerConfig, vit
return finalConfig
}

function makeCypressViteConfig (config: ViteDevServerConfig, vite: Vite): InlineConfig {
function makeCypressViteConfig (config: ViteDevServerConfig, vite: Vite): InlineConfig | InlineConfig {
const {
cypressConfig: {
port,
Expand Down
111 changes: 58 additions & 53 deletions npm/vite-dev-server/test/resolveConfig.spec.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import Chai, { expect } from 'chai'
import { EventEmitter } from 'events'
import * as vite from 'vite'
import * as vite4 from 'vite-4'
import * as vite5 from 'vite-5'
import { scaffoldSystemTestProject } from './test-helpers/scaffoldProject'
import { createViteDevServerConfig } from '../src/resolveConfig'
import sinon from 'sinon'
import SinonChai from 'sinon-chai'
import type { ViteDevServerConfig } from '../src/devServer'

type Vite = typeof import('vite-5')
Chai.use(SinonChai)

const getViteDevServerConfig = (projectRoot: string) => {
Expand All @@ -21,80 +23,83 @@ const getViteDevServerConfig = (projectRoot: string) => {
framework: 'react',
} as unknown as ViteDevServerConfig
}
const MAJOR_VERSIONS: [4, 5] = [4, 5]

describe('resolveConfig', function () {
this.timeout(1000 * 60)

context('config resolution', () => {
it('with <project-root>/vite.config.js', async () => {
const projectRoot = await scaffoldSystemTestProject('vite-inspect')
const viteDevServerConfig = getViteDevServerConfig(projectRoot)
MAJOR_VERSIONS.forEach((version) => {
context(`config resolution: v${version}`, () => {
it('with <project-root>/vite.config.js', async () => {
const projectRoot = await scaffoldSystemTestProject(`vite${version}-inspect`)
const viteDevServerConfig = getViteDevServerConfig(projectRoot)

const viteConfig = await createViteDevServerConfig(viteDevServerConfig, vite)
const viteConfig = await createViteDevServerConfig(viteDevServerConfig, version === 5 ? vite5 : (vite4 as unknown as Vite))

expect(viteConfig.configFile).to.contain('vite-inspect')
expect(viteConfig.plugins.map((p: any) => p.name)).to.have.members(['cypress:main', 'cypress:sourcemap'])
})
expect(viteConfig.configFile).to.contain(`vite${version}-inspect`)
expect(viteConfig.plugins.map((p: any) => p.name)).to.have.members(['cypress:main', 'cypress:sourcemap'])
})

it('with component.devServer.viteConfig provided', async () => {
const projectRoot = await scaffoldSystemTestProject('vite-inspect')
const inlineViteConfig = { base: '/will-be-overwritten', server: { port: 99999 } }
const viteDevServerConfig = { ...getViteDevServerConfig(projectRoot), viteConfig: inlineViteConfig }
it('with component.devServer.viteConfig provided', async () => {
const projectRoot = await scaffoldSystemTestProject(`vite${version}-inspect`)
const inlineViteConfig = { base: '/will-be-overwritten', server: { port: 99999 } }
const viteDevServerConfig = { ...getViteDevServerConfig(projectRoot), viteConfig: inlineViteConfig }

const viteConfig = await createViteDevServerConfig(viteDevServerConfig, vite)
const viteConfig = await createViteDevServerConfig(viteDevServerConfig, version === 5 ? vite5 : (vite4 as unknown as Vite))

expect(viteConfig.configFile).eq(false)
expect(viteConfig.base).eq('/__cypress/src/')
expect(viteConfig.server.port).eq(99999)
})
expect(viteConfig.configFile).eq(false)
expect(viteConfig.base).eq('/__cypress/src/')
expect(viteConfig.server.port).eq(99999)
})

it('calls viteConfig if it is a function', async () => {
const viteConfigFn = sinon.spy(async () => {
return {
server: {
fs: {
allow: ['some/other/file'],
it('calls viteConfig if it is a function', async () => {
const viteConfigFn = sinon.spy(async () => {
return {
server: {
fs: {
allow: ['some/other/file'],
},
},
},
}
})
}
})

const projectRoot = await scaffoldSystemTestProject('vite-inspect')
const viteDevServerConfig = {
...getViteDevServerConfig(projectRoot),
viteConfig: viteConfigFn,
}
const projectRoot = await scaffoldSystemTestProject(`vite${version}-inspect`)
const viteDevServerConfig = {
...getViteDevServerConfig(projectRoot),
viteConfig: viteConfigFn,
}

const viteConfig = await createViteDevServerConfig(viteDevServerConfig, vite)
const viteConfig = await createViteDevServerConfig(viteDevServerConfig, version === 5 ? vite5 : (vite4 as unknown as Vite))

expect(viteConfigFn).to.be.called
expect(viteConfig.server?.fs?.allow).to.include('some/other/file')
expect(viteConfigFn).to.be.called
expect(viteConfig.server?.fs?.allow).to.include('some/other/file')
})
})
})

context('file watching', () => {
let viteDevServerConfig: ViteDevServerConfig
context('file watching', () => {
let viteDevServerConfig: ViteDevServerConfig

beforeEach(async () => {
const projectRoot = await scaffoldSystemTestProject('vite-inspect')
beforeEach(async () => {
const projectRoot = await scaffoldSystemTestProject(`vite${version}-inspect`)

viteDevServerConfig = getViteDevServerConfig(projectRoot)
})
viteDevServerConfig = getViteDevServerConfig(projectRoot)
})

it('should be disabled in run mode', async () => {
viteDevServerConfig.cypressConfig.isTextTerminal = true
const viteConfig = await createViteDevServerConfig(viteDevServerConfig, vite)
it('should be disabled in run mode', async () => {
viteDevServerConfig.cypressConfig.isTextTerminal = true
const viteConfig = await createViteDevServerConfig(viteDevServerConfig, version === 5 ? vite5 : (vite4 as unknown as Vite))

expect(viteConfig.server?.watch?.ignored).to.eql('**/*')
expect(viteConfig.server?.hmr).to.be.false
})
expect(viteConfig.server?.watch?.ignored).to.eql('**/*')
expect(viteConfig.server?.hmr).to.be.false
})

it('uses defaults in open mode', async () => {
viteDevServerConfig.cypressConfig.isTextTerminal = false
const viteConfig = await createViteDevServerConfig(viteDevServerConfig, vite)
it('uses defaults in open mode', async () => {
viteDevServerConfig.cypressConfig.isTextTerminal = false
const viteConfig = await createViteDevServerConfig(viteDevServerConfig, version === 5 ? vite5 : (vite4 as unknown as Vite))

expect(viteConfig.server?.watch?.ignored).to.be.undefined
expect(viteConfig.server?.hmr).to.be.undefined
expect(viteConfig.server?.watch?.ignored).to.be.undefined
expect(viteConfig.server?.hmr).to.be.undefined
})
})
})
})
4 changes: 3 additions & 1 deletion npm/vite-dev-server/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@
"esModuleInterop": true,
/** Allows us to strip internal types sourced from webpack */
"stripInternal": true,
"importsNotUsedAsValues": "error"
"importsNotUsedAsValues": "error",
/* skips checking declaration types. we skip this because we have multiple versions of vite installed as dev dependencies */
"skipLibCheck": true,
},
"include": ["src"],
"exclude": ["node_modules", "*.js"]
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/errors/test/unit/visualSnapshotErrors_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1323,7 +1323,7 @@ describe('visual error templates', () => {
package: 'vite',
installer: 'vite',
description: 'Vite is dev server that serves your source files over native ES modules',
minVersion: '^=2.0.0 || ^=3.0.0 || ^=4.0.0',
minVersion: '^=2.0.0 || ^=3.0.0 || ^=4.0.0 || ^=5.0.0',
},
satisfied: false,
detectedVersion: '1.0.0',
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend-shared/src/components/highlight.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Highlighter, ILanguageRegistration } from 'shiki'
import { getHighlighter, setOnigasmWASM } from 'shiki'
import onigasm from 'onigasm/lib/onigasm.wasm?url'
import shikiCyTheme from '../public/shiki/themes/cypress.theme.json'
const langJSONFilesArray = import.meta.globEager('../public/shiki/languages/*.tmLanguage.json')
const langJSONFilesArray = import.meta.glob('../public/shiki/languages/*.tmLanguage.json', { eager: true })

// Convert to the format shiki needs for language customization.
// @see https://github.com/shikijs/shiki/blob/main/docs/languages.md
Expand Down
2 changes: 1 addition & 1 deletion packages/launchpad/cypress/e2e/config-warning.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ describe('component testing dependency warnings', () => {
cy.get('[data-cy-testingtype="component"]').click()
cy.get('[data-cy="warning-alert"]', { timeout: 12000 }).should('exist')
.should('contain.text', 'Warning: Component Testing Mismatched Dependencies')
.should('contain.text', 'vite. Expected ^2.0.0 || ^3.0.0 || ^4.0.0, found 2.0.0-beta.70')
.should('contain.text', 'vite. Expected ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0, found 2.0.0-beta.70')
.should('contain.text', 'react. Expected ^16.0.0 || ^17.0.0 || ^18.0.0, found 15.6.2.')
.should('contain.text', 'react-dom. Expected ^16.0.0 || ^17.0.0 || ^18.0.0 but dependency was not found.')

Expand Down
Loading

5 comments on commit 8a913dd

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 8a913dd May 14, 2024

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 arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.10.0/linux-arm64/feat/vite_5_support-8a913dda09b193393511ce8ee8a04a4e62ad1ce2/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 8a913dd May 14, 2024

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 build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.10.0/linux-x64/feat/vite_5_support-8a913dda09b193393511ce8ee8a04a4e62ad1ce2/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 8a913dd May 14, 2024

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 arm64 version of the Test Runner.

Learn more about this pre-release build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.10.0/darwin-arm64/feat/vite_5_support-8a913dda09b193393511ce8ee8a04a4e62ad1ce2/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 8a913dd May 14, 2024

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 build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.10.0/win32-x64/feat/vite_5_support-8a913dda09b193393511ce8ee8a04a4e62ad1ce2/cypress.tgz

@cypress-bot
Copy link
Contributor

@cypress-bot cypress-bot bot commented on 8a913dd May 14, 2024

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 build at https://on.cypress.io/advanced-installation#Install-pre-release-version

Run this command to install the pre-release locally:

npm install https://cdn.cypress.io/beta/npm/13.10.0/darwin-x64/feat/vite_5_support-8a913dda09b193393511ce8ee8a04a4e62ad1ce2/cypress.tgz

Please sign in to comment.