@aamini/config 0.0.13 → 0.0.15

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.
Files changed (56) hide show
  1. package/dist/{playwright.shared.config.d.mts → playwright.d.mts} +2 -3
  2. package/dist/{playwright.shared.config.mjs → playwright.mjs} +2 -3
  3. package/dist/playwright.mjs.map +1 -0
  4. package/dist/setup/styles.mjs +0 -1
  5. package/dist/test/browser.d.mts +7 -2
  6. package/dist/test/browser.mjs +5 -3
  7. package/dist/test/browser.mjs.map +1 -1
  8. package/dist/test/db.d.mts +34 -7
  9. package/dist/test/db.mjs +29 -15
  10. package/dist/test/db.mjs.map +1 -1
  11. package/dist/test/server.d.mts +7 -3
  12. package/dist/test/server.mjs +3 -4
  13. package/dist/test/server.mjs.map +1 -1
  14. package/dist/test/visual-page.d.mts +18 -24
  15. package/dist/test/visual-page.mjs +16 -10
  16. package/dist/test/visual-page.mjs.map +1 -1
  17. package/dist/vite.d.mts +81 -0
  18. package/dist/vite.mjs +211 -0
  19. package/dist/vite.mjs.map +1 -0
  20. package/package.json +38 -45
  21. package/tsconfig/tsconfig.tanstack.json +1 -1
  22. package/dist/internal-Dshd0hdM.mjs +0 -22
  23. package/dist/internal-Dshd0hdM.mjs.map +0 -1
  24. package/dist/playwright.shared.config.mjs.map +0 -1
  25. package/dist/test/database.d.mts +0 -22
  26. package/dist/test/database.mjs +0 -18
  27. package/dist/test/database.mjs.map +0 -1
  28. package/dist/test/playwright.d.mts +0 -7
  29. package/dist/test/playwright.mjs +0 -15
  30. package/dist/test/playwright.mjs.map +0 -1
  31. package/dist/test/postgres.d.mts +0 -14
  32. package/dist/test/postgres.mjs +0 -25
  33. package/dist/test/postgres.mjs.map +0 -1
  34. package/dist/vite.shared.d.mts +0 -379
  35. package/dist/vite.shared.mjs +0 -302
  36. package/dist/vite.shared.mjs.map +0 -1
  37. package/dist/vitest.shared.d.mts +0 -12
  38. package/dist/vitest.shared.mjs +0 -122
  39. package/dist/vitest.shared.mjs.map +0 -1
  40. package/msw.ts +0 -5
  41. package/playwright.shared.config.ts +0 -71
  42. package/setup/styles.ts +0 -4
  43. package/test/browser.ts +0 -44
  44. package/test/database.ts +0 -38
  45. package/test/db.ts +0 -86
  46. package/test/internal.ts +0 -45
  47. package/test/playwright.ts +0 -17
  48. package/test/postgres.ts +0 -43
  49. package/test/server.ts +0 -43
  50. package/test/visual-page.ts +0 -57
  51. package/tsconfig/tsconfig.astro.json +0 -34
  52. package/tsconfig/tsconfig.react.json +0 -16
  53. package/virtual-modules.d.ts +0 -6
  54. package/vite.config.ts +0 -53
  55. package/vite.shared.ts +0 -411
  56. package/vitest.shared.ts +0 -183
@@ -1,8 +1,7 @@
1
1
  import { PlaywrightTestConfig } from "@playwright/test";
2
2
 
3
- //#region playwright.shared.config.d.ts
4
- /** See https://playwright.dev/docs/test-configuration. */
3
+ //#region src/playwright.d.ts
5
4
  declare const baseConfig: (overrides?: PlaywrightTestConfig) => Promise<PlaywrightTestConfig<{}, {}>>;
6
5
  //#endregion
7
6
  export { baseConfig };
8
- //# sourceMappingURL=playwright.shared.config.d.mts.map
7
+ //# sourceMappingURL=playwright.d.mts.map
@@ -1,6 +1,5 @@
1
1
  import { defineConfig, devices } from "@playwright/test";
