@nuxt/test-utils 3.21.0 → 3.23.0
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 +1 -1
- package/dist/config.d.mts +3 -3
- package/dist/config.mjs +40 -21
- package/dist/e2e.d.mts +3 -2
- package/dist/e2e.mjs +17 -13
- package/dist/experimental.mjs +1 -1
- package/dist/module.mjs +721 -148
- package/dist/playwright.d.mts +2 -1
- package/dist/playwright.mjs +3 -3
- package/dist/runtime/shared/environment.mjs +11 -66
- package/dist/runtime/shared/h3-v1.d.ts +6 -0
- package/dist/runtime/shared/h3-v1.mjs +69 -0
- package/dist/runtime/shared/h3-v2.d.ts +6 -0
- package/dist/runtime/shared/h3-v2.mjs +35 -0
- package/dist/runtime/shared/h3.d.ts +3 -0
- package/dist/runtime/shared/h3.mjs +3 -0
- package/dist/runtime/shared/nuxt.d.ts +1 -1
- package/dist/runtime/shared/nuxt.mjs +10 -2
- package/dist/runtime/shared/vue-wrapper-plugin.d.ts +50 -0
- package/dist/runtime/shared/vue-wrapper-plugin.mjs +41 -0
- package/dist/runtime-utils/index.d.mts +26 -25
- package/dist/runtime-utils/index.mjs +185 -272
- package/dist/shared/{test-utils.3NR-so9-.mjs → test-utils.5cnw0YZR.mjs} +2 -2
- package/dist/shared/{test-utils.G1ew4kEe.mjs → test-utils.BIY9XRkB.mjs} +1 -1
- package/dist/shared/{test-utils.CtwoJP76.mjs → test-utils.BsmyE2FA.mjs} +10 -8
- package/dist/shared/{test-utils.20kU0tZa.d.mts → test-utils.C9GKP_T5.d.mts} +3 -2
- package/dist/shared/test-utils.DDUpsMYL.mjs +32 -0
- package/dist/vitest-environment.d.mts +15 -3
- package/dist/vitest-environment.mjs +118 -66
- package/dist/vitest-wrapper/cli.d.mts +2 -0
- package/dist/vitest-wrapper/cli.mjs +78 -0
- package/package.json +32 -26
package/dist/module.mjs
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { h } from 'vue';
|
|
5
|
-
import { debounce } from 'perfect-debounce';
|
|
6
|
-
import { isCI } from 'std-env';
|
|
7
|
-
import { defu } from 'defu';
|
|
8
|
-
import { extname, join, dirname, relative } from 'pathe';
|
|
9
|
-
import { getVitestConfigFromNuxt } from './config.mjs';
|
|
1
|
+
import { resolveIgnorePatterns, logger, useNuxt, addDevServerHandler, defineNuxtModule, createResolver, resolvePath } from '@nuxt/kit';
|
|
2
|
+
import { extname, join, dirname, relative, resolve } from 'pathe';
|
|
3
|
+
import { isCI, hasTTY, provider } from 'std-env';
|
|
10
4
|
import { walk } from 'estree-walker';
|
|
11
5
|
import MagicString from 'magic-string';
|
|
12
6
|
import { createUnplugin } from 'unplugin';
|
|
13
|
-
import { l as loadKit } from './shared/test-utils.
|
|
14
|
-
import { readFileSync } from 'node:fs';
|
|
15
|
-
import 'node:process';
|
|
16
|
-
import '
|
|
17
|
-
import '
|
|
7
|
+
import { l as loadKit } from './shared/test-utils.BIY9XRkB.mjs';
|
|
8
|
+
import { readFileSync, existsSync, promises } from 'node:fs';
|
|
9
|
+
import process$1 from 'node:process';
|
|
10
|
+
import { intro, multiselect, isCancel, cancel, select, confirm, outro } from '@clack/prompts';
|
|
11
|
+
import { colors } from 'consola/utils';
|
|
12
|
+
import { detectPackageManager, addDependency } from 'nypm';
|
|
13
|
+
import { h } from 'vue';
|
|
14
|
+
import { debounce } from 'perfect-debounce';
|
|
15
|
+
import { fork } from 'node:child_process';
|
|
16
|
+
import { c as createVitestTestSummary, l as listenCliMessages, s as sendMessageToCli } from './shared/test-utils.DDUpsMYL.mjs';
|
|
17
|
+
import { distDir } from '#dirs';
|
|
18
18
|
import 'destr';
|
|
19
19
|
import 'scule';
|
|
20
|
+
import 'node:url';
|
|
20
21
|
import 'exsolve';
|
|
21
22
|
|
|
22
23
|
const PLUGIN_NAME$1 = "nuxt:vitest:mock-transform";
|
|
@@ -81,7 +82,6 @@ const createMockPlugin = (ctx) => createUnplugin(() => {
|
|
|
81
82
|
}
|
|
82
83
|
const importItem = ctx.imports.find((_) => name === (_.as || _.name));
|
|
83
84
|
if (!importItem) {
|
|
84
|
-
console.log({ imports: ctx.imports });
|
|
85
85
|
return this.error(`Cannot find import "${name}" to mock`);
|
|
86
86
|
}
|
|
87
87
|
s.overwrite(
|
|
@@ -297,178 +297,751 @@ async function setupImportMocking(nuxt) {
|
|
|
297
297
|
|
|
298
298
|
const PLUGIN_NAME = "nuxt:vitest:nuxt-root-stub";
|
|
299
299
|
const STUB_ID = "nuxt-vitest-app-entry";
|
|
300
|
-
const NuxtRootStubPlugin =
|
|
301
|
-
const
|
|
300
|
+
const NuxtRootStubPlugin = (options) => {
|
|
301
|
+
const extension = extname(options.entry);
|
|
302
|
+
const escapedExt = extension.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
303
|
+
const entryPath = join(dirname(options.entry), STUB_ID + extension);
|
|
304
|
+
const idFilter = new RegExp(`${STUB_ID}(?:${escapedExt})?$`);
|
|
302
305
|
return {
|
|
303
306
|
name: PLUGIN_NAME,
|
|
304
307
|
enforce: "pre",
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
308
|
+
resolveId: {
|
|
309
|
+
filter: {
|
|
310
|
+
id: idFilter
|
|
311
|
+
},
|
|
312
|
+
async handler(id, importer) {
|
|
313
|
+
return importer?.endsWith("index.html") ? id : entryPath;
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
load: {
|
|
317
|
+
filter: {
|
|
318
|
+
id: idFilter
|
|
319
|
+
},
|
|
320
|
+
async handler() {
|
|
321
|
+
const entryContents = readFileSync(options.entry, "utf-8");
|
|
322
|
+
return entryContents.replace("#build/root-component.mjs", options.rootStubPath);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
function generateVitestConfig(answers) {
|
|
329
|
+
let config = `import { fileURLToPath } from 'node:url'
|
|
330
|
+
import { defineConfig } from 'vitest/config'
|
|
331
|
+
import { defineVitestProject } from '@nuxt/test-utils/config'`;
|
|
332
|
+
if (answers.browserMode) {
|
|
333
|
+
config += `
|
|
334
|
+
import { playwright } from '@vitest/browser-playwright'`;
|
|
335
|
+
}
|
|
336
|
+
config += `
|
|
337
|
+
|
|
338
|
+
export default defineConfig({
|
|
339
|
+
`;
|
|
340
|
+
config += ` test: {
|
|
341
|
+
projects: [
|
|
342
|
+
`;
|
|
343
|
+
if (answers.testingScope.includes("unit")) {
|
|
344
|
+
config += ` {
|
|
345
|
+
test: {
|
|
346
|
+
name: 'unit',
|
|
347
|
+
include: ['test/unit/*.{test,spec}.ts'],
|
|
348
|
+
environment: 'node',
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
`;
|
|
352
|
+
}
|
|
353
|
+
config += ` await defineVitestProject({
|
|
354
|
+
test: {
|
|
355
|
+
name: 'nuxt',
|
|
356
|
+
include: ['test/nuxt/*.{test,spec}.ts'],
|
|
357
|
+
environment: 'nuxt',
|
|
358
|
+
environmentOptions: {
|
|
359
|
+
nuxt: {
|
|
360
|
+
rootDir: fileURLToPath(new URL('.', import.meta.url)),${answers.browserMode ? "" : `
|
|
361
|
+
domEnvironment: '${answers.domEnvironment || "happy-dom"}',`}
|
|
362
|
+
},
|
|
363
|
+
},${answers.browserMode ? `
|
|
364
|
+
browser: {
|
|
365
|
+
enabled: true,
|
|
366
|
+
provider: playwright(),
|
|
367
|
+
instances: [
|
|
368
|
+
{ browser: 'chromium' },
|
|
369
|
+
],
|
|
370
|
+
},` : ""}
|
|
371
|
+
},
|
|
372
|
+
}),
|
|
373
|
+
`;
|
|
374
|
+
if (answers.testingScope.includes("e2e") && answers.e2eRunner === "vitest") {
|
|
375
|
+
config += ` {
|
|
376
|
+
test: {
|
|
377
|
+
name: 'e2e',
|
|
378
|
+
include: ['test/e2e/*.{test,spec}.ts'],
|
|
379
|
+
environment: 'node',
|
|
380
|
+
},
|
|
381
|
+
},
|
|
382
|
+
`;
|
|
383
|
+
}
|
|
384
|
+
config += ` ],
|
|
385
|
+
`;
|
|
386
|
+
if (answers.coverage) {
|
|
387
|
+
config += ` coverage: {
|
|
388
|
+
enabled: true,
|
|
389
|
+
provider: 'v8',
|
|
390
|
+
},
|
|
391
|
+
`;
|
|
392
|
+
}
|
|
393
|
+
config += ` },
|
|
394
|
+
`;
|
|
395
|
+
config += `})
|
|
396
|
+
`;
|
|
397
|
+
return config;
|
|
398
|
+
}
|
|
399
|
+
function generatePlaywrightConfig() {
|
|
400
|
+
return `import { fileURLToPath } from 'node:url'
|
|
401
|
+
import { defineConfig, devices } from '@playwright/test'
|
|
402
|
+
import type { ConfigOptions } from '@nuxt/test-utils/playwright'
|
|
403
|
+
|
|
404
|
+
export default defineConfig<ConfigOptions>({
|
|
405
|
+
testDir: './tests',
|
|
406
|
+
fullyParallel: true,
|
|
407
|
+
forbidOnly: !!process.env.CI,
|
|
408
|
+
retries: process.env.CI ? 2 : 0,
|
|
409
|
+
workers: process.env.CI ? 1 : undefined,
|
|
410
|
+
reporter: 'html',
|
|
411
|
+
use: {
|
|
412
|
+
trace: 'on-first-retry',
|
|
413
|
+
nuxt: {
|
|
414
|
+
rootDir: fileURLToPath(new URL('.', import.meta.url)),
|
|
415
|
+
},
|
|
416
|
+
},
|
|
417
|
+
projects: [
|
|
418
|
+
{
|
|
419
|
+
name: 'chromium',
|
|
420
|
+
use: { ...devices['Desktop Chrome'] },
|
|
421
|
+
},
|
|
422
|
+
],
|
|
423
|
+
})
|
|
424
|
+
`;
|
|
425
|
+
}
|
|
426
|
+
function getDependencies(answers) {
|
|
427
|
+
const dependencies = [];
|
|
428
|
+
if (answers.testingScope.includes("unit") || answers.testingScope.includes("runtime")) {
|
|
429
|
+
dependencies.push("vitest", "@vue/test-utils");
|
|
430
|
+
if (answers.domEnvironment) {
|
|
431
|
+
dependencies.push(answers.domEnvironment);
|
|
432
|
+
}
|
|
433
|
+
if (answers.browserMode) {
|
|
434
|
+
dependencies.push("@vitest/browser-playwright");
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
if (answers.e2eRunner === "playwright") {
|
|
438
|
+
dependencies.push("@playwright/test", "playwright-core");
|
|
439
|
+
} else if (answers.e2eRunner === "cucumber") {
|
|
440
|
+
dependencies.push("@cucumber/cucumber");
|
|
441
|
+
} else if (answers.e2eRunner === "jest") {
|
|
442
|
+
dependencies.push("@jest/globals");
|
|
443
|
+
}
|
|
444
|
+
if (answers.coverage) {
|
|
445
|
+
dependencies.push("@vitest/coverage-v8");
|
|
446
|
+
}
|
|
447
|
+
return dependencies;
|
|
448
|
+
}
|
|
449
|
+
function getPackageScripts(answers) {
|
|
450
|
+
const scripts = {};
|
|
451
|
+
if (answers.testingScope.includes("unit") || answers.testingScope.includes("runtime")) {
|
|
452
|
+
scripts.test = "vitest";
|
|
453
|
+
scripts["test:watch"] = "vitest --watch";
|
|
454
|
+
if (answers.coverage) {
|
|
455
|
+
scripts["test:coverage"] = "vitest --coverage";
|
|
456
|
+
}
|
|
457
|
+
if (answers.testingScope.includes("unit")) {
|
|
458
|
+
scripts["test:unit"] = "vitest --project unit";
|
|
459
|
+
}
|
|
460
|
+
scripts["test:nuxt"] = "vitest --project nuxt";
|
|
461
|
+
if (answers.testingScope.includes("e2e") && answers.e2eRunner === "vitest") {
|
|
462
|
+
scripts["test:e2e"] = "vitest --project e2e";
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (answers.e2eRunner === "playwright") {
|
|
466
|
+
scripts["test:e2e"] = "playwright test";
|
|
467
|
+
scripts["test:e2e:ui"] = "playwright test --ui";
|
|
468
|
+
}
|
|
469
|
+
return scripts;
|
|
470
|
+
}
|
|
471
|
+
async function runInstallWizard(nuxt) {
|
|
472
|
+
if (isCI || !hasTTY || nuxt.options.test) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
if (nuxt.options.workspaceDir && nuxt.options.workspaceDir !== nuxt.options.rootDir) {
|
|
476
|
+
logger.info("Monorepo detected. Skipping setup wizard.");
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
const rootDir = nuxt.options.rootDir;
|
|
480
|
+
const hasVitestConfig = existsSync(join(rootDir, "vitest.config.ts")) || existsSync(join(rootDir, "vitest.config.js")) || existsSync(join(rootDir, "vitest.config.mts")) || existsSync(join(rootDir, "vitest.config.mjs"));
|
|
481
|
+
const hasPlaywrightConfig = existsSync(join(rootDir, "playwright.config.ts")) || existsSync(join(rootDir, "playwright.config.js"));
|
|
482
|
+
if (hasVitestConfig || hasPlaywrightConfig) {
|
|
483
|
+
logger.info("Test configuration already exists. Skipping setup wizard.");
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
intro(colors.bold(colors.cyan("\u{1F9EA} Nuxt Test Utils Setup")));
|
|
487
|
+
const answers = {};
|
|
488
|
+
const testingScope = await multiselect({
|
|
489
|
+
message: "What kind of tests will you need?",
|
|
490
|
+
options: [
|
|
491
|
+
{
|
|
492
|
+
value: "runtime",
|
|
493
|
+
label: "Runtime",
|
|
494
|
+
hint: "components or composables running in a Nuxt runtime environment"
|
|
495
|
+
},
|
|
496
|
+
{
|
|
497
|
+
value: "unit",
|
|
498
|
+
label: "Unit tests",
|
|
499
|
+
hint: "pure functions or build-time/Node tests"
|
|
500
|
+
},
|
|
501
|
+
{
|
|
502
|
+
value: "e2e",
|
|
503
|
+
label: "End-to-end",
|
|
504
|
+
hint: "full application flows in browser"
|
|
505
|
+
}
|
|
506
|
+
],
|
|
507
|
+
required: true
|
|
508
|
+
});
|
|
509
|
+
if (isCancel(testingScope)) {
|
|
510
|
+
cancel("Setup cancelled.");
|
|
511
|
+
process$1.exit(0);
|
|
512
|
+
}
|
|
513
|
+
answers.testingScope = testingScope;
|
|
514
|
+
const needsVitest = answers.testingScope.includes("unit") || answers.testingScope.includes("runtime");
|
|
515
|
+
const needsE2E = answers.testingScope.includes("e2e");
|
|
516
|
+
if (answers.testingScope.includes("runtime")) {
|
|
517
|
+
const domEnvironment = await select({
|
|
518
|
+
message: "Which Vitest environment would you like to use for runtime tests?",
|
|
519
|
+
options: [
|
|
520
|
+
{
|
|
521
|
+
value: "happy-dom",
|
|
522
|
+
label: "happy-dom",
|
|
523
|
+
hint: "recommended - faster, lighter"
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
value: "jsdom",
|
|
527
|
+
label: "jsdom",
|
|
528
|
+
hint: "more complete browser simulation"
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
value: "browser",
|
|
532
|
+
label: "browser mode",
|
|
533
|
+
hint: "real browser with Playwright"
|
|
534
|
+
}
|
|
535
|
+
],
|
|
536
|
+
initialValue: "happy-dom"
|
|
537
|
+
});
|
|
538
|
+
if (isCancel(domEnvironment)) {
|
|
539
|
+
cancel("Setup cancelled.");
|
|
540
|
+
process$1.exit(0);
|
|
541
|
+
}
|
|
542
|
+
if (domEnvironment === "browser") {
|
|
543
|
+
answers.browserMode = true;
|
|
544
|
+
} else {
|
|
545
|
+
answers.domEnvironment = domEnvironment;
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
if (needsE2E) {
|
|
549
|
+
const e2eRunner = await select({
|
|
550
|
+
message: "Which end-to-end test runner would you like to use?",
|
|
551
|
+
options: [
|
|
552
|
+
{
|
|
553
|
+
value: "playwright",
|
|
554
|
+
label: "Playwright",
|
|
555
|
+
hint: "recommended - modern, multi-browser"
|
|
556
|
+
},
|
|
557
|
+
{
|
|
558
|
+
value: "vitest",
|
|
559
|
+
label: "Vitest",
|
|
560
|
+
hint: "same runner as unit tests"
|
|
561
|
+
},
|
|
562
|
+
{
|
|
563
|
+
value: "cucumber",
|
|
564
|
+
label: "Cucumber",
|
|
565
|
+
hint: "behavior-driven development"
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
value: "jest",
|
|
569
|
+
label: "Jest",
|
|
570
|
+
hint: "legacy test runner"
|
|
309
571
|
}
|
|
572
|
+
],
|
|
573
|
+
initialValue: "playwright"
|
|
574
|
+
});
|
|
575
|
+
if (isCancel(e2eRunner)) {
|
|
576
|
+
cancel("Setup cancelled.");
|
|
577
|
+
process$1.exit(0);
|
|
578
|
+
}
|
|
579
|
+
answers.e2eRunner = e2eRunner;
|
|
580
|
+
}
|
|
581
|
+
if (needsVitest) {
|
|
582
|
+
const coverage = await confirm({
|
|
583
|
+
message: "Would you like to set up test coverage?",
|
|
584
|
+
initialValue: false
|
|
585
|
+
});
|
|
586
|
+
if (isCancel(coverage)) {
|
|
587
|
+
cancel("Setup cancelled.");
|
|
588
|
+
process$1.exit(0);
|
|
589
|
+
}
|
|
590
|
+
answers.coverage = coverage;
|
|
591
|
+
}
|
|
592
|
+
const exampleTests = await confirm({
|
|
593
|
+
message: "Create example test files?",
|
|
594
|
+
initialValue: true
|
|
595
|
+
});
|
|
596
|
+
if (isCancel(exampleTests)) {
|
|
597
|
+
cancel("Setup cancelled.");
|
|
598
|
+
process$1.exit(0);
|
|
599
|
+
}
|
|
600
|
+
answers.exampleTests = exampleTests;
|
|
601
|
+
await performSetup(nuxt, answers);
|
|
602
|
+
outro(colors.green("\u2728 Test setup complete!"));
|
|
603
|
+
}
|
|
604
|
+
async function performSetup(nuxt, answers) {
|
|
605
|
+
const rootDir = nuxt.options.rootDir;
|
|
606
|
+
const packageManager = await detectPackageManager(rootDir);
|
|
607
|
+
logger.info("Installing dependencies...");
|
|
608
|
+
const dependencies = getDependencies(answers);
|
|
609
|
+
if (dependencies.length > 0) {
|
|
610
|
+
try {
|
|
611
|
+
await addDependency(dependencies, {
|
|
612
|
+
cwd: rootDir,
|
|
613
|
+
dev: true,
|
|
614
|
+
packageManager
|
|
615
|
+
});
|
|
616
|
+
} catch (error) {
|
|
617
|
+
logger.error("Failed to install dependencies:", error);
|
|
618
|
+
return;
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
if (answers.testingScope.includes("unit") || answers.testingScope.includes("runtime")) {
|
|
622
|
+
await createVitestConfig(nuxt, answers);
|
|
623
|
+
}
|
|
624
|
+
if (answers.e2eRunner === "playwright") {
|
|
625
|
+
await createPlaywrightConfig(nuxt);
|
|
626
|
+
}
|
|
627
|
+
await createTestDirectories(nuxt, answers);
|
|
628
|
+
if (answers.exampleTests) {
|
|
629
|
+
await createExampleTests(nuxt, answers);
|
|
630
|
+
}
|
|
631
|
+
await updatePackageScripts(nuxt, answers);
|
|
632
|
+
await updateGitignore(nuxt, answers);
|
|
633
|
+
}
|
|
634
|
+
async function createVitestConfig(nuxt, answers) {
|
|
635
|
+
const rootDir = nuxt.options.rootDir;
|
|
636
|
+
const configPath = join(rootDir, "vitest.config.ts");
|
|
637
|
+
const config = generateVitestConfig(answers);
|
|
638
|
+
await promises.writeFile(configPath, config, "utf-8");
|
|
639
|
+
logger.success(`Created ${colors.cyan(relative(process$1.cwd(), configPath))}`);
|
|
640
|
+
}
|
|
641
|
+
async function createPlaywrightConfig(nuxt) {
|
|
642
|
+
const rootDir = nuxt.options.rootDir;
|
|
643
|
+
const configPath = join(rootDir, "playwright.config.ts");
|
|
644
|
+
const config = generatePlaywrightConfig();
|
|
645
|
+
await promises.writeFile(configPath, config, "utf-8");
|
|
646
|
+
logger.success(`Created ${colors.cyan(relative(process$1.cwd(), configPath))}`);
|
|
647
|
+
}
|
|
648
|
+
async function createTestDirectories(nuxt, answers) {
|
|
649
|
+
const rootDir = nuxt.options.rootDir;
|
|
650
|
+
if (answers.testingScope.includes("unit")) {
|
|
651
|
+
const unitDir = join(rootDir, "test/unit");
|
|
652
|
+
await promises.mkdir(unitDir, { recursive: true });
|
|
653
|
+
logger.success(`Created ${colors.cyan(relative(process$1.cwd(), unitDir))}`);
|
|
654
|
+
}
|
|
655
|
+
if (answers.testingScope.includes("runtime")) {
|
|
656
|
+
const nuxtDir = join(rootDir, "test/nuxt");
|
|
657
|
+
await promises.mkdir(nuxtDir, { recursive: true });
|
|
658
|
+
logger.success(`Created ${colors.cyan(relative(process$1.cwd(), nuxtDir))}`);
|
|
659
|
+
}
|
|
660
|
+
if (answers.testingScope.includes("e2e")) {
|
|
661
|
+
const e2eDir = answers.e2eRunner === "playwright" ? join(rootDir, "tests") : join(rootDir, "test/e2e");
|
|
662
|
+
await promises.mkdir(e2eDir, { recursive: true });
|
|
663
|
+
logger.success(`Created ${colors.cyan(relative(process$1.cwd(), e2eDir))}`);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
async function createExampleTests(nuxt, answers) {
|
|
667
|
+
const rootDir = nuxt.options.rootDir;
|
|
668
|
+
if (answers.testingScope.includes("unit")) {
|
|
669
|
+
const unitTestPath = join(rootDir, "test/unit/example.test.ts");
|
|
670
|
+
const unitTest = `import { describe, expect, it } from 'vitest'
|
|
671
|
+
|
|
672
|
+
describe('example unit test', () => {
|
|
673
|
+
it('should pass', () => {
|
|
674
|
+
expect(1 + 1).toBe(2)
|
|
675
|
+
})
|
|
676
|
+
})
|
|
677
|
+
`;
|
|
678
|
+
await promises.writeFile(unitTestPath, unitTest, "utf-8");
|
|
679
|
+
logger.success(`Created ${colors.cyan(relative(process$1.cwd(), unitTestPath))}`);
|
|
680
|
+
}
|
|
681
|
+
if (answers.testingScope.includes("runtime")) {
|
|
682
|
+
const componentTestPath = join(rootDir, "test/nuxt/component.test.ts");
|
|
683
|
+
const componentTest = `import { describe, expect, it } from 'vitest'
|
|
684
|
+
import { mountSuspended } from '@nuxt/test-utils/runtime'
|
|
685
|
+
import { defineComponent, h } from 'vue'
|
|
686
|
+
|
|
687
|
+
describe('component test example', () => {
|
|
688
|
+
it('can mount components', async () => {
|
|
689
|
+
const TestComponent = defineComponent({
|
|
690
|
+
setup() {
|
|
691
|
+
return () => h('div', 'Hello Nuxt!')
|
|
310
692
|
},
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
693
|
+
})
|
|
694
|
+
|
|
695
|
+
const component = await mountSuspended(TestComponent)
|
|
696
|
+
|
|
697
|
+
expect(component.text()).toBe('Hello Nuxt!')
|
|
698
|
+
})
|
|
699
|
+
})
|
|
700
|
+
`;
|
|
701
|
+
await promises.writeFile(componentTestPath, componentTest, "utf-8");
|
|
702
|
+
logger.success(`Created ${colors.cyan(relative(process$1.cwd(), componentTestPath))}`);
|
|
703
|
+
}
|
|
704
|
+
if (answers.testingScope.includes("e2e")) {
|
|
705
|
+
if (answers.e2eRunner === "playwright") {
|
|
706
|
+
const e2eTestPath = join(rootDir, "tests/example.spec.ts");
|
|
707
|
+
const e2eTest = `import { expect, test } from '@nuxt/test-utils/playwright'
|
|
708
|
+
|
|
709
|
+
test('example e2e test', async ({ page, goto }) => {
|
|
710
|
+
await goto('/', { waitUntil: 'hydration' })
|
|
711
|
+
await expect(page).toHaveTitle(/Nuxt/)
|
|
712
|
+
})
|
|
713
|
+
`;
|
|
714
|
+
await promises.writeFile(e2eTestPath, e2eTest, "utf-8");
|
|
715
|
+
logger.success(`Created ${colors.cyan(relative(process$1.cwd(), e2eTestPath))}`);
|
|
716
|
+
} else {
|
|
717
|
+
const e2eTestPath = join(rootDir, "test/e2e/example.test.ts");
|
|
718
|
+
const e2eTest = `import { describe, expect, it } from 'vitest'
|
|
719
|
+
import { $fetch, setup } from '@nuxt/test-utils/e2e'
|
|
720
|
+
|
|
721
|
+
describe('example e2e test', async () => {
|
|
722
|
+
await setup()
|
|
723
|
+
|
|
724
|
+
it('renders the index page', async () => {
|
|
725
|
+
const html = await $fetch('/')
|
|
726
|
+
expect(html).toContain('Nuxt')
|
|
727
|
+
})
|
|
728
|
+
})
|
|
729
|
+
`;
|
|
730
|
+
await promises.writeFile(e2eTestPath, e2eTest, "utf-8");
|
|
731
|
+
logger.success(`Created ${colors.cyan(relative(process$1.cwd(), e2eTestPath))}`);
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
async function updatePackageScripts(nuxt, answers) {
|
|
736
|
+
const rootDir = nuxt.options.rootDir;
|
|
737
|
+
const packageJsonPath = join(rootDir, "package.json");
|
|
738
|
+
const packageJson = JSON.parse(await promises.readFile(packageJsonPath, "utf-8"));
|
|
739
|
+
packageJson.scripts = packageJson.scripts || {};
|
|
740
|
+
const newScripts = getPackageScripts(answers);
|
|
741
|
+
Object.assign(packageJson.scripts, newScripts);
|
|
742
|
+
await promises.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n", "utf-8");
|
|
743
|
+
logger.success("Updated package.json scripts");
|
|
744
|
+
}
|
|
745
|
+
async function updateGitignore(nuxt, answers) {
|
|
746
|
+
const rootDir = nuxt.options.rootDir;
|
|
747
|
+
const gitignorePath = join(rootDir, ".gitignore");
|
|
748
|
+
let gitignore = "";
|
|
749
|
+
if (existsSync(gitignorePath)) {
|
|
750
|
+
gitignore = await promises.readFile(gitignorePath, "utf-8");
|
|
751
|
+
}
|
|
752
|
+
const lines = [];
|
|
753
|
+
if (answers.coverage && !gitignore.includes("coverage")) {
|
|
754
|
+
lines.push("# Test coverage", "coverage/", "");
|
|
755
|
+
}
|
|
756
|
+
if (answers.e2eRunner === "playwright") {
|
|
757
|
+
if (!gitignore.includes("playwright-report")) {
|
|
758
|
+
lines.push("# Playwright", "playwright-report/", "test-results/", "");
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
if (lines.length > 0) {
|
|
762
|
+
gitignore += "\n" + lines.join("\n");
|
|
763
|
+
await promises.writeFile(gitignorePath, gitignore, "utf-8");
|
|
764
|
+
logger.success("Updated .gitignore");
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
async function setupDevTools(vitestWrapper, nuxt = useNuxt()) {
|
|
769
|
+
const iframeSrc = "/__test_utils_vitest__/";
|
|
770
|
+
const updateTabs = debounce(() => {
|
|
771
|
+
nuxt.callHook("devtools:customTabs:refresh");
|
|
772
|
+
}, 100);
|
|
773
|
+
nuxt.hook("devtools:customTabs", (tabs) => {
|
|
774
|
+
const tab = createVitestCustomTab(vitestWrapper, { iframeSrc });
|
|
775
|
+
const index = tabs.findIndex(({ name }) => tab.name === name);
|
|
776
|
+
if (index === -1) {
|
|
777
|
+
tabs.push(tab);
|
|
778
|
+
} else {
|
|
779
|
+
tabs.splice(index, 1, tab);
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
addDevServerHandler({
|
|
783
|
+
route: iframeSrc,
|
|
784
|
+
handler: Object.assign(() => iframeContentHtml(vitestWrapper.uiUrl), { __is_handler__: true })
|
|
785
|
+
});
|
|
786
|
+
vitestWrapper.ons({
|
|
787
|
+
started() {
|
|
788
|
+
updateTabs();
|
|
789
|
+
},
|
|
790
|
+
updated() {
|
|
791
|
+
updateTabs();
|
|
792
|
+
},
|
|
793
|
+
finished() {
|
|
794
|
+
updateTabs();
|
|
795
|
+
},
|
|
796
|
+
exited() {
|
|
797
|
+
updateTabs();
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
function createVitestCustomTab(vitest, { iframeSrc }) {
|
|
802
|
+
const launchView = {
|
|
803
|
+
type: "launch",
|
|
804
|
+
description: "Start tests along with Nuxt",
|
|
805
|
+
actions: [
|
|
806
|
+
{
|
|
807
|
+
get label() {
|
|
808
|
+
switch (vitest.status) {
|
|
809
|
+
case "starting":
|
|
810
|
+
return "Starting...";
|
|
811
|
+
case "running":
|
|
812
|
+
return "Running Vitest";
|
|
813
|
+
case "stopped":
|
|
814
|
+
return "Start Vitest";
|
|
815
|
+
case "finished":
|
|
816
|
+
return "Start Vitest";
|
|
817
|
+
}
|
|
818
|
+
},
|
|
819
|
+
get pending() {
|
|
820
|
+
return vitest.status === "starting" || vitest.status === "running";
|
|
821
|
+
},
|
|
822
|
+
handle: () => {
|
|
823
|
+
vitest.start();
|
|
315
824
|
}
|
|
316
825
|
}
|
|
826
|
+
]
|
|
827
|
+
};
|
|
828
|
+
const uiView = {
|
|
829
|
+
type: "iframe",
|
|
830
|
+
persistent: false,
|
|
831
|
+
src: iframeSrc
|
|
832
|
+
};
|
|
833
|
+
const tab = {
|
|
834
|
+
title: "Vitest",
|
|
835
|
+
name: "vitest",
|
|
836
|
+
icon: "logos-vitest",
|
|
837
|
+
get view() {
|
|
838
|
+
if (vitest.status === "stopped" || vitest.status === "starting" || !vitest.uiUrl) {
|
|
839
|
+
return launchView;
|
|
840
|
+
} else {
|
|
841
|
+
return uiView;
|
|
842
|
+
}
|
|
843
|
+
},
|
|
844
|
+
extraTabVNode: vitest.testSummary.totalCount ? h("div", { style: { color: vitest.testSummary.failedCount ? "orange" : "green" } }, [
|
|
845
|
+
h("span", {}, vitest.testSummary.passedCount),
|
|
846
|
+
h("span", { style: { opacity: "0.5", fontSize: "0.9em" } }, "/"),
|
|
847
|
+
h(
|
|
848
|
+
"span",
|
|
849
|
+
{ style: { opacity: "0.8", fontSize: "0.9em" } },
|
|
850
|
+
vitest.testSummary.totalCount
|
|
851
|
+
)
|
|
852
|
+
]) : void 0
|
|
853
|
+
};
|
|
854
|
+
return tab;
|
|
855
|
+
}
|
|
856
|
+
function iframeContentHtml(uiUrl) {
|
|
857
|
+
return [
|
|
858
|
+
"<html><head><script>",
|
|
859
|
+
`(${function redirect(uiUrl2, provider2) {
|
|
860
|
+
if (typeof window === "undefined") return;
|
|
861
|
+
if (!uiUrl2) return;
|
|
862
|
+
if (provider2 === "stackblitz") {
|
|
863
|
+
const url = new URL(window.location.href);
|
|
864
|
+
const newUrl = new URL(uiUrl2);
|
|
865
|
+
newUrl.host = url.host.replace(/--\d+--/, `--${newUrl.port}--`);
|
|
866
|
+
newUrl.protocol = url.protocol;
|
|
867
|
+
newUrl.port = url.port;
|
|
868
|
+
uiUrl2 = newUrl.toString();
|
|
869
|
+
}
|
|
870
|
+
window.location.replace(uiUrl2);
|
|
871
|
+
}})(${JSON.stringify(uiUrl)}, ${JSON.stringify(provider)})`,
|
|
872
|
+
"<\/script></head></html>"
|
|
873
|
+
].join("\n");
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
function vitestWrapper(options) {
|
|
877
|
+
const { cwd, ...startOptions } = options;
|
|
878
|
+
let _status = "stopped";
|
|
879
|
+
let _uiUrl;
|
|
880
|
+
let _process;
|
|
881
|
+
let _testSummary = createVitestTestSummary();
|
|
882
|
+
const _handlers = {
|
|
883
|
+
started: [({ uiUrl }) => {
|
|
884
|
+
_uiUrl = uiUrl;
|
|
885
|
+
_status = "running";
|
|
886
|
+
_testSummary = createVitestTestSummary();
|
|
887
|
+
}],
|
|
888
|
+
updated: [(summary) => {
|
|
889
|
+
_testSummary = summary;
|
|
890
|
+
}],
|
|
891
|
+
finished: [(summary) => {
|
|
892
|
+
_status = "finished";
|
|
893
|
+
_testSummary = summary;
|
|
894
|
+
}],
|
|
895
|
+
exited: [clear]
|
|
896
|
+
};
|
|
897
|
+
function clear() {
|
|
898
|
+
_status = "stopped";
|
|
899
|
+
_uiUrl = void 0;
|
|
900
|
+
_process = void 0;
|
|
901
|
+
_testSummary = createVitestTestSummary();
|
|
902
|
+
}
|
|
903
|
+
function on(name, handler) {
|
|
904
|
+
_handlers[name] ??= [];
|
|
905
|
+
_handlers[name]?.push(handler);
|
|
906
|
+
}
|
|
907
|
+
function ons(handlers) {
|
|
908
|
+
for (const [name, handler] of Object.entries(handlers)) {
|
|
909
|
+
if (typeof handler === "function") {
|
|
910
|
+
on(name, handler);
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
async function stop() {
|
|
915
|
+
const vitest = _process;
|
|
916
|
+
if (!vitest || vitest.exitCode !== null) return;
|
|
917
|
+
return new Promise((resolve2) => {
|
|
918
|
+
vitest.once("exit", () => resolve2());
|
|
919
|
+
sendMessageToCli(vitest, "stop", { force: true });
|
|
920
|
+
});
|
|
921
|
+
}
|
|
922
|
+
async function start() {
|
|
923
|
+
if (_process) return false;
|
|
924
|
+
const vitest = fork(resolve(distDir, "./vitest-wrapper/cli.mjs"), {
|
|
925
|
+
cwd,
|
|
926
|
+
env: {
|
|
927
|
+
...process.env,
|
|
928
|
+
NODE_ENV: "test",
|
|
929
|
+
MODE: "test"
|
|
930
|
+
},
|
|
931
|
+
stdio: startOptions.logToConsole ? void 0 : ["ignore", "ignore", "inherit", "ipc"]
|
|
932
|
+
});
|
|
933
|
+
_status = "starting";
|
|
934
|
+
_process = vitest;
|
|
935
|
+
vitest.once("exit", () => {
|
|
936
|
+
_handlers.exited.forEach((fn) => fn({ exitCode: vitest.exitCode ?? 0 }));
|
|
937
|
+
});
|
|
938
|
+
listenCliMessages(vitest, ({ type, payload }) => {
|
|
939
|
+
_handlers[type].forEach((fn) => fn(payload));
|
|
940
|
+
});
|
|
941
|
+
sendMessageToCli(vitest, "start", startOptions);
|
|
942
|
+
return true;
|
|
943
|
+
}
|
|
944
|
+
return {
|
|
945
|
+
on,
|
|
946
|
+
ons,
|
|
947
|
+
stop,
|
|
948
|
+
start,
|
|
949
|
+
get uiUrl() {
|
|
950
|
+
return _uiUrl;
|
|
951
|
+
},
|
|
952
|
+
get options() {
|
|
953
|
+
return options;
|
|
954
|
+
},
|
|
955
|
+
get status() {
|
|
956
|
+
return _status;
|
|
957
|
+
},
|
|
958
|
+
get testSummary() {
|
|
959
|
+
return { ..._testSummary };
|
|
317
960
|
}
|
|
318
961
|
};
|
|
319
|
-
}
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
const version = "3.23.0";
|
|
965
|
+
const pkg = {
|
|
966
|
+
version: version};
|
|
320
967
|
|
|
321
|
-
const vitePluginBlocklist = ["vite-plugin-vue-inspector", "vite-plugin-vue-inspector:post", "vite-plugin-inspect", "nuxt:type-check"];
|
|
322
968
|
const module$1 = defineNuxtModule({
|
|
323
969
|
meta: {
|
|
324
970
|
name: "@nuxt/test-utils",
|
|
325
|
-
configKey: "testUtils"
|
|
971
|
+
configKey: "testUtils",
|
|
972
|
+
version: pkg.version
|
|
326
973
|
},
|
|
327
974
|
defaults: {
|
|
328
975
|
startOnBoot: false,
|
|
329
976
|
logToConsole: false
|
|
330
977
|
},
|
|
978
|
+
async onInstall(nuxt) {
|
|
979
|
+
await runInstallWizard(nuxt);
|
|
980
|
+
},
|
|
331
981
|
async setup(options, nuxt) {
|
|
332
982
|
if (nuxt.options.test || nuxt.options.dev) {
|
|
333
983
|
await setupImportMocking(nuxt);
|
|
334
984
|
}
|
|
335
985
|
const { addVitePlugin } = await loadKit(nuxt.options.rootDir);
|
|
336
986
|
const resolver = createResolver(import.meta.url);
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
987
|
+
if (nuxt.options.test || nuxt.options.dev) {
|
|
988
|
+
addVitePlugin(NuxtRootStubPlugin({
|
|
989
|
+
entry: await resolvePath("#app/entry", { alias: nuxt.options.alias }),
|
|
990
|
+
rootStubPath: await resolvePath(resolver.resolve("./runtime/nuxt-root"))
|
|
991
|
+
}));
|
|
992
|
+
}
|
|
341
993
|
if (!nuxt.options.test && !nuxt.options.dev) {
|
|
342
994
|
nuxt.options.vite.define ||= {};
|
|
343
995
|
nuxt.options.vite.define["import.meta.vitest"] = "undefined";
|
|
344
996
|
}
|
|
345
|
-
nuxt.hook("prepare:types", (
|
|
346
|
-
|
|
347
|
-
if (
|
|
348
|
-
|
|
349
|
-
|
|
997
|
+
nuxt.hook("prepare:types", (ctx) => {
|
|
998
|
+
ctx.references.push({ types: "vitest/import-meta" });
|
|
999
|
+
if (ctx.nodeTsConfig) {
|
|
1000
|
+
ctx.nodeTsConfig.include ||= [];
|
|
1001
|
+
ctx.nodeTsConfig.include.push(relative(nuxt.options.buildDir, join(nuxt.options.rootDir, "vitest.config.*")));
|
|
350
1002
|
if (nuxt.options.workspaceDir !== nuxt.options.rootDir) {
|
|
351
|
-
|
|
1003
|
+
ctx.nodeTsConfig.include.push(relative(nuxt.options.buildDir, join(nuxt.options.workspaceDir, "vitest.config.*")));
|
|
352
1004
|
}
|
|
353
1005
|
}
|
|
354
1006
|
});
|
|
355
1007
|
if (!nuxt.options.dev) return;
|
|
356
1008
|
if (process.env.TEST || process.env.VITE_TEST) return;
|
|
357
|
-
const
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if (isClient) resolve(config);
|
|
361
|
-
});
|
|
362
|
-
});
|
|
363
|
-
});
|
|
364
|
-
let loaded = false;
|
|
365
|
-
let promise;
|
|
366
|
-
let ctx = void 0;
|
|
367
|
-
let testFiles = null;
|
|
368
|
-
const updateTabs = debounce(() => {
|
|
369
|
-
nuxt.callHook("devtools:customTabs:refresh");
|
|
370
|
-
}, 100);
|
|
371
|
-
let URL;
|
|
372
|
-
async function start() {
|
|
373
|
-
const { mergeConfig } = await importModule("vite", { paths: nuxt.options.modulesDir });
|
|
374
|
-
const rawViteConfig = mergeConfig({}, await rawViteConfigPromise);
|
|
375
|
-
const viteConfig = await getVitestConfigFromNuxt({ nuxt, viteConfig: defu({ test: options.vitestConfig }, rawViteConfig) });
|
|
376
|
-
viteConfig.plugins = (viteConfig.plugins || []).filter((p) => {
|
|
377
|
-
return !p || !("name" in p) || !vitePluginBlocklist.includes(p.name);
|
|
378
|
-
});
|
|
379
|
-
viteConfig.test.environmentMatchGlobs ||= [];
|
|
380
|
-
viteConfig.test.environmentMatchGlobs.push(
|
|
381
|
-
["**/*.nuxt.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}", "nuxt"],
|
|
382
|
-
["{test,tests}/nuxt/**.*", "nuxt"]
|
|
383
|
-
);
|
|
384
|
-
process.env.__NUXT_VITEST_RESOLVED__ = "true";
|
|
385
|
-
const { startVitest } = await import(pathToFileURL(await resolvePath("vitest/node")).href);
|
|
386
|
-
const customReporter = {
|
|
387
|
-
onInit(_ctx) {
|
|
388
|
-
ctx = _ctx;
|
|
389
|
-
},
|
|
390
|
-
onTaskUpdate() {
|
|
391
|
-
testFiles = ctx.state.getFiles();
|
|
392
|
-
updateTabs();
|
|
393
|
-
},
|
|
394
|
-
onFinished() {
|
|
395
|
-
testFiles = ctx.state.getFiles();
|
|
396
|
-
updateTabs();
|
|
397
|
-
}
|
|
398
|
-
};
|
|
399
|
-
const watchMode = !process.env.NUXT_VITEST_DEV_TEST && !isCI;
|
|
400
|
-
const PORT = await getPort({ port: 15555 });
|
|
401
|
-
const PROTOCOL = nuxt.options.devServer.https ? "https" : "http";
|
|
402
|
-
URL = `${PROTOCOL}://localhost:${PORT}/__vitest__/`;
|
|
403
|
-
const overrides = watchMode ? {
|
|
404
|
-
passWithNoTests: true,
|
|
405
|
-
reporters: options.logToConsole ? [
|
|
406
|
-
...toArray(options.vitestConfig?.reporters ?? ["default"]),
|
|
407
|
-
customReporter
|
|
408
|
-
] : [customReporter],
|
|
409
|
-
// do not report to console
|
|
410
|
-
watch: true,
|
|
411
|
-
ui: true,
|
|
412
|
-
open: false,
|
|
413
|
-
api: {
|
|
414
|
-
port: PORT
|
|
415
|
-
}
|
|
416
|
-
} : { watch: false };
|
|
417
|
-
const promise2 = startVitest("test", [], defu(overrides, viteConfig.test), viteConfig);
|
|
418
|
-
promise2.catch(() => process.exit(1));
|
|
419
|
-
if (watchMode) {
|
|
420
|
-
logger.info(`Vitest UI starting on ${URL}`);
|
|
421
|
-
nuxt.hook("close", () => promise2.then((v) => v?.close()));
|
|
422
|
-
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
423
|
-
} else {
|
|
424
|
-
promise2.then((v) => nuxt.close().then(() => v?.close()).then(() => process.exit()));
|
|
425
|
-
}
|
|
426
|
-
loaded = true;
|
|
427
|
-
}
|
|
428
|
-
nuxt.hook("devtools:customTabs", (tabs) => {
|
|
429
|
-
const failedCount = testFiles?.filter((f) => f.result?.state === "fail").length ?? 0;
|
|
430
|
-
const passedCount = testFiles?.filter((f) => f.result?.state === "pass").length ?? 0;
|
|
431
|
-
const totalCount = testFiles?.length ?? 0;
|
|
432
|
-
tabs.push({
|
|
433
|
-
title: "Vitest",
|
|
434
|
-
name: "vitest",
|
|
435
|
-
icon: "logos-vitest",
|
|
436
|
-
view: loaded ? {
|
|
437
|
-
type: "iframe",
|
|
438
|
-
src: URL
|
|
439
|
-
} : {
|
|
440
|
-
type: "launch",
|
|
441
|
-
description: "Start tests along with Nuxt",
|
|
442
|
-
actions: [
|
|
443
|
-
{
|
|
444
|
-
label: promise ? "Starting..." : "Start Vitest",
|
|
445
|
-
pending: !!promise,
|
|
446
|
-
handle: () => {
|
|
447
|
-
promise = promise || start();
|
|
448
|
-
return promise;
|
|
449
|
-
}
|
|
450
|
-
}
|
|
451
|
-
]
|
|
452
|
-
},
|
|
453
|
-
extraTabVNode: totalCount ? h("div", { style: { color: failedCount ? "orange" : "green" } }, [
|
|
454
|
-
h("span", {}, passedCount),
|
|
455
|
-
h("span", { style: { opacity: "0.5", fontSize: "0.9em" } }, "/"),
|
|
456
|
-
h(
|
|
457
|
-
"span",
|
|
458
|
-
{ style: { opacity: "0.8", fontSize: "0.9em" } },
|
|
459
|
-
totalCount
|
|
460
|
-
)
|
|
461
|
-
]) : void 0
|
|
462
|
-
});
|
|
1009
|
+
const vitestWrapper2 = createVitestWrapper(options, nuxt);
|
|
1010
|
+
nuxt.hook("devtools:before", async () => {
|
|
1011
|
+
await setupDevTools(vitestWrapper2, nuxt);
|
|
463
1012
|
});
|
|
464
1013
|
if (options.startOnBoot) {
|
|
465
|
-
|
|
466
|
-
promise.then(updateTabs);
|
|
1014
|
+
vitestWrapper2.start();
|
|
467
1015
|
}
|
|
468
1016
|
}
|
|
469
1017
|
});
|
|
470
|
-
function
|
|
471
|
-
|
|
1018
|
+
function createVitestWrapper(options, nuxt = useNuxt()) {
|
|
1019
|
+
const watchMode = !isCI;
|
|
1020
|
+
const wrapper = vitestWrapper({
|
|
1021
|
+
cwd: nuxt.options.rootDir,
|
|
1022
|
+
apiPorts: [15555],
|
|
1023
|
+
logToConsole: options.logToConsole ?? false,
|
|
1024
|
+
watchMode
|
|
1025
|
+
});
|
|
1026
|
+
wrapper.ons({
|
|
1027
|
+
started({ uiUrl }) {
|
|
1028
|
+
if (watchMode) {
|
|
1029
|
+
logger.info(`Vitest UI starting on ${uiUrl}`);
|
|
1030
|
+
}
|
|
1031
|
+
},
|
|
1032
|
+
exited({ exitCode }) {
|
|
1033
|
+
if (watchMode) {
|
|
1034
|
+
logger.info(`Vitest exited with code ${exitCode}`);
|
|
1035
|
+
} else {
|
|
1036
|
+
nuxt.close().finally(() => process.exit(exitCode));
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
});
|
|
1040
|
+
nuxt.hooks.addHooks({
|
|
1041
|
+
close: () => wrapper.stop(),
|
|
1042
|
+
restart: () => wrapper.stop()
|
|
1043
|
+
});
|
|
1044
|
+
return wrapper;
|
|
472
1045
|
}
|
|
473
1046
|
|
|
474
1047
|
export { module$1 as default };
|