@stencil/vitest 0.0.1-dev.20260109124515.90fb962
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +296 -0
- package/dist/bin/stencil-test.d.ts +3 -0
- package/dist/bin/stencil-test.d.ts.map +1 -0
- package/dist/bin/stencil-test.js +341 -0
- package/dist/config.d.ts +73 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +302 -0
- package/dist/environments/env/happy-dom.d.ts +4 -0
- package/dist/environments/env/happy-dom.d.ts.map +1 -0
- package/dist/environments/env/happy-dom.js +15 -0
- package/dist/environments/env/jsdom.d.ts +4 -0
- package/dist/environments/env/jsdom.d.ts.map +1 -0
- package/dist/environments/env/jsdom.js +32 -0
- package/dist/environments/env/mock-doc.d.ts +4 -0
- package/dist/environments/env/mock-doc.d.ts.map +1 -0
- package/dist/environments/env/mock-doc.js +14 -0
- package/dist/environments/stencil.d.ts +28 -0
- package/dist/environments/stencil.d.ts.map +1 -0
- package/dist/environments/stencil.js +71 -0
- package/dist/environments/types.d.ts +6 -0
- package/dist/environments/types.d.ts.map +1 -0
- package/dist/environments/types.js +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/setup/config-loader.d.ts +19 -0
- package/dist/setup/config-loader.d.ts.map +1 -0
- package/dist/setup/config-loader.js +92 -0
- package/dist/setup/happy-dom-setup.d.ts +12 -0
- package/dist/setup/happy-dom-setup.d.ts.map +1 -0
- package/dist/setup/happy-dom-setup.js +16 -0
- package/dist/setup/jsdom-setup.d.ts +30 -0
- package/dist/setup/jsdom-setup.d.ts.map +1 -0
- package/dist/setup/jsdom-setup.js +95 -0
- package/dist/setup/mock-doc-setup.d.ts +17 -0
- package/dist/setup/mock-doc-setup.d.ts.map +1 -0
- package/dist/setup/mock-doc-setup.js +90 -0
- package/dist/testing/html-serializer.d.ts +27 -0
- package/dist/testing/html-serializer.d.ts.map +1 -0
- package/dist/testing/html-serializer.js +152 -0
- package/dist/testing/matchers.d.ts +181 -0
- package/dist/testing/matchers.d.ts.map +1 -0
- package/dist/testing/matchers.js +460 -0
- package/dist/testing/render.d.ts +11 -0
- package/dist/testing/render.d.ts.map +1 -0
- package/dist/testing/render.js +118 -0
- package/dist/testing/snapshot-serializer.d.ts +17 -0
- package/dist/testing/snapshot-serializer.d.ts.map +1 -0
- package/dist/testing/snapshot-serializer.js +50 -0
- package/dist/types.d.ts +81 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +133 -0
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { type ViteUserConfig } from 'vitest/config';
|
|
2
|
+
import type { Config as StencilConfig } from '@stencil/core/internal';
|
|
3
|
+
/**
|
|
4
|
+
* Define a Vitest configuration for Stencil component testing
|
|
5
|
+
*
|
|
6
|
+
* Accepts standard Vitest config with optional Stencil enhancements.
|
|
7
|
+
* Automatically applies Stencil-specific defaults:
|
|
8
|
+
* - JSX configuration (h, Fragment)
|
|
9
|
+
* - Resolve aliases from Stencil config (@, @components, @utils)
|
|
10
|
+
* - Coverage configuration based on srcDir
|
|
11
|
+
* - Exclude patterns for build outputs
|
|
12
|
+
* - Auto-injects jsdom-setup for environment: 'jsdom'
|
|
13
|
+
* - Auto-injects happy-dom-setup for environment: 'happy-dom'
|
|
14
|
+
* - Custom 'stencil' environment handles its own setup
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { defineVitestConfig } from '@stencil/vitest/config';
|
|
19
|
+
*
|
|
20
|
+
* export default defineVitestConfig({
|
|
21
|
+
* test: {
|
|
22
|
+
* projects: [
|
|
23
|
+
* {
|
|
24
|
+
* test: {
|
|
25
|
+
* name: 'stencil',
|
|
26
|
+
* include: ['**\/*.spec.tsx'],
|
|
27
|
+
* environment: 'stencil',
|
|
28
|
+
* setupFiles: ['./vitest-setup.ts'],
|
|
29
|
+
* // environmentOptions: {
|
|
30
|
+
* // stencil: {
|
|
31
|
+
* // domEnvironment: 'happy-dom' // 'jsdom' | 'mock-doc' (default), Make sure to install relevant packages
|
|
32
|
+
* // },
|
|
33
|
+
* // },
|
|
34
|
+
* },
|
|
35
|
+
* },
|
|
36
|
+
* {
|
|
37
|
+
* test: {
|
|
38
|
+
* name: 'jsdom',
|
|
39
|
+
* include: ['**\/*.jsdom.spec.tsx'],
|
|
40
|
+
* environment: 'jsdom',
|
|
41
|
+
* setupFiles: ['./vitest-setup.ts'],
|
|
42
|
+
* },
|
|
43
|
+
* },
|
|
44
|
+
* {
|
|
45
|
+
* test: {
|
|
46
|
+
* name: 'happy-dom',
|
|
47
|
+
* include: ['**\/*.happy.spec.tsx'],
|
|
48
|
+
* environment: 'happy-dom',
|
|
49
|
+
* setupFiles: ['./vitest-setup.ts'],
|
|
50
|
+
* },
|
|
51
|
+
* },
|
|
52
|
+
* {
|
|
53
|
+
* test: {
|
|
54
|
+
* name: 'browser',
|
|
55
|
+
* include: ['**\/*.e2e.tsx'],
|
|
56
|
+
* browser: {
|
|
57
|
+
* enabled: true,
|
|
58
|
+
* provider: 'playwright',
|
|
59
|
+
* instances: [
|
|
60
|
+
* { browser: 'chromium' }
|
|
61
|
+
* ],
|
|
62
|
+
* },
|
|
63
|
+
* },
|
|
64
|
+
* },
|
|
65
|
+
* ],
|
|
66
|
+
* },
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export declare function defineVitestConfig(config?: ViteUserConfig & {
|
|
71
|
+
stencilConfig?: string | StencilConfig;
|
|
72
|
+
}): Promise<ViteUserConfig>;
|
|
73
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,cAAc,EAAE,MAAM,eAAe,CAAC;AAOlE,OAAO,KAAK,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEtE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,GAAE,cAAc,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,GAAG,aAAa,CAAA;CAAO,GACvE,OAAO,CAAC,cAAc,CAAC,CAqBzB"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
import { loadStencilConfig, getStencilSrcDir, getStencilOutputDirs, getStencilResolveAliases, } from './setup/config-loader.js';
|
|
3
|
+
/**
|
|
4
|
+
* Define a Vitest configuration for Stencil component testing
|
|
5
|
+
*
|
|
6
|
+
* Accepts standard Vitest config with optional Stencil enhancements.
|
|
7
|
+
* Automatically applies Stencil-specific defaults:
|
|
8
|
+
* - JSX configuration (h, Fragment)
|
|
9
|
+
* - Resolve aliases from Stencil config (@, @components, @utils)
|
|
10
|
+
* - Coverage configuration based on srcDir
|
|
11
|
+
* - Exclude patterns for build outputs
|
|
12
|
+
* - Auto-injects jsdom-setup for environment: 'jsdom'
|
|
13
|
+
* - Auto-injects happy-dom-setup for environment: 'happy-dom'
|
|
14
|
+
* - Custom 'stencil' environment handles its own setup
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* import { defineVitestConfig } from '@stencil/vitest/config';
|
|
19
|
+
*
|
|
20
|
+
* export default defineVitestConfig({
|
|
21
|
+
* test: {
|
|
22
|
+
* projects: [
|
|
23
|
+
* {
|
|
24
|
+
* test: {
|
|
25
|
+
* name: 'stencil',
|
|
26
|
+
* include: ['**\/*.spec.tsx'],
|
|
27
|
+
* environment: 'stencil',
|
|
28
|
+
* setupFiles: ['./vitest-setup.ts'],
|
|
29
|
+
* // environmentOptions: {
|
|
30
|
+
* // stencil: {
|
|
31
|
+
* // domEnvironment: 'happy-dom' // 'jsdom' | 'mock-doc' (default), Make sure to install relevant packages
|
|
32
|
+
* // },
|
|
33
|
+
* // },
|
|
34
|
+
* },
|
|
35
|
+
* },
|
|
36
|
+
* {
|
|
37
|
+
* test: {
|
|
38
|
+
* name: 'jsdom',
|
|
39
|
+
* include: ['**\/*.jsdom.spec.tsx'],
|
|
40
|
+
* environment: 'jsdom',
|
|
41
|
+
* setupFiles: ['./vitest-setup.ts'],
|
|
42
|
+
* },
|
|
43
|
+
* },
|
|
44
|
+
* {
|
|
45
|
+
* test: {
|
|
46
|
+
* name: 'happy-dom',
|
|
47
|
+
* include: ['**\/*.happy.spec.tsx'],
|
|
48
|
+
* environment: 'happy-dom',
|
|
49
|
+
* setupFiles: ['./vitest-setup.ts'],
|
|
50
|
+
* },
|
|
51
|
+
* },
|
|
52
|
+
* {
|
|
53
|
+
* test: {
|
|
54
|
+
* name: 'browser',
|
|
55
|
+
* include: ['**\/*.e2e.tsx'],
|
|
56
|
+
* browser: {
|
|
57
|
+
* enabled: true,
|
|
58
|
+
* provider: 'playwright',
|
|
59
|
+
* instances: [
|
|
60
|
+
* { browser: 'chromium' }
|
|
61
|
+
* ],
|
|
62
|
+
* },
|
|
63
|
+
* },
|
|
64
|
+
* },
|
|
65
|
+
* ],
|
|
66
|
+
* },
|
|
67
|
+
* });
|
|
68
|
+
* ```
|
|
69
|
+
*/
|
|
70
|
+
export async function defineVitestConfig(config = {}) {
|
|
71
|
+
// Load Stencil config if provided (optional)
|
|
72
|
+
let stencilConfig;
|
|
73
|
+
if (typeof config.stencilConfig === 'string') {
|
|
74
|
+
try {
|
|
75
|
+
stencilConfig = await loadStencilConfig(config.stencilConfig);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// loading is optional
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (config.stencilConfig) {
|
|
82
|
+
stencilConfig = config.stencilConfig;
|
|
83
|
+
}
|
|
84
|
+
// Remove stencilConfig from the final config (destructure to exclude it)
|
|
85
|
+
const { stencilConfig: _stencilConfig, ...vitestConfig } = config;
|
|
86
|
+
// Apply Stencil-specific defaults
|
|
87
|
+
const enhancedConfig = applyStencilDefaults(vitestConfig, stencilConfig);
|
|
88
|
+
return defineConfig(enhancedConfig);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Generate coverage exclude patterns from test include patterns
|
|
92
|
+
*/
|
|
93
|
+
function generateCoverageExcludes(testIncludes, srcDir) {
|
|
94
|
+
const excludes = [];
|
|
95
|
+
for (const include of testIncludes) {
|
|
96
|
+
// Convert test include patterns to coverage exclude patterns
|
|
97
|
+
// Examples:
|
|
98
|
+
// "src/**/*.spec.{ts,tsx}" -> "src/**/*.spec.{ts,tsx}"
|
|
99
|
+
// "**/*.spec.{ts,tsx}" -> "src/**/*.spec.{ts,tsx}" (assuming srcDir is "src")
|
|
100
|
+
// "components/**/*.test.tsx" -> "src/components/**/*.test.tsx"
|
|
101
|
+
let excludePattern = include;
|
|
102
|
+
// If pattern doesn't start with srcDir, prepend it
|
|
103
|
+
if (!excludePattern.startsWith(`${srcDir}/`)) {
|
|
104
|
+
// Handle patterns that start with **/ by replacing with srcDir
|
|
105
|
+
if (excludePattern.startsWith('**/')) {
|
|
106
|
+
excludePattern = excludePattern.replace('**/', `${srcDir}/`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
// For other patterns, prepend srcDir
|
|
110
|
+
excludePattern = `${srcDir}/${excludePattern}`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
excludes.push(excludePattern);
|
|
114
|
+
}
|
|
115
|
+
return excludes;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Apply Stencil-specific defaults to Vitest config
|
|
119
|
+
*/
|
|
120
|
+
function applyStencilDefaults(config, stencilConfig) {
|
|
121
|
+
// Start with the user's config
|
|
122
|
+
const result = { ...config };
|
|
123
|
+
// Add esbuild JSX config if not present
|
|
124
|
+
if (!result.esbuild) {
|
|
125
|
+
result.esbuild = {
|
|
126
|
+
jsxFactory: 'h',
|
|
127
|
+
jsxFragment: 'Fragment',
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// Add resolve aliases from Stencil config if not present
|
|
131
|
+
if (!result.resolve) {
|
|
132
|
+
result.resolve = {};
|
|
133
|
+
}
|
|
134
|
+
if (!result.resolve.alias) {
|
|
135
|
+
result.resolve.alias = getStencilResolveAliases(stencilConfig);
|
|
136
|
+
}
|
|
137
|
+
else if (typeof result.resolve.alias === 'object' && !Array.isArray(result.resolve.alias)) {
|
|
138
|
+
// Merge with existing aliases, user's aliases take precedence
|
|
139
|
+
result.resolve.alias = {
|
|
140
|
+
...getStencilResolveAliases(stencilConfig),
|
|
141
|
+
...result.resolve.alias,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
// Configure Vite server to watch Stencil output directories
|
|
145
|
+
// This allows Vitest to automatically re-run tests when Stencil rebuilds components
|
|
146
|
+
if (!result.server) {
|
|
147
|
+
result.server = {};
|
|
148
|
+
}
|
|
149
|
+
if (!result.server.watch) {
|
|
150
|
+
result.server.watch = {};
|
|
151
|
+
}
|
|
152
|
+
// Ensure test config exists
|
|
153
|
+
if (!result.test) {
|
|
154
|
+
result.test = {};
|
|
155
|
+
}
|
|
156
|
+
// Enable forceRerunTriggers to watch output directories
|
|
157
|
+
// This ensures Vitest re-runs tests when Stencil rebuilds components
|
|
158
|
+
const outputDirs = getStencilOutputDirs(stencilConfig);
|
|
159
|
+
if (!result.test.forceRerunTriggers) {
|
|
160
|
+
result.test.forceRerunTriggers = [];
|
|
161
|
+
}
|
|
162
|
+
// Add output directories to force rerun triggers
|
|
163
|
+
const existingTriggers = Array.isArray(result.test.forceRerunTriggers)
|
|
164
|
+
? result.test.forceRerunTriggers
|
|
165
|
+
: [result.test.forceRerunTriggers];
|
|
166
|
+
const outputDirTriggers = outputDirs.map((dir) => `**/${dir}/**`);
|
|
167
|
+
result.test.forceRerunTriggers = [...new Set([...existingTriggers, ...outputDirTriggers])];
|
|
168
|
+
// Add globals if not set
|
|
169
|
+
if (result.test.globals === undefined) {
|
|
170
|
+
result.test.globals = true;
|
|
171
|
+
}
|
|
172
|
+
// Add coverage config at root level if not present
|
|
173
|
+
// This applies to all projects in multi-project mode
|
|
174
|
+
if (!result.test.coverage) {
|
|
175
|
+
const srcDir = getStencilSrcDir(stencilConfig);
|
|
176
|
+
const outputDirs = getStencilOutputDirs(stencilConfig);
|
|
177
|
+
// Collect all test include patterns from projects
|
|
178
|
+
const testIncludes = [];
|
|
179
|
+
if (result.test.projects) {
|
|
180
|
+
// Multi-project mode
|
|
181
|
+
for (const project of result.test.projects) {
|
|
182
|
+
if (project.test?.include) {
|
|
183
|
+
const includes = Array.isArray(project.test.include) ? project.test.include : [project.test.include];
|
|
184
|
+
testIncludes.push(...includes);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
else if (result.test.include) {
|
|
189
|
+
// Single project mode
|
|
190
|
+
const includes = Array.isArray(result.test.include) ? result.test.include : [result.test.include];
|
|
191
|
+
testIncludes.push(...includes);
|
|
192
|
+
}
|
|
193
|
+
// Generate coverage excludes from test includes
|
|
194
|
+
const coverageExcludes = testIncludes.length > 0
|
|
195
|
+
? generateCoverageExcludes(testIncludes, srcDir)
|
|
196
|
+
: [`${srcDir}/**/*.spec.{ts,tsx}`, `${srcDir}/**/*.e2e.{ts,tsx}`, `${srcDir}/**/*.test.{ts,tsx}`];
|
|
197
|
+
result.test.coverage = {
|
|
198
|
+
provider: 'v8',
|
|
199
|
+
reporter: ['text', 'json', 'html'],
|
|
200
|
+
include: [`${srcDir}/**/*.{ts,tsx}`],
|
|
201
|
+
exclude: [...coverageExcludes, ...outputDirs.map((dir) => `${dir}/**`)],
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
// If there are projects, enhance each one
|
|
205
|
+
if (result.test.projects) {
|
|
206
|
+
result.test.projects = result.test.projects.map((project) => enhanceProject(project, stencilConfig));
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// Single project mode - enhance the test config directly
|
|
210
|
+
result.test = enhanceTestConfig(result.test, stencilConfig);
|
|
211
|
+
}
|
|
212
|
+
if (result.test.onConsoleLog === undefined) {
|
|
213
|
+
result.test.onConsoleLog = (log) => {
|
|
214
|
+
if (log?.includes('Running in development mode.'))
|
|
215
|
+
return false;
|
|
216
|
+
return true;
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Enhance test config with Stencil defaults
|
|
223
|
+
*/
|
|
224
|
+
function enhanceTestConfig(testConfig, stencilConfig) {
|
|
225
|
+
const enhanced = { ...testConfig };
|
|
226
|
+
// Get output directories from Stencil config
|
|
227
|
+
const outputDirs = getStencilOutputDirs(stencilConfig);
|
|
228
|
+
const defaultExcludes = ['**/node_modules/**', ...outputDirs.map((dir) => `**/${dir}/**`)];
|
|
229
|
+
// Add default excludes if not present
|
|
230
|
+
if (!enhanced.exclude) {
|
|
231
|
+
enhanced.exclude = defaultExcludes;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
// Merge with existing excludes
|
|
235
|
+
const existingExcludes = Array.isArray(enhanced.exclude) ? enhanced.exclude : [enhanced.exclude];
|
|
236
|
+
enhanced.exclude = [
|
|
237
|
+
...defaultExcludes,
|
|
238
|
+
...existingExcludes.filter((pattern) => !defaultExcludes.includes(pattern)),
|
|
239
|
+
];
|
|
240
|
+
}
|
|
241
|
+
// Add coverage config based on Stencil srcDir if not present
|
|
242
|
+
if (!enhanced.coverage) {
|
|
243
|
+
const srcDir = getStencilSrcDir(stencilConfig);
|
|
244
|
+
enhanced.coverage = {
|
|
245
|
+
provider: 'v8',
|
|
246
|
+
reporter: ['text', 'json', 'html'],
|
|
247
|
+
include: [`${srcDir}/**/*.{ts,tsx}`],
|
|
248
|
+
exclude: [
|
|
249
|
+
`${srcDir}/**/*.spec.{ts,tsx}`,
|
|
250
|
+
`${srcDir}/**/*.e2e.{ts,tsx}`,
|
|
251
|
+
`${srcDir}/**/*.test.{ts,tsx}`,
|
|
252
|
+
...outputDirs.map((dir) => `${dir}/**`),
|
|
253
|
+
],
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
return enhanced;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Enhance a single project with Stencil defaults
|
|
260
|
+
*/
|
|
261
|
+
function enhanceProject(project, stencilConfig) {
|
|
262
|
+
const enhanced = { ...project };
|
|
263
|
+
// Get output directories from Stencil config
|
|
264
|
+
const outputDirs = getStencilOutputDirs(stencilConfig);
|
|
265
|
+
const defaultExcludes = ['**/node_modules/**', ...outputDirs.map((dir) => `**/${dir}/**`)];
|
|
266
|
+
// Merge default excludes with user-provided excludes
|
|
267
|
+
if (enhanced.test) {
|
|
268
|
+
if (!enhanced.test.exclude) {
|
|
269
|
+
enhanced.test.exclude = defaultExcludes;
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
// Merge defaults with existing excludes, avoiding duplicates
|
|
273
|
+
const existingExcludes = Array.isArray(enhanced.test.exclude) ? enhanced.test.exclude : [enhanced.test.exclude];
|
|
274
|
+
enhanced.test.exclude = [
|
|
275
|
+
...defaultExcludes,
|
|
276
|
+
...existingExcludes.filter((pattern) => !defaultExcludes.includes(pattern)),
|
|
277
|
+
];
|
|
278
|
+
}
|
|
279
|
+
// Auto-inject setup files based on environment
|
|
280
|
+
const setupFiles = enhanced.test.setupFiles || [];
|
|
281
|
+
const setupFilesArray = Array.isArray(setupFiles) ? setupFiles : [setupFiles];
|
|
282
|
+
const environment = enhanced.test.environment?.toLowerCase();
|
|
283
|
+
// Auto-inject setup files based on environment type
|
|
284
|
+
// This provides automatic polyfills based on the environment being used
|
|
285
|
+
// Auto-inject jsdom-setup for jsdom environment
|
|
286
|
+
if (environment === 'jsdom') {
|
|
287
|
+
if (!setupFilesArray.includes('@stencil/vitest/jsdom-setup')) {
|
|
288
|
+
enhanced.test.setupFiles = ['@stencil/vitest/jsdom-setup', ...setupFilesArray];
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// Auto-inject happy-dom-setup for happy-dom environment
|
|
292
|
+
if (environment === 'happy-dom') {
|
|
293
|
+
if (!setupFilesArray.includes('@stencil/vitest/happy-dom-setup')) {
|
|
294
|
+
enhanced.test.setupFiles = ['@stencil/vitest/happy-dom-setup', ...setupFilesArray];
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
// Note: The 'stencil' custom environment handles its own setup internally
|
|
298
|
+
// and doesn't need auto-injection
|
|
299
|
+
// Note: coverage config is applied at the root test level, not per-project
|
|
300
|
+
}
|
|
301
|
+
return enhanced;
|
|
302
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"happy-dom.d.ts","sourceRoot":"","sources":["../../../src/environments/env/happy-dom.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;wBAEtC,kBAAkB;AAAlC,wBAgBE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { importModule } from 'local-pkg';
|
|
2
|
+
export default (async function (global, options) {
|
|
3
|
+
const { Window, GlobalWindow } = (await importModule('happy-dom'));
|
|
4
|
+
const happyDomOptions = {
|
|
5
|
+
url: 'http://localhost:3000',
|
|
6
|
+
...options.happyDom,
|
|
7
|
+
};
|
|
8
|
+
const window = new (GlobalWindow || Window)(happyDomOptions);
|
|
9
|
+
return {
|
|
10
|
+
window,
|
|
11
|
+
teardown() {
|
|
12
|
+
window.happyDOM.abort();
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsdom.d.ts","sourceRoot":"","sources":["../../../src/environments/env/jsdom.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;wBAGtC,kBAAkB;AAAlC,wBAoCE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { importModule } from 'local-pkg';
|
|
2
|
+
import { applyJsdomPolyfills } from '../../setup/jsdom-setup.js';
|
|
3
|
+
export default (async function (global, options) {
|
|
4
|
+
const { JSDOM, ResourceLoader, VirtualConsole, CookieJar } = (await importModule('jsdom'));
|
|
5
|
+
const jsdomOptions = {
|
|
6
|
+
html: '<!DOCTYPE html>',
|
|
7
|
+
url: 'http://localhost:3000',
|
|
8
|
+
contentType: 'text/html',
|
|
9
|
+
pretendToBeVisual: true,
|
|
10
|
+
includeNodeLocations: false,
|
|
11
|
+
runScripts: 'dangerously',
|
|
12
|
+
console: false,
|
|
13
|
+
cookieJar: false,
|
|
14
|
+
...options.jsdom,
|
|
15
|
+
};
|
|
16
|
+
const virtualConsole = jsdomOptions.console && global.console ? new VirtualConsole().sendTo(global.console) : undefined;
|
|
17
|
+
const window = new JSDOM(jsdomOptions.html, {
|
|
18
|
+
...jsdomOptions,
|
|
19
|
+
resources: jsdomOptions.resources ??
|
|
20
|
+
(jsdomOptions.userAgent ? new ResourceLoader({ userAgent: jsdomOptions.userAgent }) : undefined),
|
|
21
|
+
virtualConsole,
|
|
22
|
+
cookieJar: jsdomOptions.cookieJar ? new CookieJar() : undefined,
|
|
23
|
+
}).window;
|
|
24
|
+
// Apply all polyfills using shared logic
|
|
25
|
+
applyJsdomPolyfills(window);
|
|
26
|
+
return {
|
|
27
|
+
window,
|
|
28
|
+
teardown() {
|
|
29
|
+
window.close();
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-doc.d.ts","sourceRoot":"","sources":["../../../src/environments/env/mock-doc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;wBAGtC,kBAAkB;AAAlC,wBAaE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { applyMockDocPolyfills } from '../../setup/mock-doc-setup.js';
|
|
2
|
+
export default (async function (_global, _options) {
|
|
3
|
+
const mockDoc = await import('@stencil/core/mock-doc');
|
|
4
|
+
const win = new mockDoc.MockWindow('http://localhost:3000/');
|
|
5
|
+
applyMockDocPolyfills(win);
|
|
6
|
+
return {
|
|
7
|
+
window: win,
|
|
8
|
+
teardown() {
|
|
9
|
+
if (typeof mockDoc.teardownGlobal === 'function') {
|
|
10
|
+
mockDoc.teardownGlobal(win);
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { Environment } from 'vitest/environments';
|
|
2
|
+
export interface StencilEnvironmentOptions {
|
|
3
|
+
/**
|
|
4
|
+
* The DOM environment to use for testing
|
|
5
|
+
* @default 'mock-doc'
|
|
6
|
+
*/
|
|
7
|
+
domEnvironment?: 'mock-doc' | 'happy-dom' | 'jsdom';
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Custom Vitest environment for Stencil component testing
|
|
11
|
+
*
|
|
12
|
+
* Usage in vitest.config.ts:
|
|
13
|
+
* ```ts
|
|
14
|
+
* export default defineConfig({
|
|
15
|
+
* test: {
|
|
16
|
+
* environment: 'stencil',
|
|
17
|
+
* environmentOptions: {
|
|
18
|
+
* stencil: {
|
|
19
|
+
* domEnvironment: 'mock-doc' // or 'happy-dom' or 'jsdom'
|
|
20
|
+
* }
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* })
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare const _default: Environment;
|
|
27
|
+
export default _default;
|
|
28
|
+
//# sourceMappingURL=stencil.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stencil.d.ts","sourceRoot":"","sources":["../../src/environments/stencil.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAOvD,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,cAAc,CAAC,EAAE,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;CACrD;AAQD;;;;;;;;;;;;;;;;GAgBG;wBACa,WAAW;AAA3B,wBAqDE"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { populateGlobal } from 'vitest/environments';
|
|
2
|
+
import happyDom from './env/happy-dom.js';
|
|
3
|
+
import jsdom from './env/jsdom.js';
|
|
4
|
+
import mockDoc from './env/mock-doc.js';
|
|
5
|
+
const environmentMap = {
|
|
6
|
+
'happy-dom': happyDom,
|
|
7
|
+
jsdom: jsdom,
|
|
8
|
+
'mock-doc': mockDoc,
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Custom Vitest environment for Stencil component testing
|
|
12
|
+
*
|
|
13
|
+
* Usage in vitest.config.ts:
|
|
14
|
+
* ```ts
|
|
15
|
+
* export default defineConfig({
|
|
16
|
+
* test: {
|
|
17
|
+
* environment: 'stencil',
|
|
18
|
+
* environmentOptions: {
|
|
19
|
+
* stencil: {
|
|
20
|
+
* domEnvironment: 'mock-doc' // or 'happy-dom' or 'jsdom'
|
|
21
|
+
* }
|
|
22
|
+
* }
|
|
23
|
+
* }
|
|
24
|
+
* })
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export default {
|
|
28
|
+
name: 'stencil',
|
|
29
|
+
viteEnvironment: 'ssr',
|
|
30
|
+
async setup(global, options) {
|
|
31
|
+
const { stencil = {} } = options;
|
|
32
|
+
const domEnvironment = stencil.domEnvironment || 'mock-doc';
|
|
33
|
+
const environment = environmentMap[domEnvironment] || environmentMap['mock-doc'];
|
|
34
|
+
if (!environment) {
|
|
35
|
+
throw new Error(`Unknown domEnvironment: ${domEnvironment}. Must be 'mock-doc', 'happy-dom', or 'jsdom'`);
|
|
36
|
+
}
|
|
37
|
+
// Setup the environment and get the window
|
|
38
|
+
const { window: win, teardown: envTeardown } = await environment(global, options);
|
|
39
|
+
// Stub MessageEvent on global before populateGlobal to prevent Node's undici from loading
|
|
40
|
+
// This prevents "Class extends value undefined" errors from undici's WebSocket implementation
|
|
41
|
+
if (!global.MessageEvent && win.MessageEvent) {
|
|
42
|
+
Object.defineProperty(global, 'MessageEvent', {
|
|
43
|
+
value: win.MessageEvent,
|
|
44
|
+
writable: true,
|
|
45
|
+
configurable: true,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
// Set NODE_ENV to test if not already set
|
|
49
|
+
if (!win.process?.env) {
|
|
50
|
+
win.process = { env: {} };
|
|
51
|
+
}
|
|
52
|
+
if (!win.process.env.NODE_ENV) {
|
|
53
|
+
win.process.env.NODE_ENV = 'test';
|
|
54
|
+
}
|
|
55
|
+
// Populate global with window properties
|
|
56
|
+
const { keys, originals } = populateGlobal(global, win, {
|
|
57
|
+
bindFunctions: true,
|
|
58
|
+
});
|
|
59
|
+
return {
|
|
60
|
+
teardown(global) {
|
|
61
|
+
// Teardown the environment first (e.g., window.close())
|
|
62
|
+
// This needs to happen while globals are still populated
|
|
63
|
+
// because disconnectedCallback may use RAF and other polyfills
|
|
64
|
+
envTeardown();
|
|
65
|
+
// Then clean up populated globals
|
|
66
|
+
keys.forEach((key) => delete global[key]);
|
|
67
|
+
originals.forEach((v, k) => (global[k] = v));
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
},
|
|
71
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/environments/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,GAAG,OAAO,UAAU,CAAC;IACnC,QAAQ,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,OAAO,UAAU,EAAE,OAAO,EAAE,GAAG,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,uBAAuB,CAAC;AAC/B,OAAO,kCAAkC,CAAC;AAE1C,OAAO,EAAE,CAAC,EAAE,MAAM,eAAe,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Config as StencilConfig } from '@stencil/core/internal';
|
|
2
|
+
/**
|
|
3
|
+
* Load Stencil configuration from a file path
|
|
4
|
+
* Uses jiti to handle TypeScript files in Node.js
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadStencilConfig(configPath: string): Promise<StencilConfig | undefined>;
|
|
7
|
+
/**
|
|
8
|
+
* Get the source directory from Stencil config
|
|
9
|
+
*/
|
|
10
|
+
export declare function getStencilSrcDir(config?: StencilConfig): string;
|
|
11
|
+
/**
|
|
12
|
+
* Get all output directories from Stencil config for exclusion
|
|
13
|
+
*/
|
|
14
|
+
export declare function getStencilOutputDirs(config?: StencilConfig): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Create resolve aliases from Stencil config
|
|
17
|
+
*/
|
|
18
|
+
export declare function getStencilResolveAliases(config?: StencilConfig): Record<string, string>;
|
|
19
|
+
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../../src/setup/config-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAItE;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAsB9F;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM,CAE/D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM,EAAE,CAyCrE;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAmBvF"}
|