2
- //#region playwright.shared.config.ts
3
- /** See https://playwright.dev/docs/test-configuration. */
2
+ //#region src/playwright.ts
4
3
  const baseConfig = async (overrides) => {
5
4
  return defineConfig({
6
5
  testDir: "./e2e",
@@ -44,4 +43,4 @@ const baseConfig = async (overrides) => {
44
43
  //#endregion
45
44
  export { baseConfig };
46
45
 
47
- //# sourceMappingURL=playwright.shared.config.mjs.map
46
+ //# sourceMappingURL=playwright.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright.mjs","names":[],"sources":["../src/playwright.ts"],"sourcesContent":["import {\n\tdefineConfig,\n\tdevices,\n\ttype PlaywrightTestConfig,\n} from '@playwright/test'\n\nexport const baseConfig = async (overrides?: PlaywrightTestConfig) => {\n\treturn defineConfig(\n\t\t{\n\t\t\ttestDir: './e2e',\n\t\t\toutputDir: '.playwright/test-results',\n\t\t\tfullyParallel: true,\n\t\t\tworkers: process.env.CI ? 1 : '50%',\n\t\t\tforbidOnly: !!process.env.CI,\n\t\t\tretries: process.env.CI ? 3 : 0,\n\t\t\treporter: [\n\t\t\t\t['html', { open: 'never', outputFolder: '.playwright/report' }],\n\t\t\t],\n\t\t\tuse: {\n\t\t\t\tcolorScheme: 'dark',\n\t\t\t\tbaseURL: process.env.BASE_URL,\n\t\t\t\ttrace: 'retain-on-first-failure',\n\t\t\t\tscreenshot: 'on',\n\t\t\t\tvideo: 'retain-on-failure',\n\t\t\t},\n\t\t\ttimeout: 15_000,\n\t\t\texpect: { timeout: 5_000 },\n\t\t\tprojects: [\n\t\t\t\t{\n\t\t\t\t\tname: 'chromium',\n\t\t\t\t\tuse: {\n\t\t\t\t\t\t...devices['Desktop Chrome'],\n\t\t\t\t\t\tlaunchOptions: { args: ['--disable-lcd-text'] },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'mobile',\n\t\t\t\t\tuse: {\n\t\t\t\t\t\t...devices['Desktop Chrome'],\n\t\t\t\t\t\tviewport: { width: 320, height: 800 },\n\t\t\t\t\t\tlaunchOptions: { args: ['--disable-lcd-text'] },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\toverrides ?? {},\n\t)\n}\n"],"mappings":";;AAMA,MAAa,aAAa,OAAO,cAAqC;CACrE,OAAO,aACN;EACC,SAAS;EACT,WAAW;EACX,eAAe;EACf,SAAS,QAAQ,IAAI,KAAK,IAAI;EAC9B,YAAY,CAAC,CAAC,QAAQ,IAAI;EAC1B,SAAS,QAAQ,IAAI,KAAK,IAAI;EAC9B,UAAU,CACT,CAAC,QAAQ;GAAE,MAAM;GAAS,cAAc;GAAsB,CAAC,CAC/D;EACD,KAAK;GACJ,aAAa;GACb,SAAS,QAAQ,IAAI;GACrB,OAAO;GACP,YAAY;GACZ,OAAO;GACP;EACD,SAAS;EACT,QAAQ,EAAE,SAAS,KAAO;EAC1B,UAAU,CACT;GACC,MAAM;GACN,KAAK;IACJ,GAAG,QAAQ;IACX,eAAe,EAAE,MAAM,CAAC,qBAAqB,EAAE;IAC/C;GACD,EACD;GACC,MAAM;GACN,KAAK;IACJ,GAAG,QAAQ;IACX,UAAU;KAAE,OAAO;KAAK,QAAQ;KAAK;IACrC,eAAe,EAAE,MAAM,CAAC,qBAAqB,EAAE;IAC/C;GACD,CACD;EACD,EACD,aAAa,EAAE,CACf"}
@@ -1,3 +1,2 @@
1
- import "@testing-library/jest-dom/vitest";
2
1
  import "@test/styles";
3
2
  export {};
@@ -1,11 +1,16 @@
1
1
  import { SetupWorker } from "msw/browser";
2
- import { TestAPI, afterEach, beforeEach, describe, expect, vi } from "vitest";
2
+ import { ExpectPollOptions, TestAPI, afterEach, beforeEach, describe, expect as expect$1, vi } from "vite-plus/test";
3
+ import { Locator } from "vite-plus/test/browser";
3
4
 
4
- //#region test/browser.d.ts
5
+ //#region src/test/browser.d.ts
5
6
  interface MswBrowserFixture {
6
7
  worker: SetupWorker;
7
8
  _cleanup: void;
8
9
  }
10
+ type BrowserElementExpectation = {
11
+ element: <T extends HTMLElement | SVGElement | null | Locator>(element: T, options?: ExpectPollOptions) => any;
12
+ };
13
+ declare const expect: typeof expect$1 & BrowserElementExpectation;
9
14
  declare const test: TestAPI<MswBrowserFixture>;
10
15
  //#endregion
11
16
  export { MswBrowserFixture, afterEach, beforeEach, describe, expect, test, vi };
@@ -1,6 +1,6 @@
1
1
  import { setupWorker } from "msw/browser";
2
- import { afterEach, beforeEach, describe, expect, test as test$1, vi } from "vitest";
3
- //#region test/browser.ts
2
+ import { afterEach, beforeEach, describe, expect as expect$1, test as test$1, vi } from "vite-plus/test";
3
+ //#region src/test/browser.ts
4
4
  let workerSingleton;
5
5
  async function ensureWorker() {
6
6
  if (!workerSingleton) {
@@ -9,7 +9,7 @@ async function ensureWorker() {
9
9
  }
10
10
  return workerSingleton;
11
11
  }
12
- const test = test$1.extend({
12
+ const extended = test$1.extend({
13
13
  worker: [async ({}, use) => {
14
14
  const worker = await ensureWorker();
15
15
  await worker.start({
@@ -27,6 +27,8 @@ const test = test$1.extend({
27
27
  worker.resetHandlers();
28
28
  }, { auto: true }]
29
29
  });
30
+ const expect = expect$1;
31
+ const test = extended;
30
32
  //#endregion
31
33
  export { afterEach, beforeEach, describe, expect, test, vi };
32
34
 
@@ -1 +1 @@
1
- {"version":3,"file":"browser.mjs","names":["baseTest"],"sources":["../../test/browser.ts"],"sourcesContent":["// oxlint-disable typescript-eslint/triple-slash-reference\n/// <reference path=\"../virtual-modules.d.ts\" />\n// oxlint-disable no-empty-pattern\nimport { setupWorker, type SetupWorker } from 'msw/browser'\nimport { test as baseTest } from 'vitest'\nimport type { TestAPI } from 'vitest'\n\nexport interface MswBrowserFixture {\n\tworker: SetupWorker\n\t_cleanup: void\n}\n\nlet workerSingleton: SetupWorker | undefined\n\nasync function ensureWorker(): Promise<SetupWorker> {\n\tif (!workerSingleton) {\n\t\tconst { default: handlers } = await import('@test/handlers')\n\t\tworkerSingleton = setupWorker(...handlers)\n\t}\n\treturn workerSingleton\n}\n\nconst extended = baseTest.extend<MswBrowserFixture>({\n\tworker: [\n\t\tasync ({}, use) => {\n\t\t\tconst worker = await ensureWorker()\n\t\t\tawait worker.start({ quiet: true, onUnhandledRequest: 'bypass' })\n\t\t\tawait use(worker)\n\t\t\tworker.stop()\n\t\t},\n\t\t{ auto: true, scope: 'worker' },\n\t],\n\t_cleanup: [\n\t\tasync ({ worker }, use) => {\n\t\t\tawait use()\n\t\t\tworker.resetHandlers()\n\t\t},\n\t\t{ auto: true },\n\t],\n})\n\nexport { afterEach, beforeEach, describe, expect, vi } from 'vitest'\n\nexport const test = extended as TestAPI<MswBrowserFixture>\n"],"mappings":";;;AAYA,IAAI;AAEJ,eAAe,eAAqC;CACnD,IAAI,CAAC,iBAAiB;EACrB,MAAM,EAAE,SAAS,aAAa,MAAM,OAAO;EAC3C,kBAAkB,YAAY,GAAG,SAAS;;CAE3C,OAAO;;AAwBR,MAAa,OArBIA,OAAS,OAA0B;CACnD,QAAQ,CACP,OAAO,IAAI,QAAQ;EAClB,MAAM,SAAS,MAAM,cAAc;EACnC,MAAM,OAAO,MAAM;GAAE,OAAO;GAAM,oBAAoB;GAAU,CAAC;EACjE,MAAM,IAAI,OAAO;EACjB,OAAO,MAAM;IAEd;EAAE,MAAM;EAAM,OAAO;EAAU,CAC/B;CACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;EAC1B,MAAM,KAAK;EACX,OAAO,eAAe;IAEvB,EAAE,MAAM,MAAM,CACd;CACD,CAImB"}
1
+ {"version":3,"file":"browser.mjs","names":["baseTest","baseExpect"],"sources":["../../src/test/browser.ts"],"sourcesContent":["import { setupWorker, type SetupWorker } from 'msw/browser'\nimport { expect as baseExpect, test as baseTest } from 'vite-plus/test'\nimport type { ExpectPollOptions, TestAPI } from 'vite-plus/test'\nimport type { Locator } from 'vite-plus/test/browser'\n\nexport interface MswBrowserFixture {\n\tworker: SetupWorker\n\t_cleanup: void\n}\n\ntype BrowserElementExpectation = {\n\telement: <T extends HTMLElement | SVGElement | null | Locator>(\n\t\telement: T,\n\t\toptions?: ExpectPollOptions,\n\t) => any\n}\n\nlet workerSingleton: SetupWorker | undefined\n\nasync function ensureWorker(): Promise<SetupWorker> {\n\tif (!workerSingleton) {\n\t\tconst { default: handlers } = await import('@test/handlers')\n\t\tworkerSingleton = setupWorker(...handlers)\n\t}\n\treturn workerSingleton\n}\n\nconst extended = baseTest.extend<MswBrowserFixture>({\n\tworker: [\n\t\tasync ({}, use) => {\n\t\t\tconst worker = await ensureWorker()\n\t\t\tawait worker.start({ quiet: true, onUnhandledRequest: 'bypass' })\n\t\t\tawait use(worker)\n\t\t\tworker.stop()\n\t\t},\n\t\t{ auto: true, scope: 'worker' },\n\t],\n\t_cleanup: [\n\t\tasync ({ worker }, use) => {\n\t\t\tawait use()\n\t\t\tworker.resetHandlers()\n\t\t},\n\t\t{ auto: true },\n\t],\n})\n\nexport { afterEach, beforeEach, describe, vi } from 'vite-plus/test'\nexport const expect = baseExpect as typeof baseExpect &\n\tBrowserElementExpectation\nexport const test = extended as TestAPI<MswBrowserFixture>\n"],"mappings":";;;AAiBA,IAAI;AAEJ,eAAe,eAAqC;CACnD,IAAI,CAAC,iBAAiB;EACrB,MAAM,EAAE,SAAS,aAAa,MAAM,OAAO;EAC3C,kBAAkB,YAAY,GAAG,SAAS;;CAE3C,OAAO;;AAGR,MAAM,WAAWA,OAAS,OAA0B;CACnD,QAAQ,CACP,OAAO,IAAI,QAAQ;EAClB,MAAM,SAAS,MAAM,cAAc;EACnC,MAAM,OAAO,MAAM;GAAE,OAAO;GAAM,oBAAoB;GAAU,CAAC;EACjE,MAAM,IAAI,OAAO;EACjB,OAAO,MAAM;IAEd;EAAE,MAAM;EAAM,OAAO;EAAU,CAC/B;CACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;EAC1B,MAAM,KAAK;EACX,OAAO,eAAe;IAEvB,EAAE,MAAM,MAAM,CACd;CACD,CAAC;AAGF,MAAa,SAASC;AAEtB,MAAa,OAAO"}
@@ -1,16 +1,43 @@
1
- import { Database } from "./database.mjs";
2
- import { TestAPI, afterEach, beforeEach, describe, expect, vi } from "vitest";
1
+ import * as _$vite_plus_test0 from "vite-plus/test";
2
+ import { afterEach, beforeEach, describe, expect, vi } from "vite-plus/test";
3
3
  import { SetupServer } from "msw/node";
4
+ import { NodePgDatabase } from "drizzle-orm/node-postgres";
5
+ import { Pool } from "pg";
4
6
 
5
- //#region test/db.d.ts
7
+ //#region src/test/db.d.ts
8
+ interface DbConfig {
9
+ schemaPath?: string;
10
+ migrationsPath?: string;
11
+ postgresImage?: string;
12
+ }
13
+ type Database = NodePgDatabase & {
14
+ $client: Pool;
15
+ };
6
16
  interface DbFixture {
7
17
  server: SetupServer;
8
18
  _cleanup: void;
9
19
  db: Database;
10
- seedFunction: (db: Database) => Promise<void>;
20
+ seedFunction: (db: Database) => Promise<void> | void;
21
+ }
22
+ declare const test: _$vite_plus_test0.TestAPI<{
23
+ server: SetupServer;
24
+ _cleanup: void;
25
+ db: Database;
26
+ seedFunction: (db: Database) => Promise<void> | void;
27
+ }>;
28
+ declare function initDb(seed: (db: Database) => Promise<void> | void, config?: DbConfig): void;
29
+ interface SeedDatabaseOptions {
30
+ schemaPath: string;
31
+ migrationsFolder: string;
32
+ seedFunction?: (db: Database) => Promise<void> | void;
33
+ extensions?: string[];
11
34
  }
12
- declare const test: TestAPI<DbFixture>;
13
- declare function initDb(seedFunction: (db: Database) => Promise<void>): void;
35
+ declare function seedDatabase(db: Database, {
36
+ schemaPath,
37
+ migrationsFolder,
38
+ seedFunction,
39
+ extensions
40
+ }: SeedDatabaseOptions): Promise<void>;
14
41
  //#endregion
15
- export { DbFixture, afterEach, beforeEach, describe, expect, initDb, test, vi };
42
+ export { Database, DbConfig, DbFixture, SeedDatabaseOptions, afterEach, beforeEach, describe, expect, initDb, seedDatabase, test, vi };
16
43
  //# sourceMappingURL=db.d.mts.map
package/dist/test/db.mjs CHANGED
@@ -1,21 +1,22 @@
1
- import { seedDatabase } from "./database.mjs";
2
- import { t as findHandlerPath } from "../internal-Dshd0hdM.mjs";
3
1
  import { resolve } from "node:path";
4
- import { afterEach, beforeEach, describe, expect, test as test$1, vi } from "vitest";
2
+ import { afterEach, beforeEach, describe, expect, test as test$1, vi } from "vite-plus/test";
5
3
  import { setupServer } from "msw/node";
6
- //#region test/db.ts
4
+ //#region src/test/db.ts
7
5
  const DEFAULT_SCHEMA_PATH = "src/db/tables.ts";
8
6
  const DEFAULT_MIGRATIONS_PATH = "src/db/migrations";
9
7
  const DEFAULT_IMAGE = "postgres:17";
8
+ const DEFAULT_EXTENSIONS = ["pg_trgm"];
9
+ let dbConfig = {};
10
10
  let mswServer;
11
+ let seedFunction = async () => {};
11
12
  async function ensureMswServer() {
12
13
  if (!mswServer) {
13
- const { default: handlers } = await import(findHandlerPath());
14
+ const { default: handlers } = await import("@test/handlers");
14
15
  mswServer = setupServer(...handlers);
15
16
  }
16
17
  return mswServer;
17
18
  }
18
- let extended = test$1.extend({
19
+ const test = test$1.extend({
19
20
  server: [async ({}, use) => {
20
21
  const server = await ensureMswServer();
21
22
  server.listen({ onUnhandledRequest: "bypass" });
@@ -29,16 +30,17 @@ let extended = test$1.extend({
29
30
  await use();
30
31
  server.resetHandlers();
31
32
  }, { auto: true }],
32
- seedFunction: [async ({}, use) => use(async () => {}), { scope: "file" }],
33
+ seedFunction: [async ({}, use) => use(seedFunction), { scope: "file" }],
33
34
  db: [async ({ seedFunction }, use) => {
34
35
  const { PostgreSqlContainer } = await import("@testcontainers/postgresql");
35
36
  const { drizzle } = await import("drizzle-orm/node-postgres");
36
37
  const { Wait } = await import("testcontainers");
37
38
  const { Pool } = await import("pg");
38
- const schemaPath = resolve(process.cwd(), DEFAULT_SCHEMA_PATH);
39
- const migrationsFolder = resolve(process.cwd(), DEFAULT_MIGRATIONS_PATH);
40
- const container = await new PostgreSqlContainer(DEFAULT_IMAGE).withWaitStrategy(Wait.forHealthCheck()).start();
41
- const db = drizzle({ client: new Pool({ connectionString: container.getConnectionUri() }) });
39
+ const schemaPath = resolve(process.cwd(), dbConfig.schemaPath ?? DEFAULT_SCHEMA_PATH);
40
+ const migrationsFolder = resolve(process.cwd(), dbConfig.migrationsPath ?? DEFAULT_MIGRATIONS_PATH);
41
+ const container = await new PostgreSqlContainer(dbConfig.postgresImage ?? DEFAULT_IMAGE).withWaitStrategy(Wait.forHealthCheck()).start();
42
+ const client = new Pool({ connectionString: container.getConnectionUri() });
43
+ const db = Object.assign(drizzle({ client }), { $client: client });
42
44
  try {
43
45
  await seedDatabase(db, {
44
46
  schemaPath,
@@ -52,11 +54,23 @@ let extended = test$1.extend({
52
54
  }
53
55
  }, { scope: "file" }]
54
56
  });
55
- const test = extended;
56
- function initDb(seedFunction) {
57
- extended = extended.override({ seedFunction: [async ({}, use) => use(seedFunction), { scope: "file" }] });
57
+ function initDb(seed, config = {}) {
58
+ dbConfig = config;
59
+ seedFunction = seed;
60
+ }
61
+ async function seedDatabase(db, { schemaPath, migrationsFolder, seedFunction, extensions = DEFAULT_EXTENSIONS }) {
62
+ const { migrate } = await import("drizzle-orm/node-postgres/migrator");
63
+ const { reset } = await import("drizzle-seed");
64
+ const schema = await import(
65
+ /* @vite-ignore */
66
+ schemaPath
67
+ );
68
+ for (const ext of extensions) await db.execute(`CREATE EXTENSION IF NOT EXISTS "${ext}"`);
69
+ await migrate(db, { migrationsFolder });
70
+ await reset(db, schema);
71
+ if (seedFunction) await seedFunction(db);
58
72
  }
59
73
  //#endregion
60
- export { afterEach, beforeEach, describe, expect, initDb, test, vi };
74
+ export { afterEach, beforeEach, describe, expect, initDb, seedDatabase, test, vi };
61
75
 
62
76
  //# sourceMappingURL=db.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"db.mjs","names":["baseTest"],"sources":["../../test/db.ts"],"sourcesContent":["// oxlint-disable no-empty-pattern\nimport { setupServer, SetupServer } from 'msw/node'\nimport { resolve } from 'node:path'\nimport { test as baseTest } from 'vitest'\nimport type { TestAPI } from 'vitest'\nimport type { Database } from './database'\nimport { seedDatabase } from './database'\nimport { findHandlerPath } from './internal'\n\nconst DEFAULT_SCHEMA_PATH = 'src/db/tables.ts'\nconst DEFAULT_MIGRATIONS_PATH = 'src/db/migrations'\nconst DEFAULT_IMAGE = 'postgres:17'\n\nexport interface DbFixture {\n\tserver: SetupServer\n\t_cleanup: void\n\tdb: Database\n\tseedFunction: (db: Database) => Promise<void>\n}\n\nlet mswServer: SetupServer | undefined\n\nasync function ensureMswServer(): Promise<SetupServer> {\n\tif (!mswServer) {\n\t\tconst { default: handlers } = await import(findHandlerPath())\n\t\tmswServer = setupServer(...handlers)\n\t}\n\treturn mswServer\n}\n\nlet extended = baseTest.extend<DbFixture>({\n\tserver: [\n\t\tasync ({}, use) => {\n\t\t\tconst server = await ensureMswServer()\n\t\t\tserver.listen({ onUnhandledRequest: 'bypass' })\n\t\t\tawait use(server)\n\t\t\tserver.close()\n\t\t},\n\t\t{ auto: true, scope: 'worker' },\n\t],\n\t_cleanup: [\n\t\tasync ({ server }, use) => {\n\t\t\tawait use()\n\t\t\tserver.resetHandlers()\n\t\t},\n\t\t{ auto: true },\n\t],\n\tseedFunction: [async ({}, use) => use(async () => {}), { scope: 'file' }],\n\tdb: [\n\t\tasync ({ seedFunction }: Pick<DbFixture, 'seedFunction'>, use) => {\n\t\t\tconst { PostgreSqlContainer } = await import('@testcontainers/postgresql')\n\t\t\tconst { drizzle } = await import('drizzle-orm/node-postgres')\n\t\t\tconst { Wait } = await import('testcontainers')\n\t\t\tconst { Pool } = await import('pg')\n\n\t\t\tconst schemaPath = resolve(process.cwd(), DEFAULT_SCHEMA_PATH)\n\t\t\tconst migrationsFolder = resolve(process.cwd(), DEFAULT_MIGRATIONS_PATH)\n\n\t\t\tconst container = await new PostgreSqlContainer(DEFAULT_IMAGE)\n\t\t\t\t.withWaitStrategy(Wait.forHealthCheck())\n\t\t\t\t.start()\n\t\t\tconst db = drizzle({\n\t\t\t\tclient: new Pool({ connectionString: container.getConnectionUri() }),\n\t\t\t}) as Database\n\n\t\t\ttry {\n\t\t\t\tawait seedDatabase(db, { schemaPath, migrationsFolder, seedFunction })\n\t\t\t\tawait use(db)\n\t\t\t} finally {\n\t\t\t\tawait db.$client.end()\n\t\t\t\tawait container.stop()\n\t\t\t}\n\t\t},\n\t\t{ scope: 'file' },\n\t],\n})\n\nexport { afterEach, beforeEach, describe, expect, vi } from 'vitest'\n\nexport const test = extended as TestAPI<DbFixture>\n\nexport function initDb(seedFunction: (db: Database) => Promise<void>) {\n\textended = extended.override({\n\t\tseedFunction: [async ({}, use) => use(seedFunction), { scope: 'file' }],\n\t}) as typeof extended\n}\n"],"mappings":";;;;;;AASA,MAAM,sBAAsB;AAC5B,MAAM,0BAA0B;AAChC,MAAM,gBAAgB;AAStB,IAAI;AAEJ,eAAe,kBAAwC;CACtD,IAAI,CAAC,WAAW;EACf,MAAM,EAAE,SAAS,aAAa,MAAM,OAAO,iBAAiB;EAC5D,YAAY,YAAY,GAAG,SAAS;;CAErC,OAAO;;AAGR,IAAI,WAAWA,OAAS,OAAkB;CACzC,QAAQ,CACP,OAAO,IAAI,QAAQ;EAClB,MAAM,SAAS,MAAM,iBAAiB;EACtC,OAAO,OAAO,EAAE,oBAAoB,UAAU,CAAC;EAC/C,MAAM,IAAI,OAAO;EACjB,OAAO,OAAO;IAEf;EAAE,MAAM;EAAM,OAAO;EAAU,CAC/B;CACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;EAC1B,MAAM,KAAK;EACX,OAAO,eAAe;IAEvB,EAAE,MAAM,MAAM,CACd;CACD,cAAc,CAAC,OAAO,IAAI,QAAQ,IAAI,YAAY,GAAG,EAAE,EAAE,OAAO,QAAQ,CAAC;CACzE,IAAI,CACH,OAAO,EAAE,gBAAiD,QAAQ;EACjE,MAAM,EAAE,wBAAwB,MAAM,OAAO;EAC7C,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,MAAM,EAAE,SAAS,MAAM,OAAO;EAC9B,MAAM,EAAE,SAAS,MAAM,OAAO;EAE9B,MAAM,aAAa,QAAQ,QAAQ,KAAK,EAAE,oBAAoB;EAC9D,MAAM,mBAAmB,QAAQ,QAAQ,KAAK,EAAE,wBAAwB;EAExE,MAAM,YAAY,MAAM,IAAI,oBAAoB,cAAc,CAC5D,iBAAiB,KAAK,gBAAgB,CAAC,CACvC,OAAO;EACT,MAAM,KAAK,QAAQ,EAClB,QAAQ,IAAI,KAAK,EAAE,kBAAkB,UAAU,kBAAkB,EAAE,CAAC,EACpE,CAAC;EAEF,IAAI;GACH,MAAM,aAAa,IAAI;IAAE;IAAY;IAAkB;IAAc,CAAC;GACtE,MAAM,IAAI,GAAG;YACJ;GACT,MAAM,GAAG,QAAQ,KAAK;GACtB,MAAM,UAAU,MAAM;;IAGxB,EAAE,OAAO,QAAQ,CACjB;CACD,CAAC;AAIF,MAAa,OAAO;AAEpB,SAAgB,OAAO,cAA+C;CACrE,WAAW,SAAS,SAAS,EAC5B,cAAc,CAAC,OAAO,IAAI,QAAQ,IAAI,aAAa,EAAE,EAAE,OAAO,QAAQ,CAAC,EACvE,CAAC"}
1
+ {"version":3,"file":"db.mjs","names":["baseTest"],"sources":["../../src/test/db.ts"],"sourcesContent":["import { setupServer, type SetupServer } from 'msw/node'\nimport { resolve } from 'node:path'\nimport { test as baseTest } from 'vite-plus/test'\nimport type { NodePgDatabase } from 'drizzle-orm/node-postgres'\nimport type { Pool } from 'pg'\n\nconst DEFAULT_SCHEMA_PATH = 'src/db/tables.ts'\nconst DEFAULT_MIGRATIONS_PATH = 'src/db/migrations'\nconst DEFAULT_IMAGE = 'postgres:17'\nconst DEFAULT_EXTENSIONS = ['pg_trgm']\n\nexport interface DbConfig {\n\tschemaPath?: string\n\tmigrationsPath?: string\n\tpostgresImage?: string\n}\n\nexport type Database = NodePgDatabase & {\n\t$client: Pool\n}\n\nexport interface DbFixture {\n\tserver: SetupServer\n\t_cleanup: void\n\tdb: Database\n\tseedFunction: (db: Database) => Promise<void> | void\n}\n\nlet dbConfig: DbConfig = {}\nlet mswServer: SetupServer | undefined\nlet seedFunction: (db: Database) => Promise<void> | void = async () => {}\n\nasync function ensureMswServer(): Promise<SetupServer> {\n\tif (!mswServer) {\n\t\tconst { default: handlers } = await import('@test/handlers')\n\t\tmswServer = setupServer(...handlers)\n\t}\n\treturn mswServer\n}\n\nexport const test = baseTest.extend<DbFixture>({\n\tserver: [\n\t\tasync ({}, use) => {\n\t\t\tconst server = await ensureMswServer()\n\t\t\tserver.listen({ onUnhandledRequest: 'bypass' })\n\t\t\tawait use(server)\n\t\t\tserver.close()\n\t\t},\n\t\t{ auto: true, scope: 'worker' },\n\t],\n\t_cleanup: [\n\t\tasync ({ server }, use) => {\n\t\t\tawait use()\n\t\t\tserver.resetHandlers()\n\t\t},\n\t\t{ auto: true },\n\t],\n\tseedFunction: [async ({}, use) => use(seedFunction), { scope: 'file' }],\n\tdb: [\n\t\tasync ({ seedFunction }, use) => {\n\t\t\tconst { PostgreSqlContainer } = await import('@testcontainers/postgresql')\n\t\t\tconst { drizzle } = await import('drizzle-orm/node-postgres')\n\t\t\tconst { Wait } = await import('testcontainers')\n\t\t\tconst { Pool } = await import('pg')\n\t\t\tconst schemaPath = resolve(\n\t\t\t\tprocess.cwd(),\n\t\t\t\tdbConfig.schemaPath ?? DEFAULT_SCHEMA_PATH,\n\t\t\t)\n\t\t\tconst migrationsFolder = resolve(\n\t\t\t\tprocess.cwd(),\n\t\t\t\tdbConfig.migrationsPath ?? DEFAULT_MIGRATIONS_PATH,\n\t\t\t)\n\t\t\tconst container = await new PostgreSqlContainer(\n\t\t\t\tdbConfig.postgresImage ?? DEFAULT_IMAGE,\n\t\t\t)\n\t\t\t\t.withWaitStrategy(Wait.forHealthCheck())\n\t\t\t\t.start()\n\t\t\tconst client = new Pool({\n\t\t\t\tconnectionString: container.getConnectionUri(),\n\t\t\t})\n\t\t\tconst db = Object.assign(drizzle({ client }), { $client: client })\n\n\t\t\ttry {\n\t\t\t\tawait seedDatabase(db, { schemaPath, migrationsFolder, seedFunction })\n\t\t\t\tawait use(db)\n\t\t\t} finally {\n\t\t\t\tawait db.$client.end()\n\t\t\t\tawait container.stop()\n\t\t\t}\n\t\t},\n\t\t{ scope: 'file' },\n\t],\n})\n\nexport { afterEach, beforeEach, describe, expect, vi } from 'vite-plus/test'\n\nexport function initDb(\n\tseed: (db: Database) => Promise<void> | void,\n\tconfig: DbConfig = {},\n) {\n\tdbConfig = config\n\tseedFunction = seed\n}\n\nexport interface SeedDatabaseOptions {\n\tschemaPath: string\n\tmigrationsFolder: string\n\tseedFunction?: (db: Database) => Promise<void> | void\n\textensions?: string[]\n}\n\nexport async function seedDatabase(\n\tdb: Database,\n\t{\n\t\tschemaPath,\n\t\tmigrationsFolder,\n\t\tseedFunction,\n\t\textensions = DEFAULT_EXTENSIONS,\n\t}: SeedDatabaseOptions,\n) {\n\tconst { migrate } = await import('drizzle-orm/node-postgres/migrator')\n\tconst { reset } = await import('drizzle-seed')\n\tconst schema = await import(/* @vite-ignore */ schemaPath)\n\n\tfor (const ext of extensions) {\n\t\tawait db.execute(`CREATE EXTENSION IF NOT EXISTS \"${ext}\"`)\n\t}\n\tawait migrate(db, { migrationsFolder })\n\tawait reset(db, schema)\n\tif (seedFunction) await seedFunction(db)\n}\n"],"mappings":";;;;AAMA,MAAM,sBAAsB;AAC5B,MAAM,0BAA0B;AAChC,MAAM,gBAAgB;AACtB,MAAM,qBAAqB,CAAC,UAAU;AAmBtC,IAAI,WAAqB,EAAE;AAC3B,IAAI;AACJ,IAAI,eAAuD,YAAY;AAEvE,eAAe,kBAAwC;CACtD,IAAI,CAAC,WAAW;EACf,MAAM,EAAE,SAAS,aAAa,MAAM,OAAO;EAC3C,YAAY,YAAY,GAAG,SAAS;;CAErC,OAAO;;AAGR,MAAa,OAAOA,OAAS,OAAkB;CAC9C,QAAQ,CACP,OAAO,IAAI,QAAQ;EAClB,MAAM,SAAS,MAAM,iBAAiB;EACtC,OAAO,OAAO,EAAE,oBAAoB,UAAU,CAAC;EAC/C,MAAM,IAAI,OAAO;EACjB,OAAO,OAAO;IAEf;EAAE,MAAM;EAAM,OAAO;EAAU,CAC/B;CACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;EAC1B,MAAM,KAAK;EACX,OAAO,eAAe;IAEvB,EAAE,MAAM,MAAM,CACd;CACD,cAAc,CAAC,OAAO,IAAI,QAAQ,IAAI,aAAa,EAAE,EAAE,OAAO,QAAQ,CAAC;CACvE,IAAI,CACH,OAAO,EAAE,gBAAgB,QAAQ;EAChC,MAAM,EAAE,wBAAwB,MAAM,OAAO;EAC7C,MAAM,EAAE,YAAY,MAAM,OAAO;EACjC,MAAM,EAAE,SAAS,MAAM,OAAO;EAC9B,MAAM,EAAE,SAAS,MAAM,OAAO;EAC9B,MAAM,aAAa,QAClB,QAAQ,KAAK,EACb,SAAS,cAAc,oBACvB;EACD,MAAM,mBAAmB,QACxB,QAAQ,KAAK,EACb,SAAS,kBAAkB,wBAC3B;EACD,MAAM,YAAY,MAAM,IAAI,oBAC3B,SAAS,iBAAiB,cAC1B,CACC,iBAAiB,KAAK,gBAAgB,CAAC,CACvC,OAAO;EACT,MAAM,SAAS,IAAI,KAAK,EACvB,kBAAkB,UAAU,kBAAkB,EAC9C,CAAC;EACF,MAAM,KAAK,OAAO,OAAO,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,QAAQ,CAAC;EAElE,IAAI;GACH,MAAM,aAAa,IAAI;IAAE;IAAY;IAAkB;IAAc,CAAC;GACtE,MAAM,IAAI,GAAG;YACJ;GACT,MAAM,GAAG,QAAQ,KAAK;GACtB,MAAM,UAAU,MAAM;;IAGxB,EAAE,OAAO,QAAQ,CACjB;CACD,CAAC;AAIF,SAAgB,OACf,MACA,SAAmB,EAAE,EACpB;CACD,WAAW;CACX,eAAe;;AAUhB,eAAsB,aACrB,IACA,EACC,YACA,kBACA,cACA,aAAa,sBAEb;CACD,MAAM,EAAE,YAAY,MAAM,OAAO;CACjC,MAAM,EAAE,UAAU,MAAM,OAAO;CAC/B,MAAM,SAAS,MAAM;;EAA0B;;CAE/C,KAAK,MAAM,OAAO,YACjB,MAAM,GAAG,QAAQ,mCAAmC,IAAI,GAAG;CAE5D,MAAM,QAAQ,IAAI,EAAE,kBAAkB,CAAC;CACvC,MAAM,MAAM,IAAI,OAAO;CACvB,IAAI,cAAc,MAAM,aAAa,GAAG"}
@@ -1,12 +1,16 @@
1
- import { TestAPI, afterEach, beforeEach, describe, expect, vi } from "vitest";
1
+ import * as _$vite_plus_test0 from "vite-plus/test";
2
+ import { afterEach, beforeEach, describe, expect, vi } from "vite-plus/test";
2
3
  import { SetupServer } from "msw/node";
3
4
 
4
- //#region test/server.d.ts
5
+ //#region src/test/server.d.ts
5
6
  interface MswServerFixture {
6
7
  server: SetupServer;
7
8
  _cleanup: void;
8
9
  }
9
- declare const test: TestAPI<MswServerFixture>;
10
+ declare const test: _$vite_plus_test0.TestAPI<{
11
+ server: SetupServer;
12
+ _cleanup: void;
13
+ }>;
10
14
  //#endregion
11
15
  export { MswServerFixture, afterEach, beforeEach, describe, expect, test, vi };
12
16
  //# sourceMappingURL=server.d.mts.map
@@ -1,11 +1,10 @@
1
- import { t as findHandlerPath } from "../internal-Dshd0hdM.mjs";
2
- import { afterEach, beforeEach, describe, expect, test as test$1, vi } from "vitest";
1
+ import { afterEach, beforeEach, describe, expect, test as test$1, vi } from "vite-plus/test";
3
2
  import { setupServer } from "msw/node";
4
- //#region test/server.ts
3
+ //#region src/test/server.ts
5
4
  let mswServer;
6
5
  async function ensureMswServer() {
7
6
  if (!mswServer) {
8
- const { default: handlers } = await import(findHandlerPath());
7
+ const { default: handlers } = await import("@test/handlers");
9
8
  mswServer = setupServer(...handlers);
10
9
  }
11
10
  return mswServer;
@@ -1 +1 @@
1
- {"version":3,"file":"server.mjs","names":["baseTest"],"sources":["../../test/server.ts"],"sourcesContent":["// oxlint-disable no-empty-pattern\nimport { setupServer, type SetupServer } from 'msw/node'\nimport { test as baseTest } from 'vitest'\nimport type { TestAPI } from 'vitest'\nimport { findHandlerPath } from './internal'\n\nexport interface MswServerFixture {\n\tserver: SetupServer\n\t_cleanup: void\n}\n\nlet mswServer: SetupServer | undefined\n\nasync function ensureMswServer(): Promise<SetupServer> {\n\tif (!mswServer) {\n\t\tconst { default: handlers } = await import(findHandlerPath())\n\t\tmswServer = setupServer(...handlers)\n\t}\n\treturn mswServer\n}\n\nconst extended = baseTest.extend<MswServerFixture>({\n\tserver: [\n\t\tasync ({}, use) => {\n\t\t\tconst server = await ensureMswServer()\n\t\t\tserver.listen({ onUnhandledRequest: 'bypass' })\n\t\t\tawait use(server)\n\t\t\tserver.close()\n\t\t},\n\t\t{ auto: true, scope: 'worker' },\n\t],\n\t_cleanup: [\n\t\tasync ({ server }, use) => {\n\t\t\tawait use()\n\t\t\tserver.resetHandlers()\n\t\t},\n\t\t{ auto: true },\n\t],\n})\n\nexport { afterEach, beforeEach, describe, expect, vi } from 'vitest'\n\nexport const test = extended as TestAPI<MswServerFixture>\n"],"mappings":";;;;AAWA,IAAI;AAEJ,eAAe,kBAAwC;CACtD,IAAI,CAAC,WAAW;EACf,MAAM,EAAE,SAAS,aAAa,MAAM,OAAO,iBAAiB;EAC5D,YAAY,YAAY,GAAG,SAAS;;CAErC,OAAO;;AAwBR,MAAa,OArBIA,OAAS,OAAyB;CAClD,QAAQ,CACP,OAAO,IAAI,QAAQ;EAClB,MAAM,SAAS,MAAM,iBAAiB;EACtC,OAAO,OAAO,EAAE,oBAAoB,UAAU,CAAC;EAC/C,MAAM,IAAI,OAAO;EACjB,OAAO,OAAO;IAEf;EAAE,MAAM;EAAM,OAAO;EAAU,CAC/B;CACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;EAC1B,MAAM,KAAK;EACX,OAAO,eAAe;IAEvB,EAAE,MAAM,MAAM,CACd;CACD,CAImB"}
1
+ {"version":3,"file":"server.mjs","names":["baseTest"],"sources":["../../src/test/server.ts"],"sourcesContent":["import { setupServer, type SetupServer } from 'msw/node'\nimport { test as baseTest } from 'vite-plus/test'\n\nexport interface MswServerFixture {\n\tserver: SetupServer\n\t_cleanup: void\n}\n\nlet mswServer: SetupServer | undefined\n\nasync function ensureMswServer(): Promise<SetupServer> {\n\tif (!mswServer) {\n\t\tconst { default: handlers } = await import('@test/handlers')\n\t\tmswServer = setupServer(...handlers)\n\t}\n\treturn mswServer\n}\n\nconst extended = baseTest.extend<MswServerFixture>({\n\tserver: [\n\t\tasync ({}, use) => {\n\t\t\tconst server = await ensureMswServer()\n\t\t\tserver.listen({ onUnhandledRequest: 'bypass' })\n\t\t\tawait use(server)\n\t\t\tserver.close()\n\t\t},\n\t\t{ auto: true, scope: 'worker' },\n\t],\n\t_cleanup: [\n\t\tasync ({ server }, use) => {\n\t\t\tawait use()\n\t\t\tserver.resetHandlers()\n\t\t},\n\t\t{ auto: true },\n\t],\n})\n\nexport { afterEach, beforeEach, describe, expect, vi } from 'vite-plus/test'\nexport const test = extended\n"],"mappings":";;;AAQA,IAAI;AAEJ,eAAe,kBAAwC;CACtD,IAAI,CAAC,WAAW;EACf,MAAM,EAAE,SAAS,aAAa,MAAM,OAAO;EAC3C,YAAY,YAAY,GAAG,SAAS;;CAErC,OAAO;;AAuBR,MAAa,OApBIA,OAAS,OAAyB;CAClD,QAAQ,CACP,OAAO,IAAI,QAAQ;EAClB,MAAM,SAAS,MAAM,iBAAiB;EACtC,OAAO,OAAO,EAAE,oBAAoB,UAAU,CAAC;EAC/C,MAAM,IAAI,OAAO;EACjB,OAAO,OAAO;IAEf;EAAE,MAAM;EAAM,OAAO;EAAU,CAC/B;CACD,UAAU,CACT,OAAO,EAAE,UAAU,QAAQ;EAC1B,MAAM,KAAK;EACX,OAAO,eAAe;IAEvB,EAAE,MAAM,MAAM,CACd;CACD,CAGmB"}
@@ -1,36 +1,30 @@
1
- import { ComponentType, ReactNode } from "react";
2
- import { Locator } from "vitest/browser";
3
- import { RenderResult } from "vitest-browser-react";
1
+ import { ComponentType } from "react";
2
+ import { render } from "vitest-browser-react";
4
3
 
5
- //#region test/visual-page.d.ts
6
- interface Viewport {
7
- width: number;
8
- height: number;
9
- }
10
- interface ExpectComponentScreenshotOptions {
4
+ //#region src/test/visual-page.d.ts
5
+ type ScreenshotOptions = {
11
6
  component: ComponentType;
12
7
  name: string;
13
- waitFor: (screen: RenderResult) => Locator;
14
- prepare?: ((screen: RenderResult) => void | Promise<void>) | undefined;
15
- target?: ((screen: RenderResult) => Locator) | undefined;
16
- setup?: (() => void | Promise<void>) | undefined;
17
- wrapper?: ComponentType<{
18
- children: ReactNode;
19
- }> | undefined;
20
- viewport?: Viewport | undefined;
21
- fullPage?: boolean | undefined;
22
- }
8
+ waitFor: (screen: Awaited<ReturnType<typeof render>>) => HTMLElement | SVGElement | null;
9
+ prepare?: (screen: Awaited<ReturnType<typeof render>>) => void | Promise<void>;
10
+ setup?: () => void | Promise<void>;
11
+ target?: (screen: Awaited<ReturnType<typeof render>>) => HTMLElement;
12
+ fullPage?: boolean;
13
+ viewport?: {
14
+ width: number;
15
+ height: number;
16
+ };
17
+ };
23
18
  declare function expectComponentScreenshot({
24
19
  component,
25
20
  name,
26
21
  waitFor,
27
22
  prepare,
28
- target,
29
23
  setup,
30
- wrapper,
31
- viewport,
32
- fullPage
33
- }: ExpectComponentScreenshotOptions): Promise<void>;
24
+ target,
25
+ fullPage,
26
+ viewport
27
+ }: ScreenshotOptions): Promise<void>;
34
28
  //#endregion
35
29
  export { expectComponentScreenshot };
36
30
  //# sourceMappingURL=visual-page.d.mts.map
@@ -1,28 +1,34 @@
1
- import { expect } from "vitest";
1
+ import { expect } from "./browser.mjs";
2
2
  import { createElement } from "react";
3
- import { page } from "vitest/browser";
3
+ import { page } from "vite-plus/test/browser";
4
4
  import { render } from "vitest-browser-react";
5
- //#region test/visual-page.ts
6
- async function expectComponentScreenshot({ component, name, waitFor, prepare, target = (screen) => screen.locator, setup, wrapper, viewport = {
5
+ //#region src/test/visual-page.tsx
6
+ async function waitForImages() {
7
+ await Promise.all(Array.from(document.images, (image) => {
8
+ if (image.complete) return Promise.resolve();
9
+ return image.decode().catch(() => void 0);
10
+ }));
11
+ }
12
+ async function expectComponentScreenshot({ component, name, waitFor, prepare, setup, target = (screen) => screen.container, fullPage = true, viewport = {
7
13
  width: 1280,
8
14
  height: 720
9
- }, fullPage = true }) {
15
+ } }) {
10
16
  localStorage.clear();
11
17
  document.body.replaceChildren();
12
18
  await setup?.();
13
19
  await page.viewport(viewport.width, viewport.height);
20
+ document.documentElement.style.setProperty("--visual-viewport-height", `${viewport.height}px`);
14
21
  const container = document.body.appendChild(document.createElement("div"));
15
22
  container.style.width = "100vw";
16
23
  container.style.minHeight = "100vh";
17
- const screen = await render(createElement(component), wrapper ? {
18
- container,
19
- wrapper
20
- } : { container });
24
+ const screen = await render(createElement(component), { container });
21
25
  await prepare?.(screen);
22
26
  await expect.element(waitFor(screen)).toBeVisible();
23
27
  await document.fonts.ready;
28
+ await waitForImages();
24
29
  if (fullPage) await page.viewport(viewport.width, Math.ceil(container.scrollHeight));
25
- await expect.element(target(screen)).toMatchScreenshot(`${name}.png`, { screenshotOptions: { scale: "css" } });
30
+ const screenshotTarget = fullPage ? () => container : target;
31
+ await expect.element(screenshotTarget(screen)).toMatchScreenshot(`${name}.png`, { screenshotOptions: { scale: "css" } });
26
32
  }
27
33
  //#endregion
28
34
  export { expectComponentScreenshot };
@@ -1 +1 @@
1
- {"version":3,"file":"visual-page.mjs","names":[],"sources":["../../test/visual-page.ts"],"sourcesContent":["import { createElement, type ComponentType, type ReactNode } from 'react'\nimport { expect } from 'vitest'\nimport { page, type Locator } from 'vitest/browser'\nimport { render, type RenderResult } from 'vitest-browser-react'\n\ninterface Viewport {\n\twidth: number\n\theight: number\n}\n\ninterface ExpectComponentScreenshotOptions {\n\tcomponent: ComponentType\n\tname: string\n\twaitFor: (screen: RenderResult) => Locator\n\tprepare?: ((screen: RenderResult) => void | Promise<void>) | undefined\n\ttarget?: ((screen: RenderResult) => Locator) | undefined\n\tsetup?: (() => void | Promise<void>) | undefined\n\twrapper?: ComponentType<{ children: ReactNode }> | undefined\n\tviewport?: Viewport | undefined\n\tfullPage?: boolean | undefined\n}\n\nexport async function expectComponentScreenshot({\n\tcomponent,\n\tname,\n\twaitFor,\n\tprepare,\n\ttarget = (screen) => screen.locator,\n\tsetup,\n\twrapper,\n\tviewport = { width: 1280, height: 720 },\n\tfullPage = true,\n}: ExpectComponentScreenshotOptions) {\n\tlocalStorage.clear()\n\tdocument.body.replaceChildren()\n\tawait setup?.()\n\tawait page.viewport(viewport.width, viewport.height)\n\n\tconst container = document.body.appendChild(document.createElement('div'))\n\tcontainer.style.width = '100vw'\n\tcontainer.style.minHeight = '100vh'\n\n\tconst screen = await render(\n\t\tcreateElement(component),\n\t\twrapper ? { container, wrapper } : { container },\n\t)\n\n\tawait prepare?.(screen)\n\tawait expect.element(waitFor(screen)).toBeVisible()\n\tawait document.fonts.ready\n\tif (fullPage) {\n\t\tawait page.viewport(viewport.width, Math.ceil(container.scrollHeight))\n\t}\n\tawait expect.element(target(screen)).toMatchScreenshot(`${name}.png`, {\n\t\tscreenshotOptions: { scale: 'css' },\n\t})\n}\n"],"mappings":";;;;;AAsBA,eAAsB,0BAA0B,EAC/C,WACA,MACA,SACA,SACA,UAAU,WAAW,OAAO,SAC5B,OACA,SACA,WAAW;CAAE,OAAO;CAAM,QAAQ;CAAK,EACvC,WAAW,QACyB;CACpC,aAAa,OAAO;CACpB,SAAS,KAAK,iBAAiB;CAC/B,MAAM,SAAS;CACf,MAAM,KAAK,SAAS,SAAS,OAAO,SAAS,OAAO;CAEpD,MAAM,YAAY,SAAS,KAAK,YAAY,SAAS,cAAc,MAAM,CAAC;CAC1E,UAAU,MAAM,QAAQ;CACxB,UAAU,MAAM,YAAY;CAE5B,MAAM,SAAS,MAAM,OACpB,cAAc,UAAU,EACxB,UAAU;EAAE;EAAW;EAAS,GAAG,EAAE,WAAW,CAChD;CAED,MAAM,UAAU,OAAO;CACvB,MAAM,OAAO,QAAQ,QAAQ,OAAO,CAAC,CAAC,aAAa;CACnD,MAAM,SAAS,MAAM;CACrB,IAAI,UACH,MAAM,KAAK,SAAS,SAAS,OAAO,KAAK,KAAK,UAAU,aAAa,CAAC;CAEvE,MAAM,OAAO,QAAQ,OAAO,OAAO,CAAC,CAAC,kBAAkB,GAAG,KAAK,OAAO,EACrE,mBAAmB,EAAE,OAAO,OAAO,EACnC,CAAC"}
1
+ {"version":3,"file":"visual-page.mjs","names":[],"sources":["../../src/test/visual-page.tsx"],"sourcesContent":["import { createElement, type ComponentType } from 'react'\nimport { page } from 'vite-plus/test/browser'\nimport { render } from 'vitest-browser-react'\n\nimport { expect } from './browser'\n\nasync function waitForImages() {\n\tawait Promise.all(\n\t\tArray.from(document.images, (image) => {\n\t\t\tif (image.complete) return Promise.resolve()\n\t\t\treturn image.decode().catch(() => undefined)\n\t\t}),\n\t)\n}\n\ntype ScreenshotOptions = {\n\tcomponent: ComponentType\n\tname: string\n\twaitFor: (\n\t\tscreen: Awaited<ReturnType<typeof render>>,\n\t) => HTMLElement | SVGElement | null\n\tprepare?: (screen: Awaited<ReturnType<typeof render>>) => void | Promise<void>\n\tsetup?: () => void | Promise<void>\n\ttarget?: (screen: Awaited<ReturnType<typeof render>>) => HTMLElement\n\tfullPage?: boolean\n\tviewport?: { width: number; height: number }\n}\n\nexport async function expectComponentScreenshot({\n\tcomponent,\n\tname,\n\twaitFor,\n\tprepare,\n\tsetup,\n\ttarget = (screen) => screen.container,\n\tfullPage = true,\n\tviewport = { width: 1280, height: 720 },\n}: ScreenshotOptions) {\n\tlocalStorage.clear()\n\tdocument.body.replaceChildren()\n\tawait setup?.()\n\tawait page.viewport(viewport.width, viewport.height)\n\tdocument.documentElement.style.setProperty(\n\t\t'--visual-viewport-height',\n\t\t`${viewport.height}px`,\n\t)\n\n\tconst container = document.body.appendChild(document.createElement('div'))\n\tcontainer.style.width = '100vw'\n\tcontainer.style.minHeight = '100vh'\n\n\tconst screen = await render(createElement(component), { container })\n\tawait prepare?.(screen)\n\tawait expect.element(waitFor(screen)).toBeVisible()\n\tawait document.fonts.ready\n\tawait waitForImages()\n\n\tif (fullPage) {\n\t\tawait page.viewport(viewport.width, Math.ceil(container.scrollHeight))\n\t}\n\n\tconst screenshotTarget = fullPage ? () => container : target\n\n\tawait expect\n\t\t.element(screenshotTarget(screen))\n\t\t.toMatchScreenshot(`${name}.png`, {\n\t\t\tscreenshotOptions: { scale: 'css' },\n\t\t})\n}\n"],"mappings":";;;;;AAMA,eAAe,gBAAgB;CAC9B,MAAM,QAAQ,IACb,MAAM,KAAK,SAAS,SAAS,UAAU;EACtC,IAAI,MAAM,UAAU,OAAO,QAAQ,SAAS;EAC5C,OAAO,MAAM,QAAQ,CAAC,YAAY,KAAA,EAAU;GAC3C,CACF;;AAgBF,eAAsB,0BAA0B,EAC/C,WACA,MACA,SACA,SACA,OACA,UAAU,WAAW,OAAO,WAC5B,WAAW,MACX,WAAW;CAAE,OAAO;CAAM,QAAQ;CAAK,IAClB;CACrB,aAAa,OAAO;CACpB,SAAS,KAAK,iBAAiB;CAC/B,MAAM,SAAS;CACf,MAAM,KAAK,SAAS,SAAS,OAAO,SAAS,OAAO;CACpD,SAAS,gBAAgB,MAAM,YAC9B,4BACA,GAAG,SAAS,OAAO,IACnB;CAED,MAAM,YAAY,SAAS,KAAK,YAAY,SAAS,cAAc,MAAM,CAAC;CAC1E,UAAU,MAAM,QAAQ;CACxB,UAAU,MAAM,YAAY;CAE5B,MAAM,SAAS,MAAM,OAAO,cAAc,UAAU,EAAE,EAAE,WAAW,CAAC;CACpE,MAAM,UAAU,OAAO;CACvB,MAAM,OAAO,QAAQ,QAAQ,OAAO,CAAC,CAAC,aAAa;CACnD,MAAM,SAAS,MAAM;CACrB,MAAM,eAAe;CAErB,IAAI,UACH,MAAM,KAAK,SAAS,SAAS,OAAO,KAAK,KAAK,UAAU,aAAa,CAAC;CAGvE,MAAM,mBAAmB,iBAAiB,YAAY;CAEtD,MAAM,OACJ,QAAQ,iBAAiB,OAAO,CAAC,CACjC,kBAAkB,GAAG,KAAK,OAAO,EACjC,mBAAmB,EAAE,OAAO,OAAO,EACnC,CAAC"}
@@ -0,0 +1,81 @@
1
+ import { TestProjectConfiguration } from "vite-plus";
2
+
3
+ //#region src/workspace.d.ts
4
+ declare const workspaceConfig: {
5
+ fmt: {
6
+ singleQuote: boolean;
7
+ semi: boolean;
8
+ useTabs: boolean;
9
+ experimentalTailwindcss: {};
10
+ printWidth: number;
11
+ experimentalSortPackageJson: boolean;
12
+ proseWrap: string;
13
+ ignorePatterns: string[];
14
+ overrides: {
15
+ files: string[];
16
+ options: {
17
+ useTabs: boolean;
18
+ };
19
+ }[];
20
+ };
21
+ lint: {
22
+ plugins: string[];
23
+ categories: {};
24
+ options: {
25
+ typeAware: boolean;
26
+ typeCheck: boolean;
27
+ };
28
+ rules: {
29
+ 'no-empty-pattern': string;
30
+ 'no-console': (string | {
31
+ allow: string[];
32
+ })[];
33
+ };
34
+ settings: {
35
+ 'jsx-a11y': {
36
+ components: {};
37
+ attributes: {};
38
+ };
39
+ react: {
40
+ formComponents: any[];
41
+ linkComponents: any[];
42
+ };
43
+ jsdoc: {
44
+ ignorePrivate: boolean;
45
+ ignoreInternal: boolean;
46
+ ignoreReplacesDocs: boolean;
47
+ overrideReplacesDocs: boolean;
48
+ augmentsExtendsReplacesDocs: boolean;
49
+ implementsReplacesDocs: boolean;
50
+ exemptDestructuredRootsFromChecks: boolean;
51
+ tagNamePreference: {};
52
+ };
53
+ };
54
+ env: {
55
+ builtin: boolean;
56
+ };
57
+ globals: {};
58
+ ignorePatterns: string[];
59
+ };
60
+ staged: {
61
+ '*.{js,ts,tsx}': string;
62
+ };
63
+ };
64
+ //#endregion
65
+ //#region src/vite.d.ts
66
+ interface ProjectOverrides {
67
+ server?: TestProjectConfiguration;
68
+ browser?: TestProjectConfiguration;
69
+ }
70
+ interface AppConfigOptions {
71
+ root?: string;
72
+ projectOverrides?: ProjectOverrides;
73
+ }
74
+ declare const createAppConfig: ({
75
+ root,
76
+ projectOverrides
77
+ }?: AppConfigOptions) => Record<string, unknown>;
78
+ declare const viteConfig: typeof createAppConfig;
79
+ //#endregion
80
+ export { AppConfigOptions, createAppConfig, viteConfig, workspaceConfig };
81
+ //# sourceMappingURL=vite.d.mts.map