Skip to content

Commit

Permalink
chore: cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
sheremet-va committed Jan 31, 2024
1 parent b2fb744 commit 60baafc
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 54 deletions.
42 changes: 19 additions & 23 deletions packages/browser/src/client/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,25 @@ import { getConfig } from './utils'

const url = new URL(location.href)

const ID_ALL = '__vitest_all__'

const iframes = new Map<string, HTMLIFrameElement>()

function debug(...args: unknown[]) {
client.rpc.debug(...args.map(String))
const debug = getConfig().env.VITEST_BROWSER_DEBUG
if (debug && debug !== 'false')
client.rpc.debug(...args.map(String))
}

function createIframe(container: HTMLDivElement, version: number, file: string) {
function createIframe(container: HTMLDivElement, file: string) {
if (iframes.has(file)) {
container.removeChild(iframes.get(file)!)
iframes.delete(file)
}

const iframe = document.createElement('iframe')
iframe.setAttribute('loading', 'eager')
const queryName = file === 'all' ? '__vitest_all' : '__vitest_file'
iframe.setAttribute('src', `${url.pathname}__vitest_test__/tester.html?${queryName}=${file}&browserv=${version}`)
iframe.setAttribute('src', `${url.pathname}__vitest_test__/__test__/${encodeURIComponent(file)}`)
iframes.set(file, iframe)
container.appendChild(iframe)
return iframe
Expand All @@ -39,24 +42,19 @@ interface IframeErrorEvent {
type: 'error'
error: any
errorType: string
file: string
}

interface IframeStartEvent {
type: 'start'
files: string[]
}

interface IframeImportEvent {
type: 'import'
interface IframeInvalidEvent {
type: 'invalid'
id: number
}

type IframeChannelEvent = IframeDoneEvent | IframeErrorEvent | IframeStartEvent | IframeImportEvent
type IframeChannelEvent = IframeDoneEvent | IframeErrorEvent | IframeInvalidEvent

client.ws.addEventListener('open', async () => {
const config = getConfig()
const container = document.querySelector('#vitest-tester') as HTMLDivElement
const now = new Date().getTime()
// @ts-expect-error this is set in injector
const testFiles = window.__vi_files__ as string[]

Expand All @@ -81,20 +79,19 @@ client.ws.addEventListener('open', async () => {
await done()
break
}
// error happened at the top level, this should never happen in user code, but it can trigger during development
case 'error': {
iframes.delete(e.data.file)
const iframeId = e.data.files.length > 1 ? ID_ALL : e.data.files[0]
iframes.delete(iframeId)
await client.rpc.onUnhandledError(e.data.error, e.data.errorType)
if (e.data.file === 'all')
if (iframeId === ID_ALL)
runningFiles.clear()
else
runningFiles.delete(iframeId)
if (!runningFiles.size)
await done()
break
}
// skip known events
case 'start':
case 'import': {
break
}
default: {
await client.rpc.onUnhandledError({
name: 'Unexpected Event',
Expand All @@ -108,15 +105,14 @@ client.ws.addEventListener('open', async () => {
if (config.isolate === false) {
createIframe(
container,
now,
'all',
ID_ALL,
)
}
else {
// TODO: if cofnig.fileParallelism, then at the same time, otherwise one after another
for (const file of testFiles) {
createIframe(
container,
now,
file,
)
}
Expand Down
1 change: 1 addition & 0 deletions packages/browser/src/client/tester.html
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,6 @@
</head>
<body>
<script type="module" src="/tester.ts"></script>
{__VITEST_APPEND__}
</body>
</html>
21 changes: 10 additions & 11 deletions packages/browser/src/client/tester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import { loadSafeRpc } from './rpc'
import { VitestBrowserClientMocker } from './mocker'
import { registerUnexpectedErrors, registerUnhandledErrors, serializeError } from './unhandled'

channel.postMessage({ type: 'import' })

const stopErrorHandler = registerUnhandledErrors()

const url = new URL(location.href)
const reloadStart = url.searchParams.get('__reloadStart')

function debug(...args: unknown[]) {
client.rpc.debug(...args.map(String))
const debug = getConfig().env.VITEST_BROWSER_DEBUG
if (debug && debug !== 'false')
client.rpc.debug(...args.map(String))
}

async function tryCall<T>(fn: () => Promise<T>): Promise<T | false | undefined> {
Expand Down Expand Up @@ -182,13 +182,12 @@ async function runTests(files: string[]) {
}
}

function getTestFiles() {
if (url.searchParams.has('__vitest_all'))
// @ts-expect-error untyped global for internal use
return window.__vi_files__
const file = url.searchParams.get('__vitest_file')
// if it's actually a file path, use it
return file ? [file] : []
async function invalid(id: string) {
channel.postMessage({ type: 'invalid', id })
}

runTests(getTestFiles())
// @ts-expect-error untyped global for internal use
window.__vitest_browser_runner__ = {
runTests,
invalid,
}
11 changes: 7 additions & 4 deletions packages/browser/src/client/unhandled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@ import type { client } from './client'
import { channel } from './client'
import { importId } from './utils'

const url = new URL(location.href)
const file = url.searchParams.has('__vitest_all') ? 'all' : url.searchParams.get('__vitest_file')!

function on(event: string, listener: (...args: any[]) => void) {
window.addEventListener(event, listener)
return () => window.removeEventListener(event, listener)
Expand All @@ -18,10 +15,16 @@ export function serializeError(unhandledError: any) {
stack: String(unhandledError.stack),
}
}

function getFiles(): string[] {
// @ts-expect-error this is set in injector
return window.__vi_running_tests__
}

// we can't import "processError" yet because error might've been thrown before the module was loaded
async function defaultErrorReport(type: string, unhandledError: any) {
const error = serializeError(unhandledError)
channel.postMessage({ type: 'error', file, error, errorType: type })
channel.postMessage({ type: 'error', files: getFiles(), error, errorType: type })
}

function catchWindowErrors(cb: (e: ErrorEvent) => void) {
Expand Down
22 changes: 19 additions & 3 deletions packages/browser/src/node/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export default (project: WorkspaceProject, base = '/'): Plugin[] => {
const runnerHtml = readFile(resolve(distRoot, 'client/index.html'), 'utf8')
const injectorJs = readFile(resolve(distRoot, 'client/esm-client-injector.js'), 'utf8')
const favicon = `${base}favicon.svg`
const testerPrefix = `${base}__vitest_test__/__test__/`
server.middlewares.use((_req, res, next) => {
const headers = server.config.server.headers
if (headers) {
Expand All @@ -44,15 +45,20 @@ export default (project: WorkspaceProject, base = '/'): Plugin[] => {
if (!req.url)
return next()
const url = new URL(req.url, 'http://localhost')
if (!url.pathname.endsWith('__vitest_test__/tester.html') && url.pathname !== base)
if (!url.pathname.startsWith(testerPrefix) && url.pathname !== base)
return next()

res.setHeader('Cache-Control', 'no-cache, max-age=0, must-revalidate')
res.setHeader('Content-Type', 'text/html; charset=utf-8')

const files = project.browserState?.files ?? []

const config = wrapConfig(project.getSerializableConfig())
config.env ??= {}
config.env.VITEST_BROWSER_DEBUG = process.env.VITEST_BROWSER_DEBUG || ''

const injector = replacer(await injectorJs, {
__VITEST_CONFIG__: JSON.stringify(wrapConfig(project.getSerializableConfig())),
__VITEST_CONFIG__: JSON.stringify(config),
__VITEST_FILES__: JSON.stringify(files),
})

Expand All @@ -67,10 +73,20 @@ export default (project: WorkspaceProject, base = '/'): Plugin[] => {
return
}

const decodedTestFile = decodeURIComponent(url.pathname.slice(testerPrefix.length))
// if decoded test file is "__vitest_all__" or not in the list of known files, run all tests
const tests = decodedTestFile === '__vitest_all__' || !files.includes(decodedTestFile) ? 'window.__vi_files__' : JSON.stringify([decodedTestFile])

const html = replacer(await testerHtml, {
__VITEST_FAVICON__: favicon,
__VITEST_TITLE__: url.searchParams.get('__vitest_test') ?? 'Vitest Browser Tester',
__VITEST_TITLE__: 'Vitest Browser Tester',
__VITEST_INJECTOR__: injector,
__VITEST_APPEND__:
// TODO: have only a single global variable to not pollute the global scope
`<script type="module">
window.__vi_running_tests__ = ${tests}
__vitest_browser_runner__.runTests(window.__vi_running_tests__)
</script>`,
})
res.write(html, 'utf-8')
res.end()
Expand Down
1 change: 0 additions & 1 deletion packages/vitest/src/api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ export interface WebSocketHandlers {

finishBrowserTests(): void
getBrowserFiles(): string[]
// TODO: remove
debug(...args: string[]): void
}

Expand Down
14 changes: 8 additions & 6 deletions test/browser/specs/filter.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ test('filter', async () => {
},
},
)
result.stderr.on('data', (data) => {
process.stderr.write(data.toString())
})
result.stdout.on('data', (data) => {
process.stdout.write(data.toString())
})
if (process.env.VITEST_BROWSER_DEBUG) {
result.stderr.on('data', (data) => {
process.stderr.write(data.toString())
})
result.stdout.on('data', (data) => {
process.stdout.write(data.toString())
})
}
result = await result
assert.match(result.stdout, /✓ test\/basic.test.ts > basic 2/)
assert.match(result.stdout, /Test Files {2}1 passed/)
Expand Down
14 changes: 8 additions & 6 deletions test/browser/specs/run-vitest.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@ export default async function runVitest(moreArgs = []) {
},
reject: false,
})
result.stderr.on('data', (data) => {
process.stderr.write(data.toString())
})
result.stdout.on('data', (data) => {
process.stdout.write(data.toString())
})
if (process.env.VITEST_BROWSER_DEBUG) {
result.stderr.on('data', (data) => {
process.stderr.write(data.toString())
})
result.stdout.on('data', (data) => {
process.stdout.write(data.toString())
})
}
const { stderr, stdout } = await result
const browserResult = await readFile('./browser.json', 'utf-8')
const browserResultJson = JSON.parse(browserResult)
Expand Down

0 comments on commit 60baafc

Please sign in to comment.