-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvite.config.ts
More file actions
239 lines (237 loc) · 8.03 KB
/
Copy pathvite.config.ts
File metadata and controls
239 lines (237 loc) · 8.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
/// <reference types="vitest" />
import { defineConfig } from 'vite';
import path from 'path';
import fs from 'fs';
import { transcriptPersistPlugin } from './scripts/vite-transcript-plugin';
// Read version from package.json (single source of truth)
const pkg = JSON.parse(fs.readFileSync(path.resolve(__dirname, 'package.json'), 'utf-8'));
const APP_VERSION = pkg.version;
export default defineConfig(({ mode, command }) => ({
define: {
__APP_VERSION__: JSON.stringify(APP_VERSION),
},
// Use the repo sub-path for production builds (GitHub Pages);
// keep '/' for local development so localhost:3000 works as expected.
// The electron mode emits relative asset URLs ('./') so the built app can
// be loaded via Electron's file:// protocol (no server, no absolute paths).
base: mode === 'electron' ? './' : mode === 'production' ? '/Tableau-Card-Engine/' : '/',
plugins: [
// Only register the transcript persistence plugin during normal dev-server runs.
// Vitest browser uses an internal Vite server; avoid plugin middleware there to
// prevent file-system side effects and extra request handling during tests.
...(command === 'serve' && !process.env.VITEST ? [transcriptPersistPlugin()] : []),
],
resolve: {
alias: {
'@core-engine': path.resolve(__dirname, 'src/core-engine'),
'@card-system': path.resolve(__dirname, 'src/card-system'),
'@rule-engine': path.resolve(__dirname, 'src/rule-engine'),
'@ui': path.resolve(__dirname, 'src/ui'),
'@ai': path.resolve(__dirname, 'src/ai'),
},
},
build: {
outDir: 'dist',
sourcemap: true,
},
server: {
port: 3000,
open: false,
},
test: {
projects: [
// ── Unit Tests (Node environment) ─────────────────
{
extends: true,
test: {
name: 'unit',
globals: true,
environment: 'node',
include: ['tests/**/*.test.ts'],
exclude: [
'tests/**/*.browser.test.ts',
'tests/e2e/replay-*.test.ts',
// Electron launch smoke test runs in its own project (needs a
// display and the built Electron app).
'tests/electron/launch-smoke.test.ts',
],
testTimeout: 15_000,
// Worker-pool cap (fan-out bounding, SA-0MSAEKOQE009TEB4): bound the
// number of concurrent tinypool workers so parallel test runs do not
// spawn 15+ node processes per vitest invocation. Mirrors the
// ContextHub vitest cap (maxWorkers: 4).
maxWorkers: 4,
},
},
// ── Replay E2E Tests — isolated from parallel unit tests to avoid
// cold Vite compilation timeout under CPU contention ──────────────
{
extends: true,
test: {
name: 'replay-e2e',
globals: true,
environment: 'node',
include: ['tests/e2e/replay-*.test.ts'],
fileParallelism: false,
sequence: { concurrent: false },
testTimeout: 180_000,
pool: 'forks',
poolOptions: {
forks: {
singleFork: true,
},
},
},
},
// ── Electron Launch Smoke Test — isolated project; needs a display
// (xvfb on headless Linux) and the built Electron app. Run via
// `npx vitest run --project electron` or the CI electron stage.
// Excluded from the unit project so the fast unit suite stays fast. ────
{
extends: true,
test: {
name: 'electron',
globals: true,
environment: 'node',
include: ['tests/electron/launch-smoke.test.ts'],
fileParallelism: false,
sequence: { concurrent: false },
testTimeout: 180_000,
hookTimeout: 240_000,
},
},
// ── Non-Tutorial Browser Tests ────────────────────
{
extends: true,
test: {
name: 'browser',
include: ['tests/**/*.browser.test.ts'],
exclude: ['tests/e2e/main-street-tutorial-e2e-*.browser.test.ts'],
fileParallelism: false,
sequence: { concurrent: false },
testTimeout: 30_000,
browser: {
enabled: true,
provider: 'playwright',
headless: true,
instances: [{ browser: 'chromium' }],
viewport: { width: 900, height: 700 },
isolate: true,
},
},
},
// ── Tutorial E2E Tests (each in its own browser context) ──
// Each part gets its own project with a uniquely-named browser
// instance to prevent canvas/GPU context exhaustion from
// sequential Phaser game create/destroy cycles.
{
extends: true,
test: {
name: 'tutorial-part1',
include: ['tests/e2e/main-street-tutorial-e2e-part1.browser.test.ts'],
fileParallelism: false,
sequence: { concurrent: false },
testTimeout: 30_000,
browser: {
enabled: true,
provider: 'playwright',
headless: true,
instances: [{ browser: 'chromium', name: 't1' }],
viewport: { width: 900, height: 700 },
isolate: true,
},
},
},
{
extends: true,
test: {
name: 'tutorial-part2',
include: ['tests/e2e/main-street-tutorial-e2e-part2.browser.test.ts'],
fileParallelism: false,
sequence: { concurrent: false },
testTimeout: 30_000,
browser: {
enabled: true,
provider: 'playwright',
headless: true,
instances: [{ browser: 'chromium', name: 't2' }],
viewport: { width: 900, height: 700 },
isolate: true,
},
},
},
{
extends: true,
test: {
name: 'tutorial-part3',
include: ['tests/e2e/main-street-tutorial-e2e-part3.browser.test.ts'],
fileParallelism: false,
sequence: { concurrent: false },
testTimeout: 30_000,
browser: {
enabled: true,
provider: 'playwright',
headless: true,
instances: [{ browser: 'chromium', name: 't3' }],
viewport: { width: 900, height: 700 },
isolate: true,
},
},
},
{
extends: true,
test: {
name: 'tutorial-part4',
include: ['tests/e2e/main-street-tutorial-e2e-part4.browser.test.ts'],
fileParallelism: false,
sequence: { concurrent: false },
testTimeout: 30_000,
browser: {
enabled: true,
provider: 'playwright',
headless: true,
instances: [{ browser: 'chromium', name: 't4' }],
viewport: { width: 900, height: 700 },
isolate: true,
},
},
},
{
extends: true,
test: {
name: 'tutorial-part5',
include: ['tests/e2e/main-street-tutorial-e2e-part5.browser.test.ts'],
fileParallelism: false,
sequence: { concurrent: false },
testTimeout: 30_000,
browser: {
enabled: true,
provider: 'playwright',
headless: true,
instances: [{ browser: 'chromium', name: 't5' }],
viewport: { width: 900, height: 700 },
isolate: true,
},
},
},
{
extends: true,
test: {
name: 'tutorial-part6',
include: ['tests/e2e/main-street-tutorial-e2e-part6.browser.test.ts'],
fileParallelism: false,
sequence: { concurrent: false },
testTimeout: 30_000,
browser: {
enabled: true,
provider: 'playwright',
headless: true,
instances: [{ browser: 'chromium', name: 't6' }],
viewport: { width: 900, height: 700 },
isolate: true,
},
},
},
],
},
}));