Skip to content

Commit

Permalink
fix: make sure the cloned config doesn't reference the root config
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Dec 17, 2024
1 parent 1e41e34 commit 603e323
Show file tree
Hide file tree
Showing 24 changed files with 498 additions and 350 deletions.
2 changes: 1 addition & 1 deletion eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export default antfu(
'no-restricted-imports': [
'error',
{
paths: ['vitest', 'path'],
paths: ['vitest', 'path', 'vitest/node'],
},
],
},
Expand Down
20 changes: 4 additions & 16 deletions packages/browser/src/node/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import type { Plugin } from 'vitest/config'
import type { BrowserServer as IBrowserServer, TestProject } from 'vitest/node'
import type { TestProject } from 'vitest/node'
import c from 'tinyrainbow'
import { createViteLogger, createViteServer } from 'vitest/node'
import { version } from '../../package.json'
import BrowserPlugin from './plugin'
import { ParentBrowserProject } from './projectParent'
import { setupBrowserRpc } from './rpc'
import { BrowserServer } from './server'

export { distRoot } from './constants'
export { createBrowserPool } from './pool'

export type { BrowserServer } from './server'
export type { ProjectBrowser } from './project'

export async function createBrowserServer(
project: TestProject,
Expand All @@ -28,7 +28,7 @@ export async function createBrowserServer(
)
}

const server = new BrowserServer(project, '/')
const server = new ParentBrowserProject(project, '/')

const configPath = typeof configFile === 'string' ? configFile : false

Expand Down Expand Up @@ -77,15 +77,3 @@ export async function createBrowserServer(

return server
}

export function cloneBrowserServer(
project: TestProject,
browserServer: IBrowserServer,
) {
const clone = new BrowserServer(
project,
'/',
)
clone.setServer(browserServer.vite)
return clone
}
18 changes: 10 additions & 8 deletions packages/browser/src/node/middlewares/orchestratorMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
import type { Connect } from 'vite'
import type { BrowserServer } from '../server'
import type { ParentBrowserProject } from '../projectParent'
import { resolveOrchestrator } from '../serverOrchestrator'
import { allowIframes, disableCache } from './utils'

