1- import { dedent , defineAddon , log } from '@sveltejs/cli-core' ;
2- import { array , common , exports , functions , imports , object } from '@sveltejs/cli-core/js' ;
1+ import { dedent , defineAddon , defineAddonOptions , log } from '@sveltejs/cli-core' ;
2+ import { array , exports , functions , object } from '@sveltejs/cli-core/js' ;
33import { parseJson , parseScript } from '@sveltejs/cli-core/parsers' ;
44
5+ const options = defineAddonOptions ( {
6+ usages : {
7+ question : 'What do you want to use vitest for?' ,
8+ type : 'multiselect' ,
9+ default : [ 'unit' , 'component' ] ,
10+ options : [
11+ { value : 'unit' , label : 'unit testing' } ,
12+ { value : 'component' , label : 'component testing' }
13+ ] ,
14+ required : true
15+ }
16+ } ) ;
17+
518export default defineAddon ( {
619 id : 'vitest' ,
720 shortDescription : 'unit testing' ,
821 homepage : 'https://vitest.dev' ,
9- options : { } ,
10- run : ( { sv, typescript, kit } ) => {
22+ options,
23+ run : ( { sv, typescript, kit, options } ) => {
1124 const ext = typescript ? 'ts' : 'js' ;
25+ const unitTesting = options . usages . includes ( 'unit' ) ;
26+ const componentTesting = options . usages . includes ( 'component' ) ;
1227
1328 sv . devDependency ( 'vitest' , '^3.2.3' ) ;
14- sv . devDependency ( '@testing-library/svelte' , '^5.2.4' ) ;
15- sv . devDependency ( '@testing-library/jest-dom' , '^6.6.3' ) ;
16- sv . devDependency ( 'jsdom' , '^26.0.0' ) ;
29+
30+ if ( componentTesting ) {
31+ sv . devDependency ( '@vitest/browser' , '^3.2.3' ) ;
32+ sv . devDependency ( 'vitest-browser-svelte' , '^0.1.0' ) ;
33+ sv . devDependency ( 'playwright' , '^1.53.0' ) ;
34+ }
1735
1836 sv . file ( 'package.json' , ( content ) => {
1937 const { data, generateCode } = parseJson ( content ) ;
@@ -28,108 +46,84 @@ export default defineAddon({
2846 return generateCode ( ) ;
2947 } ) ;
3048
31- sv . file ( `src/demo.spec.${ ext } ` , ( content ) => {
32- if ( content ) return content ;
33-
34- return dedent `
35- import { describe, it, expect } from 'vitest';
36-
37- describe('sum test', () => {
38- it('adds 1 + 2 to equal 3', () => {
39- expect(1 + 2).toBe(3);
40- });
41- });
42- ` ;
43- } ) ;
44-
45- if ( kit ) {
46- sv . file ( `${ kit . routesDirectory } /page.svelte.test.${ ext } ` , ( content ) => {
49+ if ( unitTesting ) {
50+ sv . file ( `src/demo.spec.${ ext } ` , ( content ) => {
4751 if ( content ) return content ;
4852
4953 return dedent `
50- import { describe, test, expect } from 'vitest';
51- import '@testing-library/jest-dom/vitest';
52- import { render, screen } from '@testing-library/svelte';
53- import Page from './+page.svelte';
54+ import { describe, it, expect } from 'vitest';
5455
55- describe('/+page.svelte', () => {
56- test('should render h1', () => {
57- render(Page);
58- expect(screen.getByRole('heading', { level: 1 })).toBeInTheDocument();
59- });
56+ describe('sum test', () => {
57+ it('adds 1 + 2 to equal 3', () => {
58+ expect(1 + 2).toBe(3);
6059 });
61- ` ;
60+ });
61+ ` ;
6262 } ) ;
63- } else {
64- sv . file ( `src/App.svelte.test.${ ext } ` , ( content ) => {
63+ }
64+
65+ if ( componentTesting ) {
66+ const fileName = kit
67+ ? `${ kit . routesDirectory } /page.svelte.test.${ ext } `
68+ : `src/App.svelte.test.${ ext } ` ;
69+
70+ sv . file ( fileName , ( content ) => {
6571 if ( content ) return content ;
6672
6773 return dedent `
68- import { describe, test, expect } from 'vitest';
69- import '@testing-library/jest-dom/vitest';
70- import { render, screen } from '@testing-library/svelte';
71- import App from './App.svelte';
72-
73- describe('App.svelte', () => {
74- test('should render h1', () => {
75- render(App);
76- expect(screen.getByRole('heading', { level: 1 })).toBeInTheDocument();
74+ import { page } from '@vitest/browser/context';
75+ import { describe, expect, it } from 'vitest';
76+ import { render } from 'vitest-browser-svelte';
77+ ${ kit ? "import Page from './+page.svelte';" : "import App from './App.svelte';" }
78+
79+ describe('${ kit ? '/+page.svelte' : 'App.svelte' } ', () => {
80+ it('should render h1', async () => {
81+ render(${ kit ? 'Page' : 'App' } );
82+
83+ const heading = page.getByRole('heading', { level: 1 });
84+ await expect.element(heading).toBeInTheDocument();
7785 });
7886 });
7987 ` ;
8088 } ) ;
81- }
8289
83- sv . file ( `vitest-setup-client.${ ext } ` , ( content ) => {
84- if ( content ) return content ;
85-
86- return dedent `
87- import '@testing-library/jest-dom/vitest';
88- import { vi } from 'vitest';
89-
90- // required for svelte5 + jsdom as jsdom does not support matchMedia
91- Object.defineProperty(window, 'matchMedia', {
92- writable: true,
93- enumerable: true,
94- value: vi.fn().mockImplementation(query => ({
95- matches: false,
96- media: query,
97- onchange: null,
98- addEventListener: vi.fn(),
99- removeEventListener: vi.fn(),
100- dispatchEvent: vi.fn(),
101- })),
102- })
103-
104- // add more mocks here if you need them
90+ sv . file ( `vitest-setup-client.${ ext } ` , ( content ) => {
91+ if ( content ) return content ;
92+
93+ return dedent `
94+ /// <reference types="@vitest/browser/matchers" />
95+ /// <reference types="@vitest/browser/providers/playwright" />
10596 ` ;
106- } ) ;
97+ } ) ;
98+ }
10799
108100 sv . file ( `vite.config.${ ext } ` , ( content ) => {
109101 const { ast, generateCode } = parseScript ( content ) ;
110102
111- imports . addNamed ( ast , '@testing-library/svelte/vite' , { svelteTesting : 'svelteTesting' } ) ;
112-
113- const clientObjectExpression = object . create ( {
114- extends : common . createLiteral ( `./vite.config.${ ext } ` ) ,
115- plugins : common . expressionFromString ( '[svelteTesting()]' ) ,
116- test : object . create ( {
117- name : common . createLiteral ( 'client' ) ,
118- environment : common . createLiteral ( 'jsdom' ) ,
119- clearMocks : common . expressionFromString ( 'true' ) ,
120- include : common . expressionFromString ( "['src/**/*.svelte.{test,spec}.{js,ts}']" ) ,
121- exclude : common . expressionFromString ( "['src/lib/server/**']" ) ,
122- setupFiles : common . expressionFromString ( `['./vitest-setup-client.${ ext } ']` )
123- } )
103+ const clientObjectExpression = object . createFromPrimitives ( {
104+ extends : `./vite.config.${ ext } ` ,
105+ test : {
106+ name : 'client' ,
107+ environment : 'browser' ,
108+ browser : {
109+ enabled : true ,
110+ provider : 'playwright' ,
111+ instances : [ { browser : 'chromium' } ]
112+ } ,
113+ include : [ 'src/**/*.svelte.{test,spec}.{js,ts}' ] ,
114+ exclude : [ 'src/lib/server/**' ] ,
115+ setupFiles : [ `./vitest-setup-client.${ ext } ` ]
116+ }
124117 } ) ;
125- const serverObjectExpression = object . create ( {
126- extends : common . createLiteral ( `./vite.config.${ ext } ` ) ,
127- test : object . create ( {
128- name : common . createLiteral ( 'server' ) ,
129- environment : common . createLiteral ( 'node' ) ,
130- include : common . expressionFromString ( "['src/**/*.{test,spec}.{js,ts}']" ) ,
131- exclude : common . expressionFromString ( "['src/**/*.svelte.{test,spec}.{js,ts}']" )
132- } )
118+
119+ const serverObjectExpression = object . createFromPrimitives ( {
120+ extends : `./vite.config.${ ext } ` ,
121+ test : {
122+ name : 'server' ,
123+ environment : 'node' ,
124+ include : [ 'src/**/*.{test,spec}.{js,ts}' ] ,
125+ exclude : [ 'src/**/*.svelte.{test,spec}.{js,ts}' ]
126+ }
133127 } ) ;
134128
135129 const defineConfigFallback = functions . call ( 'defineConfig' , [ ] ) ;
@@ -142,8 +136,9 @@ export default defineAddon({
142136 const testObject = object . property ( vitestConfig , 'test' , object . createEmpty ( ) ) ;
143137
144138 const workspaceArray = object . property ( testObject , 'projects' , array . createEmpty ( ) ) ;
145- array . push ( workspaceArray , clientObjectExpression ) ;
146- array . push ( workspaceArray , serverObjectExpression ) ;
139+
140+ if ( componentTesting ) array . push ( workspaceArray , clientObjectExpression ) ;
141+ if ( unitTesting ) array . push ( workspaceArray , serverObjectExpression ) ;
147142
148143 return generateCode ( ) ;
149144 } ) ;
0 commit comments