@recursica/adapter-tester 2.2.0 → 4.0.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 (42) hide show
  1. package/README.md +69 -23
  2. package/dist/adapter-tester.schema.json.d.ts +24 -11
  3. package/dist/cli.cjs +32 -23
  4. package/dist/cli.cjs.map +1 -1
  5. package/dist/cli.js +296 -4853
  6. package/dist/cli.js.map +1 -1
  7. package/dist/config.d.ts +57 -6
  8. package/dist/config.d.ts.map +1 -1
  9. package/dist/fileConfig.d.ts +21 -5
  10. package/dist/fileConfig.d.ts.map +1 -1
  11. package/dist/golden/diffPng.d.ts +13 -0
  12. package/dist/golden/diffPng.d.ts.map +1 -0
  13. package/dist/golden/manifest.schema.json.d.ts +27 -0
  14. package/dist/golden/manifestStore.d.ts +33 -0
  15. package/dist/golden/manifestStore.d.ts.map +1 -0
  16. package/dist/golden/resolveSourceOfTruthGolden.d.ts +29 -0
  17. package/dist/golden/resolveSourceOfTruthGolden.d.ts.map +1 -0
  18. package/dist/golden/validateManifest.d.ts +7 -0
  19. package/dist/golden/validateManifest.d.ts.map +1 -0
  20. package/dist/index-C6uYPRmx.cjs +9 -0
  21. package/dist/index-C6uYPRmx.cjs.map +1 -0
  22. package/dist/index-DqQzFSAH.js +4667 -0
  23. package/dist/index-DqQzFSAH.js.map +1 -0
  24. package/dist/index.cjs +1 -1
  25. package/dist/index.cjs.map +1 -1
  26. package/dist/index.js +21 -6
  27. package/dist/index.js.map +1 -1
  28. package/dist/testing/runVisualRegression.d.ts +48 -6
  29. package/dist/testing/runVisualRegression.d.ts.map +1 -1
  30. package/dist/testing.cjs +4 -1
  31. package/dist/testing.cjs.map +1 -1
  32. package/dist/testing.d.ts +1 -1
  33. package/dist/testing.d.ts.map +1 -1
  34. package/dist/testing.js +311 -155
  35. package/dist/testing.js.map +1 -1
  36. package/package.json +4 -7
  37. package/src/adapter-tester.schema.json +24 -11
  38. package/src/golden/manifest.schema.json +24 -0
  39. package/dist/config-B0Eop8Az.cjs +0 -2
  40. package/dist/config-B0Eop8Az.cjs.map +0 -1
  41. package/dist/config-CDxTeSAY.js +0 -21
  42. package/dist/config-CDxTeSAY.js.map +0 -1
@@ -8,11 +8,11 @@
8
8
  "properties": {
9
9
  "$schema": {
10
10
  "type": "string",
11
- "description": "Optional pointer to this schema for editor autocomplete, e.g. \"./node_modules/@recursica/adapter-tester/src/adapter-tester.schema.json\"."
11
+ "description": "Optional pointer to this schema for editor autocomplete, e.g. \"https://raw.githubusercontent.com/borderux/recursica/main/packages/adapter-tester/src/adapter-tester.schema.json\"."
12
12
  },
13
13
  "name": {
14
14
  "type": "string",
15
- "description": "Label for this project's own target. Defaults to the unscoped name in this project's package.json (e.g. \"@recursica/mui-adapter\" -> \"mui-adapter\")."
15
+ "description": "Label for this project's own target. Defaults to the unscoped name in this project's package.json (e.g. \"@recursica/some-adapter\" -> \"some-adapter\")."
16
16
  },
17
17
  "storybook": {
18
18
  "type": "object",
@@ -89,20 +89,33 @@
89
89
  }
90
90
  ]
91
91
  },
92
+ "isSourceOfTruthAdapter": {
93
+ "type": "boolean",
94
+ "description": "True only for the source-of-truth adapter's own config (mantine-adapter). Skips `sourceOfTruth` entirely — there's nothing above it to diverge from — and runs the own-drift golden check standalone, against just this project's own Storybook. Defaults to false."
95
+ },
92
96
  "diffThresholdPixels": {
93
97
  "type": "number",
94
98
  "minimum": 0,
95
99
  "description": "Global visual diff threshold, in mismatched pixels, before a story is considered a failure. Defaults to 3500. AI agents must not modify this field — see AGENT.md."
96
100
  },