export function createOrchestratorMiddleware(browserServer: BrowserServer): Connect.NextHandleFunction {
export function createOrchestratorMiddleware(parentServer: ParentBrowserProject): Connect.NextHandleFunction {
return async function vitestOrchestratorMiddleware(req, res, next) {
if (!req.url) {
return next()
}
const url = new URL(req.url, 'http://localhost')
if (url.pathname !== browserServer.base) {
if (url.pathname !== parentServer.base) {
return next()
}

disableCache(res)
allowIframes(res)
const html = await resolveOrchestrator(parentServer, url, res)
if (html) {
disableCache(res)
allowIframes(res)

const html = await resolveOrchestrator(browserServer, url, res)
res.write(html, 'utf-8')
res.end()
res.write(html, 'utf-8')
res.end()
}
}
}
9 changes: 4 additions & 5 deletions packages/browser/src/node/middlewares/testerMiddleware.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { Connect } from 'vite'
import type { BrowserServer } from '../server'
import type { ParentBrowserProject } from '../projectParent'
import { resolveTester } from '../serverTester'
import { allowIframes, disableCache } from './utils'

export function createTesterMiddleware(browserServer: BrowserServer): Connect.NextHandleFunction {
export function createTesterMiddleware(browserServer: ParentBrowserProject): Connect.NextHandleFunction {
return async function vitestTesterMiddleware(req, res, next) {
if (!req.url) {
return next()
Expand All @@ -13,11 +13,10 @@ export function createTesterMiddleware(browserServer: BrowserServer): Connect.Ne
return next()
}

disableCache(res)
allowIframes(res)

const html = await resolveTester(browserServer, url, res, next)
if (html) {
disableCache(res)
allowIframes(res)
res.write(html, 'utf-8')
res.end()
}
Expand Down
96 changes: 50 additions & 46 deletions packages/browser/src/node/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Stats } from 'node:fs'
import type { HtmlTagDescriptor } from 'vite'
import type { Vitest } from 'vitest/node'
import type { BrowserServer } from './server'
import type { ParentBrowserProject } from './projectParent'
import { lstatSync, readFileSync } from 'node:fs'
import { createRequire } from 'node:module'
import { dynamicImportPlugin } from '@vitest/mocker/node'
Expand All @@ -21,9 +21,9 @@ export type { BrowserCommand } from 'vitest/node'

const versionRegexp = /(?:\?|&)v=\w{8}/

export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
export default (parentServer: ParentBrowserProject, base = '/'): Plugin[] => {
function isPackageExists(pkg: string, root: string) {
return browserServer.vitest.packageInstaller.isPackageExists?.(pkg, {
return parentServer.vitest.packageInstaller.isPackageExists?.(pkg, {
paths: [root],
})
}
Expand All @@ -33,7 +33,7 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
enforce: 'pre',
name: 'vitest:browser',
async configureServer(server) {
browserServer.setServer(server)
parentServer.setServer(server)

// eslint-disable-next-line prefer-arrow-callback
server.middlewares.use(function vitestHeaders(_req, res, next) {
Expand All @@ -45,8 +45,8 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
}
next()
})
server.middlewares.use(createOrchestratorMiddleware(browserServer))
server.middlewares.use(createTesterMiddleware(browserServer))
server.middlewares.use(createOrchestratorMiddleware(parentServer))
server.middlewares.use(createTesterMiddleware(parentServer))

server.middlewares.use(
`${base}favicon.svg`,
Expand All @@ -57,7 +57,7 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
},
)

const coverageFolder = resolveCoverageFolder(browserServer.vitest)
const coverageFolder = resolveCoverageFolder(parentServer.vitest)
const coveragePath = coverageFolder ? coverageFolder[1] : undefined
if (coveragePath && base === coveragePath) {
throw new Error(
Expand All @@ -81,12 +81,12 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
)
}

const screenshotFailures = browserServer.config.browser.ui && browserServer.config.browser.screenshotFailures
const uiEnabled = parentServer.config.browser.ui

if (screenshotFailures) {
if (uiEnabled) {
// eslint-disable-next-line prefer-arrow-callback
server.middlewares.use(`${base}__screenshot-error`, function vitestBrowserScreenshotError(req, res) {
if (!req.url || !browserServer.provider) {
if (!req.url) {
res.statusCode = 404
res.end()
return
Expand Down Expand Up @@ -152,17 +152,17 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
name: 'vitest:browser:tests',
enforce: 'pre',
async config() {
const project = browserServer.vitest.getProjectByName(browserServer.config.name)
const project = parentServer.vitest.getProjectByName(parentServer.config.name)
const { testFiles: allTestFiles } = await project.globTestFiles()
const browserTestFiles = allTestFiles.filter(
file => getFilePoolName(project, file) === 'browser',
)
const setupFiles = toArray(browserServer.config.setupFiles)
const setupFiles = toArray(project.config.setupFiles)

// replace env values - cannot be reassign at runtime
const define: Record<string, string> = {}
for (const env in (browserServer.config.env || {})) {
const stringValue = JSON.stringify(browserServer.config.env[env])
for (const env in (project.config.env || {})) {
const stringValue = JSON.stringify(project.config.env[env])
define[`import.meta.env.${env}`] = stringValue
}

Expand All @@ -173,7 +173,7 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
resolve(vitestDist, 'browser.js'),
resolve(vitestDist, 'runners.js'),
resolve(vitestDist, 'utils.js'),
...(browserServer.config.snapshotSerializers || []),
...(project.config.snapshotSerializers || []),
]

const exclude = [
Expand All @@ -199,22 +199,22 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
'msw/browser',
]

if (typeof browserServer.config.diff === 'string') {
entries.push(browserServer.config.diff)
if (typeof project.config.diff === 'string') {
entries.push(project.config.diff)
}

if (browserServer.vitest.coverageProvider) {
const coverage = browserServer.vitest.config.coverage
if (parentServer.vitest.coverageProvider) {
const coverage = parentServer.vitest.config.coverage
const provider = coverage.provider
if (provider === 'v8') {
const path = tryResolve('@vitest/coverage-v8', [browserServer.config.root])
const path = tryResolve('@vitest/coverage-v8', [parentServer.config.root])
if (path) {
entries.push(path)
exclude.push('@vitest/coverage-v8/browser')
}
}
else if (provider === 'istanbul') {
const path = tryResolve('@vitest/coverage-istanbul', [browserServer.config.root])
const path = tryResolve('@vitest/coverage-istanbul', [parentServer.config.root])
if (path) {
entries.push(path)
exclude.push('@vitest/coverage-istanbul')
Expand All @@ -235,7 +235,7 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
'@vitest/browser > @testing-library/dom',
]

const fileRoot = browserTestFiles[0] ? dirname(browserTestFiles[0]) : browserServer.config.root
const fileRoot = browserTestFiles[0] ? dirname(browserTestFiles[0]) : project.config.root

const svelte = isPackageExists('vitest-browser-svelte', fileRoot)
if (svelte) {
Expand Down Expand Up @@ -302,14 +302,14 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
}
},
transform(code, id) {
if (id.includes(browserServer.vite.config.cacheDir) && id.includes('loupe.js')) {
if (id.includes(parentServer.vite.config.cacheDir) && id.includes('loupe.js')) {
// loupe bundle has a nastry require('util') call that leaves a warning in the console
const utilRequire = 'nodeUtil = require_util();'
return code.replace(utilRequire, ' '.repeat(utilRequire.length))
}
},
},
BrowserContext(browserServer),
BrowserContext(parentServer),
dynamicImportPlugin({
globalThisAccessor: '"__vitest_browser_runner__"',
filter(id) {
Expand All @@ -329,7 +329,7 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
viteConfig.esbuild.legalComments = 'inline'
}

const defaultPort = browserServer.vitest._browserLastPort++
const defaultPort = parentServer.vitest._browserLastPort++

const api = resolveApiServerConfig(
viteConfig.test?.browser || {},
Expand All @@ -347,8 +347,8 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
viteConfig.server.fs.allow = viteConfig.server.fs.allow || []
viteConfig.server.fs.allow.push(
...resolveFsAllow(
browserServer.vitest.config.root,
browserServer.vitest.server.config.configFile,
parentServer.vitest.config.root,
parentServer.vitest.vite.config.configFile,
),
distRoot,
)
Expand All @@ -363,7 +363,7 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
{
name: 'vitest:browser:in-source-tests',
transform(code, id) {
const project = browserServer.vitest.getProjectByName(browserServer.config.name)
const project = parentServer.vitest.getProjectByName(parentServer.config.name)
if (!project.isCachedTestFile(id) || !code.includes('import.meta.vitest')) {
return
}
Expand Down Expand Up @@ -395,34 +395,38 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
name: 'vitest:browser:transform-tester-html',
enforce: 'pre',
async transformIndexHtml(html, ctx) {
if (ctx.filename !== browserServer.testerFilepath) {
const projectBrowser = [...parentServer.children].find((server) => {
return ctx.filename === server.testerFilepath
})
if (!projectBrowser) {
return
}

if (!browserServer.testerScripts) {
const testerScripts = await browserServer.formatScripts(
browserServer.config.browser.testerScripts,
if (!parentServer.testerScripts) {
const testerScripts = await parentServer.formatScripts(
parentServer.config.browser.testerScripts,
)
browserServer.testerScripts = testerScripts
parentServer.testerScripts = testerScripts
}
const stateJs = typeof browserServer.stateJs === 'string'
? browserServer.stateJs
: await browserServer.stateJs
const stateJs = typeof parentServer.stateJs === 'string'
? parentServer.stateJs
: await parentServer.stateJs

const testerTags: HtmlTagDescriptor[] = []
const isDefaultTemplate = resolve(distRoot, 'client/tester/tester.html') === browserServer.testerFilepath

const isDefaultTemplate = resolve(distRoot, 'client/tester/tester.html') === projectBrowser.testerFilepath
if (!isDefaultTemplate) {
const manifestContent = browserServer.manifest instanceof Promise
? await browserServer.manifest
: browserServer.manifest
const manifestContent = parentServer.manifest instanceof Promise
? await parentServer.manifest
: parentServer.manifest
const testerEntry = manifestContent['tester/tester.html']

testerTags.push({
tag: 'script',
attrs: {
type: 'module',
crossorigin: '',
src: `${browserServer.base}${testerEntry.file}`,
src: `${parentServer.base}${testerEntry.file}`,
},
injectTo: 'head',
})
Expand All @@ -434,7 +438,7 @@ export default (browserServer: BrowserServer, base = '/'): Plugin[] => {
{
tag: 'link',
attrs: {
href: `${browserServer.base}${entryManifest.file}`,
href: `${parentServer.base}${entryManifest.file}`,
rel: 'modulepreload',
crossorigin: '',
},
Expand Down Expand Up @@ -478,21 +482,21 @@ body {
tag: 'script',
attrs: {
type: 'module',
src: browserServer.errorCatcherUrl,
src: parentServer.errorCatcherUrl,
},
injectTo: 'head' as const,
},
browserServer.locatorsUrl
parentServer.locatorsUrl
? {
tag: 'script',
attrs: {
type: 'module',
src: browserServer.locatorsUrl,
src: parentServer.locatorsUrl,
},
injectTo: 'head',
} as const
: null,
...browserServer.testerScripts,
...parentServer.testerScripts,
...testerTags,
{
tag: 'script',
Expand Down
Loading

0 comments on commit 603e323

Please sign in to comment.