diff --git a/README.md b/README.md index afa6985aad14..40b6b353ed8e 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,11 @@ A blazing fast test runner powered by Vite. ## Features -- [Vite](https://vitejs.dev/)'s config, transformers, resolvers, and plugins. Powered by [vite-node](https://github.com/antfu/vite-node) +- [Vite](https://vitejs.dev/)'s config, transformers, resolvers, and plugins. - [Jest Snapshot](https://jestjs.io/docs/snapshot-testing) - [Chai](https://www.chaijs.com/) for assertions - [Sinon](https://sinonjs.org/) for mocking +- [JSDOM](https://github.com/jsdom/jsdom) for DOM mocking - Async suite / test, top level await - ESM friendly - Out-of-box TypeScript support @@ -20,11 +21,12 @@ import { it, describe, expect, assert } from 'vitest' describe('suite name', () => { it('foo', () => { - assert.equal(Math.sqrt(4), 2) + expect(1 + 1).toEqual(2) + expect(true).to.be.true }) it('bar', () => { - expect(1 + 1).eq(2) + assert.equal(Math.sqrt(4), 2) }) it('snapshot', () => { diff --git a/package.json b/package.json index cc25e5485637..73bc42bdf42c 100644 --- a/package.json +++ b/package.json @@ -62,6 +62,7 @@ "devDependencies": { "@antfu/eslint-config": "^0.11.1", "@antfu/ni": "^0.11.0", + "@types/jsdom": "^16.2.13", "@types/minimist": "^1.2.2", "@types/node": "^16.11.11", "@types/sinon": "^10.0.6", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6dd7a123b291..ef7127c51154 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,7 @@ importers: '@antfu/ni': ^0.11.0 '@jest/test-result': ^27.4.2 '@types/chai': ^4.2.22 + '@types/jsdom': ^16.2.13 '@types/minimist': ^1.2.2 '@types/node': ^16.11.11 '@types/sinon': ^10.0.6 @@ -47,6 +48,7 @@ importers: devDependencies: '@antfu/eslint-config': 0.11.1_eslint@8.3.0+typescript@4.5.2 '@antfu/ni': 0.11.0 + '@types/jsdom': 16.2.13 '@types/minimist': 1.2.2 '@types/node': 16.11.11 '@types/sinon': 10.0.6 @@ -654,6 +656,14 @@ packages: '@types/istanbul-lib-report': 3.0.0 dev: false + /@types/jsdom/16.2.13: + resolution: {integrity: sha512-8JQCjdeAidptSsOcRWk2iTm9wCcwn9l+kRG6k5bzUacrnm1ezV4forq0kWjUih/tumAeoG+OspOvQEbbRucBTw==} + dependencies: + '@types/node': 16.11.11 + '@types/parse5': 6.0.3 + '@types/tough-cookie': 4.0.1 + dev: true + /@types/json-schema/7.0.9: resolution: {integrity: sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==} dev: true @@ -673,6 +683,10 @@ packages: resolution: {integrity: sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==} dev: true + /@types/parse5/6.0.3: + resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} + dev: true + /@types/prettier/2.2.1: resolution: {integrity: sha512-DxZZbyMAM9GWEzXL+BMZROWz9oo6A9EilwwOMET2UVu2uZTqMWS5S69KVtuVKaRjCUpcrOXRalet86/OpG4kqw==} dev: false @@ -693,6 +707,10 @@ packages: resolution: {integrity: sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==} dev: false + /@types/tough-cookie/4.0.1: + resolution: {integrity: sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==} + dev: true + /@types/yargs-parser/20.2.0: resolution: {integrity: sha512-37RSHht+gzzgYeobbG+KWryeAW8J33Nhr69cjTqSYymXVZEN9NbRYWoYlRtDhHKPVT1FyNKwaTPC1NynKZpzRA==} dev: false diff --git a/src/cli.ts b/src/cli.ts index 84681ae6f5c0..aa9f16bad5b7 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -11,7 +11,7 @@ const argv = minimist(process.argv.slice(2), { w: 'watch', }, string: ['root', 'config'], - boolean: ['update', 'dev', 'global', 'watch'], + boolean: ['update', 'dev', 'global', 'watch', 'jsdom'], unknown(name) { if (name[0] === '-') { console.error(c.red(`Unknown argument: ${name}`)) @@ -28,8 +28,7 @@ const viteConfig = server?.config || {} const testOptions = viteConfig.test || {} await run({ - global: argv.global, - watch: argv.watch, + ...argv, ...testOptions, server, updateSnapshot: argv.update, diff --git a/src/integrations/jsdom.ts b/src/integrations/jsdom.ts index e69de29bb2d1..fc02b7e8c5fa 100644 --- a/src/integrations/jsdom.ts +++ b/src/integrations/jsdom.ts @@ -0,0 +1,26 @@ +import { JSDOM } from 'jsdom' + +export function setupJSDOM(global: any) { + const dom = new JSDOM('', + { + pretendToBeVisual: true, + runScripts: 'dangerously', + // TODO: options + url: 'http://localhost:3000', + }, + ) + + const keys = Object.getOwnPropertyNames(dom.window) + .filter(k => !k.startsWith('_')) + .filter(k => !(k in global)) + + for (const key of keys) + global[key] = dom.window[key] + + return { + dom, + restore() { + keys.forEach(key => delete global[key]) + }, + } +} diff --git a/src/run.ts b/src/run.ts index 6c62c0b2b44a..4c16a9d38b8c 100644 --- a/src/run.ts +++ b/src/run.ts @@ -140,6 +140,9 @@ export async function run(config: Config) { if (config.global) (await import('./global')).registerApiGlobally() + if (config.jsdom) + (await import('./integrations/jsdom')).setupJSDOM(globalThis) + const files = await collectFiles(paths) const ctx: RunnerContext = {