97
- "relaxedThresholdStoryIds": {
98
- "type": "array",
99
- "items": { "type": "string" },
100
- "description": "Story id prefixes that use `relaxedThresholdPixels` instead of the global `diffThresholdPixels`."
101
- },
102
- "relaxedThresholdPixels": {
103
- "type": "number",
104
- "minimum": 0,
105
- "description": "Diff threshold applied to stories matching `relaxedThresholdStoryIds`."
101
+ "stories": {
102
+ "type": "object",
103
+ "additionalProperties": {
104
+ "type": "object",
105
+ "additionalProperties": false,
106
+ "properties": {
107
+ "threshold": {
108
+ "type": "number",
109
+ "minimum": 0,
110
+ "description": "Diff threshold override for matching stories, in mismatched pixels. Overrides `diffThresholdPixels`."
111
+ },
112
+ "exclude": {
113
+ "type": "boolean",
114
+ "description": "Skip matching stories entirely — no own-drift check, no divergence check, no golden captured. For stories that don't have a cross-adapter counterpart; use `excludeTitlePrefixes` to drop a whole title instead."
115
+ }
116
+ }
117
+ },
118
+ "description": "Per-story overrides, keyed by story id prefix (a story matches if its id equals the key or starts with it). When more than one key matches a story, the longest (most specific) key wins."
106
119
  },
107
120
  "excludeTitlePrefixes": {
108
121
  "type": "array",
@@ -0,0 +1,24 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "$id": "https://github.com/borderux/recursica/tree/main/packages/adapter-tester/src/golden/manifest.schema.json",
4
+ "title": "test/golden/manifest.json",
5
+ "description": "Tracks golden (baseline) image metadata for @recursica/adapter-tester's golden-image visual regression checks. One manifest lives alongside its adapter's test/golden/<story-id>.png files, keyed by story id.",
6
+ "type": "object",
7
+ "additionalProperties": {
8
+ "type": "object",
9
+ "additionalProperties": false,
10
+ "required": ["createdAt"],
11
+ "properties": {
12
+ "createdAt": {
13
+ "type": "string",
14
+ "format": "date-time",
15
+ "description": "When this story's own golden PNG was last captured, via --update-golden, --approve-divergence, or first-run auto-create."
16
+ },
17
+ "sourceOfTruthCreatedAt": {
18
+ "type": "string",
19
+ "format": "date-time",
20
+ "description": "The source-of-truth adapter's (mantine) manifest `createdAt` for this story at the time this adapter's divergence from it was last reviewed via --approve-divergence. Omitted on the source-of-truth adapter's own manifest, and omitted here until the first approval. If mantine's current `createdAt` for this story is newer than this value, the divergence is flagged again for re-review."
21
+ }
22
+ }
23
+ }
24
+ }
@@ -1,2 +0,0 @@
1
- "use strict";function u(t){const r=t.targets.filter(e=>e.sourceOfTruth).length;if(r!==1)throw new Error(`adapter-tester config must mark exactly one target as sourceOfTruth (found ${r})`);return t}function o(t){const r=t.targets.find(e=>e.sourceOfTruth);if(!r)throw new Error("adapter-tester config has no target marked sourceOfTruth");return r}exports.defineAdapterTesterConfig=u;exports.getSourceOfTruth=o;
2
- //# sourceMappingURL=config-B0Eop8Az.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-B0Eop8Az.cjs","sources":["../src/config.ts"],"sourcesContent":["export interface AdapterTarget {\n /** Human-readable name used in test titles, report labels, and artifact filenames. */\n name: string;\n /** Base URL the target's Storybook instance is served from. */\n url: string;\n /**\n * Marks this target as the visual/token source of truth every other target\n * is compared against. Exactly one target in a config must set this true.\n */\n sourceOfTruth?: boolean;\n}\n\nexport interface AdapterTesterConfig {\n targets: AdapterTarget[];\n /** Global pixel-diff threshold applied to every story comparison. */\n diffThresholdPixels: number;\n /**\n * Story ids (matched by prefix) that get `relaxedThresholdPixels` instead\n * of `diffThresholdPixels`, for components with acceptable cross-library\n * structural variation (e.g. native control widgets).\n */\n relaxedThresholdStoryIds?: string[];\n /** Pixel-diff threshold applied to `relaxedThresholdStoryIds`. */\n relaxedThresholdPixels?: number;\n /**\n * Storybook entry title categories excluded from the comparison — an\n * entry is excluded if its title equals one of these or starts with\n * `\"<value>/\"`. Defaults to [\"Theme\", \"Tokens\", \"Introduction\"]:\n * `@recursica/storybook-template`'s own default token/theme demo stories\n * (which every adapter's Storybook inherits automatically) plus each\n * adapter's own onboarding \"Introduction\" stories — neither has a\n * cross-adapter counterpart to diff against.\n */\n excludeTitlePrefixes?: string[];\n}\n\nexport function defineAdapterTesterConfig(\n config: AdapterTesterConfig,\n): AdapterTesterConfig {\n const sourceOfTruthCount = config.targets.filter(\n (target) => target.sourceOfTruth,\n ).length;\n if (sourceOfTruthCount !== 1) {\n throw new Error(\n `adapter-tester config must mark exactly one target as sourceOfTruth (found ${sourceOfTruthCount})`,\n );\n }\n return config;\n}\n\nexport function getSourceOfTruth(config: AdapterTesterConfig): AdapterTarget {\n const sourceOfTruth = config.targets.find((target) => target.sourceOfTruth);\n if (!sourceOfTruth) {\n throw new Error(\"adapter-tester config has no target marked sourceOfTruth\");\n }\n return sourceOfTruth;\n}\n"],"names":["defineAdapterTesterConfig","config","sourceOfTruthCount","target","getSourceOfTruth","sourceOfTruth"],"mappings":"aAoCO,SAASA,EACdC,EACqB,CACrB,MAAMC,EAAqBD,EAAO,QAAQ,OACvCE,GAAWA,EAAO,aAAA,EACnB,OACF,GAAID,IAAuB,EACzB,MAAM,IAAI,MACR,8EAA8EA,CAAkB,GAAA,EAGpG,OAAOD,CACT,CAEO,SAASG,EAAiBH,EAA4C,CAC3E,MAAMI,EAAgBJ,EAAO,QAAQ,KAAME,GAAWA,EAAO,aAAa,EAC1E,GAAI,CAACE,EACH,MAAM,IAAI,MAAM,0DAA0D,EAE5E,OAAOA,CACT"}
@@ -1,21 +0,0 @@
1
- function o(t) {
2
- const r = t.targets.filter(
3
- (e) => e.sourceOfTruth
4
- ).length;
5
- if (r !== 1)
6
- throw new Error(
7
- `adapter-tester config must mark exactly one target as sourceOfTruth (found ${r})`
8
- );
9
- return t;
10
- }
11
- function u(t) {
12
- const r = t.targets.find((e) => e.sourceOfTruth);
13
- if (!r)
14
- throw new Error("adapter-tester config has no target marked sourceOfTruth");
15
- return r;
16
- }
17
- export {
18
- o as d,
19
- u as g
20
- };
21
- //# sourceMappingURL=config-CDxTeSAY.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-CDxTeSAY.js","sources":["../src/config.ts"],"sourcesContent":["export interface AdapterTarget {\n /** Human-readable name used in test titles, report labels, and artifact filenames. */\n name: string;\n /** Base URL the target's Storybook instance is served from. */\n url: string;\n /**\n * Marks this target as the visual/token source of truth every other target\n * is compared against. Exactly one target in a config must set this true.\n */\n sourceOfTruth?: boolean;\n}\n\nexport interface AdapterTesterConfig {\n targets: AdapterTarget[];\n /** Global pixel-diff threshold applied to every story comparison. */\n diffThresholdPixels: number;\n /**\n * Story ids (matched by prefix) that get `relaxedThresholdPixels` instead\n * of `diffThresholdPixels`, for components with acceptable cross-library\n * structural variation (e.g. native control widgets).\n */\n relaxedThresholdStoryIds?: string[];\n /** Pixel-diff threshold applied to `relaxedThresholdStoryIds`. */\n relaxedThresholdPixels?: number;\n /**\n * Storybook entry title categories excluded from the comparison — an\n * entry is excluded if its title equals one of these or starts with\n * `\"<value>/\"`. Defaults to [\"Theme\", \"Tokens\", \"Introduction\"]:\n * `@recursica/storybook-template`'s own default token/theme demo stories\n * (which every adapter's Storybook inherits automatically) plus each\n * adapter's own onboarding \"Introduction\" stories — neither has a\n * cross-adapter counterpart to diff against.\n */\n excludeTitlePrefixes?: string[];\n}\n\nexport function defineAdapterTesterConfig(\n config: AdapterTesterConfig,\n): AdapterTesterConfig {\n const sourceOfTruthCount = config.targets.filter(\n (target) => target.sourceOfTruth,\n ).length;\n if (sourceOfTruthCount !== 1) {\n throw new Error(\n `adapter-tester config must mark exactly one target as sourceOfTruth (found ${sourceOfTruthCount})`,\n );\n }\n return config;\n}\n\nexport function getSourceOfTruth(config: AdapterTesterConfig): AdapterTarget {\n const sourceOfTruth = config.targets.find((target) => target.sourceOfTruth);\n if (!sourceOfTruth) {\n throw new Error(\"adapter-tester config has no target marked sourceOfTruth\");\n }\n return sourceOfTruth;\n}\n"],"names":["defineAdapterTesterConfig","config","sourceOfTruthCount","target","getSourceOfTruth","sourceOfTruth"],"mappings":"AAoCO,SAASA,EACdC,GACqB;AACrB,QAAMC,IAAqBD,EAAO,QAAQ;AAAA,IACxC,CAACE,MAAWA,EAAO;AAAA,EAAA,EACnB;AACF,MAAID,MAAuB;AACzB,UAAM,IAAI;AAAA,MACR,8EAA8EA,CAAkB;AAAA,IAAA;AAGpG,SAAOD;AACT;AAEO,SAASG,EAAiBH,GAA4C;AAC3E,QAAMI,IAAgBJ,EAAO,QAAQ,KAAK,CAACE,MAAWA,EAAO,aAAa;AAC1E,MAAI,CAACE;AACH,UAAM,IAAI,MAAM,0DAA0D;AAE5E,SAAOA;AACT;"}