@forgebook/testing 0.0.0-stage → 0.1.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.
Files changed (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -2
  3. package/dist/bin/forgebook-heights/forgebook-heights.d.mts +3 -0
  4. package/dist/bin/forgebook-heights/forgebook-heights.d.mts.map +1 -0
  5. package/dist/bin/forgebook-heights/forgebook-heights.mjs +124 -0
  6. package/dist/bin/forgebook-heights/forgebook-heights.mjs.map +1 -0
  7. package/dist/bin/forgebook-heights/measureHeights.d.ts +84 -0
  8. package/dist/bin/forgebook-heights/measureHeights.d.ts.map +1 -0
  9. package/dist/bin/forgebook-heights/measureHeights.js +180 -0
  10. package/dist/bin/forgebook-heights/measureHeights.js.map +1 -0
  11. package/dist/bin/forgebook-heights/measureHeights.types.d.ts +27 -0
  12. package/dist/bin/forgebook-heights/measureHeights.types.d.ts.map +1 -0
  13. package/dist/bin/forgebook-heights/measureHeights.types.js +7 -0
  14. package/dist/bin/forgebook-heights/measureHeights.types.js.map +1 -0
  15. package/dist/bin/forgebook-shot/forgebook-shot.d.mts +3 -0
  16. package/dist/bin/forgebook-shot/forgebook-shot.d.mts.map +1 -0
  17. package/dist/bin/forgebook-shot/forgebook-shot.mjs +110 -0
  18. package/dist/bin/forgebook-shot/forgebook-shot.mjs.map +1 -0
  19. package/dist/bin/forgebook-shot/storyShot.d.ts +34 -0
  20. package/dist/bin/forgebook-shot/storyShot.d.ts.map +1 -0
  21. package/dist/bin/forgebook-shot/storyShot.js +83 -0
  22. package/dist/bin/forgebook-shot/storyShot.js.map +1 -0
  23. package/dist/bin/forgebook-shot/storyShot.types.d.ts +32 -0
  24. package/dist/bin/forgebook-shot/storyShot.types.d.ts.map +1 -0
  25. package/dist/bin/forgebook-shot/storyShot.types.js +1 -0
  26. package/dist/bin/forgebook-shot/storyShot.types.js.map +1 -0
  27. package/dist/src/browserTests.d.ts +55 -0
  28. package/dist/src/browserTests.d.ts.map +1 -0
  29. package/dist/src/browserTests.js +137 -0
  30. package/dist/src/browserTests.js.map +1 -0
  31. package/dist/src/fonts/Inter-OFL.txt +92 -0
  32. package/dist/src/fonts/Inter-latin-ext.woff2 +0 -0
  33. package/dist/src/fonts/Inter-latin.woff2 +0 -0
  34. package/dist/src/fonts/JetBrainsMono-OFL.txt +93 -0
  35. package/dist/src/fonts/JetBrainsMono-latin-ext.woff2 +0 -0
  36. package/dist/src/fonts/JetBrainsMono-latin.woff2 +0 -0
  37. package/dist/src/fonts/fonts.css +34 -0
  38. package/dist/src/overlays.d.ts +87 -0
  39. package/dist/src/overlays.d.ts.map +1 -0
  40. package/dist/src/overlays.js +103 -0
  41. package/dist/src/overlays.js.map +1 -0
  42. package/dist/src/playwrightConfig.d.ts +26 -0
  43. package/dist/src/playwrightConfig.d.ts.map +1 -0
  44. package/dist/src/playwrightConfig.js +62 -0
  45. package/dist/src/playwrightConfig.js.map +1 -0
  46. package/dist/src/serverTests.d.ts +44 -0
  47. package/dist/src/serverTests.d.ts.map +1 -0
  48. package/dist/src/serverTests.js +101 -0
  49. package/dist/src/serverTests.js.map +1 -0
  50. package/dist/src/spills.d.ts +28 -0
  51. package/dist/src/spills.d.ts.map +1 -0
  52. package/dist/src/spills.js +53 -0
  53. package/dist/src/spills.js.map +1 -0
  54. package/dist/src/storyControls.d.ts +24 -0
  55. package/dist/src/storyControls.d.ts.map +1 -0
  56. package/dist/src/storyControls.js +29 -0
  57. package/dist/src/storyControls.js.map +1 -0
  58. package/dist/src/storyFiles.d.ts +34 -0
  59. package/dist/src/storyFiles.d.ts.map +1 -0
  60. package/dist/src/storyFiles.js +66 -0
  61. package/dist/src/storyFiles.js.map +1 -0
  62. package/dist/src/testViteConfig.d.ts +21 -0
  63. package/dist/src/testViteConfig.d.ts.map +1 -0
  64. package/dist/src/testViteConfig.js +26 -0
  65. package/dist/src/testViteConfig.js.map +1 -0
  66. package/dist/src/visualBrowser.d.ts +18 -0
  67. package/dist/src/visualBrowser.d.ts.map +1 -0
  68. package/dist/src/visualBrowser.js +78 -0
  69. package/dist/src/visualBrowser.js.map +1 -0
  70. package/package.json +84 -3
@@ -0,0 +1,34 @@
1
+ import type { StorySource } from "@forgebook/story-format/source";
2
+ /** Where a package's story files are. */
3
+ export type StoryFilesOptions = {
4
+ /** The source's id, as its `StorySource` gives it (story ids start with it). */
5
+ readonly sourceId: string;
6
+ /** The source's name. */
7
+ readonly name: string;
8
+ /** The folder the patterns are relative to: the folder of the module that declares the source. */
9
+ readonly root: string;
10
+ /** The same patterns as the source's `?forgebook-files` imports, relative to `root` (`../src/**\/*.stories.tsx`). */
11
+ readonly patterns: readonly string[];
12
+ };
13
+ /**
14
+ * The story files the patterns match, as the source's keys (`./x` or `../x`, relative to `root`), sorted.
15
+ *
16
+ * @param options - where the files are.
17
+ */
18
+ export declare const storyFiles: (options: StoryFilesOptions) => string[];
19
+ /**
20
+ * A source with its index read from the disk and no loaders: enough for the story tree, the ids and the tests.
21
+ *
22
+ * @param options - where the files are.
23
+ * @throws When a story file cannot be indexed.
24
+ */
25
+ export declare const indexedSource: (options: StoryFilesOptions) => StorySource;
26
+ /**
27
+ * Whether the patterns match exactly the files of the source's `?forgebook-files` imports.
28
+ *
29
+ * @param options - the patterns.
30
+ * @param source - the source, loaded through Vite (in Vitest).
31
+ * @returns the files only one side lists; empty when they match.
32
+ */
33
+ export declare const storyFilesMismatch: (options: StoryFilesOptions, source: StorySource) => string[];
34
+ //# sourceMappingURL=storyFiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storyFiles.d.ts","sourceRoot":"","sources":["../../src/storyFiles.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAkB,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAMlF,yCAAyC;AACzC,MAAM,MAAM,iBAAiB,GAAG;IAC9B,gFAAgF;IAChF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yBAAyB;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,kGAAkG;IAClG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,qHAAqH;IACrH,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,YAAa,iBAAiB,KAAG,MAAM,EACf,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,aAAa,YAAa,iBAAiB,KAAG,WAmB1D,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,YAAa,iBAAiB,UAAU,WAAW,KAAG,MAAM,EAS1F,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * A package's story files and their index, read from the disk: what a test runner that does not go through Vite
3
+ * (Playwright) needs to declare one test per story.
4
+ *
5
+ * @remarks
6
+ * A `StorySource` names its files with `?forgebook-files` imports, which only the catalogue's Vite plugin answers; this
7
+ * reads the same files from the same patterns, with the plugin's static index. A package keeps the two lists equal with
8
+ * `storyFilesMismatch`, run in Vitest, which goes through Vite.
9
+ *
10
+ * @module
11
+ */
12
+ import { readFileSync } from "node:fs";
13
+ import { join } from "node:path";
14
+ import { sourceFiles } from "forgebook/source-files";
15
+ import { autoTitle, patternBase } from "forgebook/vite/auto-title";
16
+ import { indexStoryFile } from "forgebook/vite/index-story-file";
17
+ import { storyFileKeys } from "forgebook/vite/story-files-module";
18
+ /**
19
+ * The story files the patterns match, as the source's keys (`./x` or `../x`, relative to `root`), sorted.
20
+ *
21
+ * @param options - where the files are.
22
+ */
23
+ export const storyFiles = (options) => storyFileKeys(options.root, options.patterns);
24
+ /**
25
+ * A source with its index read from the disk and no loaders: enough for the story tree, the ids and the tests.
26
+ *
27
+ * @param options - where the files are.
28
+ * @throws When a story file cannot be indexed.
29
+ */
30
+ export const indexedSource = (options) => {
31
+ const index = {};
32
+ for (const file of storyFiles(options)) {
33
+ // the title the plugin gives: from the first pattern that matches the file, as each pattern is one module
34
+ const pattern = options.patterns.find((candidate) => storyFileKeys(options.root, [candidate]).includes(file));
35
+ const title = pattern === undefined ? undefined : autoTitle(patternBase(pattern), file);
36
+ const text = readFileSync(join(options.root, file), "utf8");
37
+ const entry = indexStoryFile(file, text, title === undefined ? {} : { autoTitle: title });
38
+ if (typeof entry === "string")
39
+ throw new Error(entry);
40
+ index[file] = entry;
41
+ }
42
+ return {
43
+ id: options.sourceId,
44
+ name: options.name,
45
+ files: [{ index, stories: {}, docs: {}, code: {}, pages: {} }],
46
+ sheets: { required: [], theme: [], restyled: [] }
47
+ };
48
+ };
49
+ /**
50
+ * Whether the patterns match exactly the files of the source's `?forgebook-files` imports.
51
+ *
52
+ * @param options - the patterns.
53
+ * @param source - the source, loaded through Vite (in Vitest).
54
+ * @returns the files only one side lists; empty when they match.
55
+ */
56
+ export const storyFilesMismatch = (options, source) => {
57
+ const fromPatterns = new Set(storyFiles(options));
58
+ const fromSource = new Set(Object.keys(sourceFiles(source).stories));
59
+ return [
60
+ ...[...fromPatterns]
61
+ .filter((file) => !fromSource.has(file))
62
+ .map((file) => `only in the patterns: ${file}`),
63
+ ...[...fromSource].filter((file) => !fromPatterns.has(file)).map((file) => `only in the source: ${file}`)
64
+ ];
65
+ };
66
+ //# sourceMappingURL=storyFiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storyFiles.js","sourceRoot":"","sources":["../../src/storyFiles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * The Vite config of a package's test instance of the frame page: the catalogue's plugin and the host name the
3
+ * container's browser asks for.
4
+ *
5
+ * @remarks
6
+ * Published (`forgebook/testing/vite`; D-167). The package's `vite.config.ts` beside its specs exports it.
7
+ * Vite serves files up to its workspace root (the monorepo's, or the package's alone), which covers the package's
8
+ * sources, the libraries it builds on and this kit's fonts.
9
+ *
10
+ * @module
11
+ */
12
+ import type { FrameworkAdapter } from "forgebook/vite/adapter";
13
+ import type { UserConfig } from "vite";
14
+ /**
15
+ * The test frame page's Vite config.
16
+ *
17
+ * @param dir - the folder of the frame page (Vite's root).
18
+ * @param framework - the framework the stories are written for (`react()` of `@forgebook/react/vite`).
19
+ */
20
+ export declare const storyTestViteConfig: (dir: string, framework: FrameworkAdapter) => UserConfig;
21
+ //# sourceMappingURL=testViteConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testViteConfig.d.ts","sourceRoot":"","sources":["../../src/testViteConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAEvC;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,QAAS,MAAM,aAAa,gBAAgB,KAAG,UAK7E,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The Vite config of a package's test instance of the frame page: the catalogue's plugin and the host name the
3
+ * container's browser asks for.
4
+ *
5
+ * @remarks
6
+ * Published (`forgebook/testing/vite`; D-167). The package's `vite.config.ts` beside its specs exports it.
7
+ * Vite serves files up to its workspace root (the monorepo's, or the package's alone), which covers the package's
8
+ * sources, the libraries it builds on and this kit's fonts.
9
+ *
10
+ * @module
11
+ */
12
+ // Node loads this module itself, as Vite leaves a workspace package out of the config bundle: hence the extension
13
+ import { forgebookPlugin } from "forgebook/vite";
14
+ /**
15
+ * The test frame page's Vite config.
16
+ *
17
+ * @param dir - the folder of the frame page (Vite's root).
18
+ * @param framework - the framework the stories are written for (`react()` of `@forgebook/react/vite`).
19
+ */
20
+ export const storyTestViteConfig = (dir, framework) => ({
21
+ root: dir,
22
+ plugins: [forgebookPlugin({ framework })],
23
+ // the visual tests' browser runs in a container and asks for the host by this name
24
+ server: { allowedHosts: ["host.docker.internal"] }
25
+ });
26
+ //# sourceMappingURL=testViteConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testViteConfig.js","sourceRoot":"","sources":["../../src/testViteConfig.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,kHAAkH;AAClH,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAIjD;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,GAAW,EAAE,SAA2B,EAAc,EAAE,CAAC,CAAC;IAC5F,IAAI,EAAE,GAAG;IACT,OAAO,EAAE,CAAC,eAAe,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC;IACzC,mFAAmF;IACnF,MAAM,EAAE,EAAE,YAAY,EAAE,CAAC,sBAAsB,CAAC,EAAE;CACnD,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /** The Playwright image the reference images are made in, the version of `@playwright/test` the repo installs. */
2
+ export declare const PLAYWRIGHT_IMAGE = "mcr.microsoft.com/playwright:v1.64.1-noble";
3
+ /** Where the browser listens and the container it runs in. */
4
+ export type VisualBrowserOptions = {
5
+ /** The port the container's browser listens on (the package's `browserPort`). */
6
+ readonly port: number;
7
+ /** The container's name, so a leftover one from an earlier run is replaced. */
8
+ readonly container: string;
9
+ };
10
+ /**
11
+ * Starts the container's browser.
12
+ *
13
+ * @param options - the port it listens on and the container's name.
14
+ * @returns the teardown, which stops it.
15
+ * @throws When Docker is not running.
16
+ */
17
+ export declare const startVisualBrowser: ({ port, container }: VisualBrowserOptions) => Promise<() => void>;
18
+ //# sourceMappingURL=visualBrowser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visualBrowser.d.ts","sourceRoot":"","sources":["../../src/visualBrowser.ts"],"names":[],"mappings":"AAaA,kHAAkH;AAClH,eAAO,MAAM,gBAAgB,+CAA+C,CAAC;AAE7E,8DAA8D;AAC9D,MAAM,MAAM,oBAAoB,GAAG;IACjC,iFAAiF;IACjF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B,CAAC;AAqBF;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,wBAA+B,oBAAoB,KAAG,OAAO,CAAC,MAAM,IAAI,CAsCtG,CAAC"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The visual tests' browser on a developer's machine: the Playwright container's Chromium, so fonts and rendering
3
+ * are the same as in CI, where the tests run inside that image.
4
+ *
5
+ * @remarks
6
+ * Published (`forgebook/testing/visual-browser`; D-167). A package's `visualBrowser.ts` beside its specs
7
+ * exports a global setup that calls `startVisualBrowser` with its own port and container name and returns the
8
+ * teardown. Needs Docker (OrbStack or Docker Desktop).
9
+ *
10
+ * @module
11
+ */
12
+ import { execFileSync } from "node:child_process";
13
+ /** The Playwright image the reference images are made in, the version of `@playwright/test` the repo installs. */
14
+ export const PLAYWRIGHT_IMAGE = "mcr.microsoft.com/playwright:v1.64.1-noble";
15
+ /** How long the browser may take to listen, in ms (the first run pulls the image). */
16
+ const START_TIMEOUT = 300_000;
17
+ /**
18
+ * Whether the browser server answers: any HTTP answer counts. A bare TCP connection does not, because Docker accepts
19
+ * connections on a published port before the server inside listens.
20
+ */
21
+ const isAnswering = async (port) => {
22
+ try {
23
+ await fetch(`http://127.0.0.1:${port}/`);
24
+ return true;
25
+ }
26
+ catch {
27
+ return false;
28
+ }
29
+ };
30
+ /** Runs docker, its output hidden unless it fails. */
31
+ const docker = (args) => execFileSync("docker", args, { encoding: "utf8" });
32
+ /**
33
+ * Starts the container's browser.
34
+ *
35
+ * @param options - the port it listens on and the container's name.
36
+ * @returns the teardown, which stops it.
37
+ * @throws When Docker is not running.
38
+ */
39
+ export const startVisualBrowser = async ({ port, container }) => {
40
+ try {
41
+ docker(["info", "--format", "{{.ServerVersion}}"]);
42
+ }
43
+ catch {
44
+ throw new Error("The visual tests need Docker: start it (OrbStack or Docker Desktop), then run them again");
45
+ }
46
+ docker(["rm", "--force", container]);
47
+ const version = PLAYWRIGHT_IMAGE.split(":v")[1]?.split("-")[0] ?? "";
48
+ docker([
49
+ "run",
50
+ "--detach",
51
+ "--rm",
52
+ "--name",
53
+ container,
54
+ "--publish",
55
+ `127.0.0.1:${port}:${port}`,
56
+ "--add-host",
57
+ "host.docker.internal:host-gateway",
58
+ PLAYWRIGHT_IMAGE,
59
+ "npx",
60
+ "--yes",
61
+ `playwright@${version}`,
62
+ "run-server",
63
+ "--port",
64
+ String(port),
65
+ "--host",
66
+ "0.0.0.0"
67
+ ]);
68
+ const deadline = Date.now() + START_TIMEOUT;
69
+ while (!(await isAnswering(port))) {
70
+ if (Date.now() > deadline)
71
+ throw new Error(`The container's browser did not listen on ${port}`);
72
+ await new Promise((resolve) => setTimeout(resolve, 500));
73
+ }
74
+ return () => {
75
+ docker(["stop", container]);
76
+ };
77
+ };
78
+ //# sourceMappingURL=visualBrowser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visualBrowser.js","sourceRoot":"","sources":["../../src/visualBrowser.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,kHAAkH;AAClH,MAAM,CAAC,MAAM,gBAAgB,GAAG,4CAA4C,CAAC;AAU7E,sFAAsF;AACtF,MAAM,aAAa,GAAG,OAAO,CAAC;AAE9B;;;GAGG;AACH,MAAM,WAAW,GAAG,KAAK,EAAE,IAAY,EAAoB,EAAE;IAC3D,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,oBAAoB,IAAI,GAAG,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC;AAEF,sDAAsD;AACtD,MAAM,MAAM,GAAG,CAAC,IAAuB,EAAU,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;AAEvG;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAwB,EAAuB,EAAE;IACzG,IAAI,CAAC;QACH,MAAM,CAAC,CAAC,MAAM,EAAE,UAAU,EAAE,oBAAoB,CAAC,CAAC,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,0FAA0F,CAC3F,CAAC;IACJ,CAAC;IACD,MAAM,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACrE,MAAM,CAAC;QACL,KAAK;QACL,UAAU;QACV,MAAM;QACN,QAAQ;QACR,SAAS;QACT,WAAW;QACX,aAAa,IAAI,IAAI,IAAI,EAAE;QAC3B,YAAY;QACZ,mCAAmC;QACnC,gBAAgB;QAChB,KAAK;QACL,OAAO;QACP,cAAc,OAAO,EAAE;QACvB,YAAY;QACZ,QAAQ;QACR,MAAM,CAAC,IAAI,CAAC;QACZ,QAAQ;QACR,SAAS;KACV,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,CAAC;IAC5C,OAAO,CAAC,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAClC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,IAAI,EAAE,CAAC,CAAC;QAChG,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,GAAS,EAAE;QAChB,MAAM,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC;AACJ,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,87 @@
1
1
  {
2
2
  "name": "@forgebook/testing",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0",
4
+ "description": "Tests from a package's stories: each story and variant in the browser with axe, spills and overlays, screenshots, and each story rendered on the server.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/Ensiria/forgebook.git",
9
+ "directory": "packages/testing"
10
+ },
11
+ "type": "module",
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "engines": {
16
+ "node": ">=22.18"
17
+ },
18
+ "sideEffects": [
19
+ "*.css"
20
+ ],
21
+ "bin": {
22
+ "forgebook-heights": "./dist/bin/forgebook-heights/forgebook-heights.mjs",
23
+ "forgebook-shot": "./dist/bin/forgebook-shot/forgebook-shot.mjs"
24
+ },
25
+ "exports": {
26
+ "./browser": {
27
+ "types": "./dist/src/browserTests.d.ts",
28
+ "default": "./dist/src/browserTests.js"
29
+ },
30
+ "./server": {
31
+ "types": "./dist/src/serverTests.d.ts",
32
+ "default": "./dist/src/serverTests.js"
33
+ },
34
+ "./story-files": {
35
+ "types": "./dist/src/storyFiles.d.ts",
36
+ "default": "./dist/src/storyFiles.js"
37
+ },
38
+ "./playwright": {
39
+ "types": "./dist/src/playwrightConfig.d.ts",
40
+ "default": "./dist/src/playwrightConfig.js"
41
+ },
42
+ "./vite": {
43
+ "types": "./dist/src/testViteConfig.d.ts",
44
+ "default": "./dist/src/testViteConfig.js"
45
+ },
46
+ "./visual-browser": {
47
+ "types": "./dist/src/visualBrowser.d.ts",
48
+ "default": "./dist/src/visualBrowser.js"
49
+ },
50
+ "./overlays": {
51
+ "types": "./dist/src/overlays.d.ts",
52
+ "default": "./dist/src/overlays.js"
53
+ },
54
+ "./fonts.css": "./dist/src/fonts/fonts.css"
55
+ },
56
+ "dependencies": {
57
+ "@axe-core/playwright": "4.14.0",
58
+ "@ensiria/cli-kit": "^0.1.1",
59
+ "@forgebook/story-format": "0.1.0"
60
+ },
61
+ "peerDependencies": {
62
+ "@playwright/test": "^1.64.0",
63
+ "vite": "^8.0.0",
64
+ "vitest": "^5.0.0",
65
+ "forgebook": "^0.1.0"
66
+ },
67
+ "devDependencies": {
68
+ "@playwright/test": "1.64.1",
69
+ "@types/node": "24.19.2",
70
+ "@types/react": "19.3.0",
71
+ "react": "19.3.0",
72
+ "vite": "8.3.5",
73
+ "vitest": "5.0.5",
74
+ "@forgebook/tools": "0.0.0",
75
+ "@forgebook/typescript-config": "0.0.0",
76
+ "forgebook": "0.1.0"
77
+ },
78
+ "publishConfig": {
79
+ "access": "public"
80
+ },
81
+ "scripts": {
82
+ "build": "package-build build",
83
+ "manifest": "package-build manifest",
84
+ "test": "vitest run",
85
+ "typecheck": "tsc -p src && tsc -p bin && tsc -p test"
86
+ }
6
87
  }