@invarn/cibuild 2.2.1 → 2.2.3
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/dist/cli.cjs +217 -38
- package/dist/src/yaml/steps/structural-facts.d.ts +101 -0
- package/dist/src/yaml/steps/structural-facts.d.ts.map +1 -1
- package/dist/src/yaml/steps/structural-facts.js +0 -0
- package/dist/src/yaml/steps/structural-facts.test.js +386 -3
- package/dist/src/yaml/steps/ui-fidelity-render-android.d.ts.map +1 -1
- package/dist/src/yaml/steps/ui-fidelity-render-android.js +21 -1
- package/package.json +1 -1
|
@@ -224,9 +224,25 @@ export type AppearanceFact = {
|
|
|
224
224
|
kind: 'element_extra';
|
|
225
225
|
elementId: string;
|
|
226
226
|
};
|
|
227
|
+
/**
|
|
228
|
+
* A reference-shaped snapshot of the render's OWN appearance — the element-id
|
|
229
|
+
* set plus per-element text/colors it produced. Persisted in the structural
|
|
230
|
+
* block so a later no-Figma render can use it as the `previous_render` baseline
|
|
231
|
+
* (the colors/text/ids to diff against), mirroring how Signal B's geometry
|
|
232
|
+
* baseline reuses the previous render's persisted `geometry`. text/color are
|
|
233
|
+
* present only for the elements that exposed them.
|
|
234
|
+
*/
|
|
235
|
+
export interface AppearanceRendered {
|
|
236
|
+
elementIds: string[];
|
|
237
|
+
text?: TextSource;
|
|
238
|
+
color?: ColorSource;
|
|
239
|
+
}
|
|
227
240
|
export interface StructuralAppearance {
|
|
228
241
|
baseline: AppearanceBaseline;
|
|
229
242
|
facts: AppearanceFact[];
|
|
243
|
+
/** The render's own appearance, persisted as the baseline source for the next
|
|
244
|
+
* no-Figma render. Present whenever Signal C ran. */
|
|
245
|
+
rendered?: AppearanceRendered;
|
|
230
246
|
}
|
|
231
247
|
/**
|
|
232
248
|
* The reference side of the appearance diff, passed into `buildStructuralBlock`.
|
|
@@ -242,7 +258,52 @@ export interface AppearanceReference {
|
|
|
242
258
|
* previous render's text on `previous_render`). When supplied, copy facts are
|
|
243
259
|
* derived against the render's per-node text. Absent → presence facts only. */
|
|
244
260
|
text?: TextSource;
|
|
261
|
+
/** Reference fill/text color per element id (Figma `fills` on the figma
|
|
262
|
+
* baseline; the previous render's colors on `previous_render`). When supplied,
|
|
263
|
+
* color facts are derived against the render's per-node colors. */
|
|
264
|
+
color?: ColorSource;
|
|
245
265
|
}
|
|
266
|
+
/** The per-screen reference params the runner assembles an `AppearanceReference`
|
|
267
|
+
* from (the slices of `params.reference_*` for one screen). */
|
|
268
|
+
export interface AppearanceReferenceParams {
|
|
269
|
+
/** Per-screen `reference_geometry` (design/baseline geometry). Its keys seed
|
|
270
|
+
* the element-id set. */
|
|
271
|
+
refGeom?: ReferenceGeometry | null;
|
|
272
|
+
/** Per-screen `reference_text` (text per element id). */
|
|
273
|
+
refText?: TextSource | null;
|
|
274
|
+
/** Per-screen `reference_color` (fill/text color per element id). */
|
|
275
|
+
refColor?: ColorSource | null;
|
|
276
|
+
baseline: AppearanceBaseline;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Assemble the `AppearanceReference` from a screen's reference params. Issue 05
|
|
280
|
+
* decouples the appearance container from `reference_geometry`: the reference is
|
|
281
|
+
* built when ANY of geometry / text / color is present, with `elementIds` = the
|
|
282
|
+
* UNION of their keys (geometry first, then text, then color — deduped, order
|
|
283
|
+
* preserved). So a run carrying `reference_color` but no `reference_geometry` now
|
|
284
|
+
* yields a reference (→ color facts), while a geometry-only run is byte-identical
|
|
285
|
+
* to before (color/text keys are a subset). `text`/`color` are attached only when
|
|
286
|
+
* present. No reference of any kind → null (no appearance container).
|
|
287
|
+
*/
|
|
288
|
+
export declare function buildAppearanceReferenceFromParams(params: AppearanceReferenceParams): AppearanceReference | null;
|
|
289
|
+
/**
|
|
290
|
+
* Map a previous catalog render's persisted appearance snapshot
|
|
291
|
+
* (`StructuralAppearance.rendered` — element ids + per-element colors) into the
|
|
292
|
+
* `previous_render` AppearanceReference the next render diffs against. The
|
|
293
|
+
* no-Figma drift path: the colors/ids the next render compares itself to are the
|
|
294
|
+
* LAST render's, so a diverging fill surfaces as a regression (drift), marked
|
|
295
|
+
* `baseline: 'previous_render'`, distinct from a design divergence.
|
|
296
|
+
*
|
|
297
|
+
* Pure (no I/O) — the testable core the thin catalog-fetch adapter wraps,
|
|
298
|
+
* mirroring how the geometry baseline reuses the previous render's persisted
|
|
299
|
+
* `geometry`. `color` is carried only when the previous render exposed colors;
|
|
300
|
+
* a previous render with no extractable color yields a presence-only reference
|
|
301
|
+
* (element ids, no color). A genuinely absent previous render (no snapshot) →
|
|
302
|
+
* null, so the next render carries no appearance container, exactly as before.
|
|
303
|
+
* Issue 01 carries the color channels; the previous render's `text` (copy) is a
|
|
304
|
+
* later slice's concern and is intentionally not mapped here.
|
|
305
|
+
*/
|
|
306
|
+
export declare function appearanceReferenceFromPreviousRender(previous: AppearanceRendered | null | undefined): AppearanceReference | null;
|
|
246
307
|
/**
|
|
247
308
|
* Element-presence facts from the set difference of the rendered element-id set
|
|
248
309
|
* and the reference element-id set, keyed on the stable element id shared with
|
|
@@ -275,6 +336,42 @@ export type TextSource = Record<string, string | undefined>;
|
|
|
275
336
|
* separately-wired concern.
|
|
276
337
|
*/
|
|
277
338
|
export declare function deriveCopyFacts(rendered: TextSource, reference: TextSource): AppearanceFact[];
|
|
339
|
+
/** CIELAB triple [L, a, b]. */
|
|
340
|
+
export type Lab = [number, number, number];
|
|
341
|
+
/** One element's rendered/reference colors, by channel. A missing channel is
|
|
342
|
+
* "no color signal" for that element/channel — never a divergence. */
|
|
343
|
+
export interface ElementColors {
|
|
344
|
+
fill?: string;
|
|
345
|
+
text?: string;
|
|
346
|
+
}
|
|
347
|
+
export type ColorSource = Record<string, ElementColors>;
|
|
348
|
+
/**
|
|
349
|
+
* Convert an sRGB hex string to CIELAB (D65). White → ~[100,0,0], black → L 0.
|
|
350
|
+
* Returns [0,0,0] for an unparseable string so a malformed color never throws
|
|
351
|
+
* (the deriver guards on signal presence separately).
|
|
352
|
+
*/
|
|
353
|
+
export declare function hexToLab(hex: string): Lab;
|
|
354
|
+
/**
|
|
355
|
+
* CIEDE2000 colour-difference ΔE00 between two CIELAB colours (kL=kC=kH=1).
|
|
356
|
+
* Implements Sharma, Wu & Dalal (2005); validated against their supplementary
|
|
357
|
+
* test data. Pure and symmetric; identical colours give 0.
|
|
358
|
+
*/
|
|
359
|
+
export declare function ciede2000(lab1: Lab, lab2: Lab): number;
|
|
360
|
+
/**
|
|
361
|
+
* Color facts from the per-element, per-channel comparison of rendered vs
|
|
362
|
+
* reference color, keyed on the stable element id shared with Signal B. For each
|
|
363
|
+
* element/channel the REFERENCE declares a color for and the render also exposes
|
|
364
|
+
* one: identical color → no fact; any divergence → a `color` fact carrying the
|
|
365
|
+
* channel (fill vs text), both hex values, and the CIEDE2000 ΔE as the metric.
|
|
366
|
+
* Fill and text are distinct channels, so a correct background with a wrong text
|
|
367
|
+
* color and the reverse are separate facts, never collapsed. A missing rendered
|
|
368
|
+
* or reference color for a channel is no signal → no fact.
|
|
369
|
+
*
|
|
370
|
+
* Pure and platform-agnostic; order-independent and deterministic (output sorted
|
|
371
|
+
* by element id then channel, fill before text). Measurement only — significance
|
|
372
|
+
* is a later, separately-wired concern.
|
|
373
|
+
*/
|
|
374
|
+
export declare function deriveColorFacts(rendered: ColorSource, reference: ColorSource): AppearanceFact[];
|
|
278
375
|
/**
|
|
279
376
|
* Assemble the inline `structural` block (ADR-0004): Signal-A facts always, plus
|
|
280
377
|
* the Signal-B geometry block when `referenceGeometry` is supplied. Size (w/h)
|
|
@@ -361,5 +458,9 @@ export declare function getGeometryStageInternals(): {
|
|
|
361
458
|
}) => ReviewScaffold;
|
|
362
459
|
derivePresenceFacts: (renderedIds: Iterable<string>, referenceIds: Iterable<string>) => AppearanceFact[];
|
|
363
460
|
deriveCopyFacts: (rendered: TextSource, reference: TextSource) => AppearanceFact[];
|
|
461
|
+
deriveColorFacts: (rendered: ColorSource, reference: ColorSource) => AppearanceFact[];
|
|
462
|
+
buildAppearanceReferenceFromParams: (params: AppearanceReferenceParams) => AppearanceReference | null;
|
|
463
|
+
ciede2000: (lab1: Lab, lab2: Lab) => number;
|
|
464
|
+
hexToLab: (hex: string) => Lab;
|
|
364
465
|
};
|
|
365
466
|
//# sourceMappingURL=structural-facts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"structural-facts.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/structural-facts.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"structural-facts.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/structural-facts.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* overflowing voucher tag; the deriver must surface the bottom clip as a
|
|
9
9
|
* fact so it is never again skipped by eye.
|
|
10
10
|
*/
|
|
11
|
-
import { deriveStructuralFacts, derivePresenceFacts, deriveCopyFacts, diffKeyGeometry, buildStructuralBlock, buildReviewScaffold, getStructuralFactsStageInternals, getGeometryStageInternals, } from './structural-facts.js';
|
|
11
|
+
import { deriveStructuralFacts, derivePresenceFacts, deriveCopyFacts, deriveColorFacts, ciede2000, hexToLab, diffKeyGeometry, buildStructuralBlock, buildReviewScaffold, appearanceReferenceFromPreviousRender, buildAppearanceReferenceFromParams, getStructuralFactsStageInternals, getGeometryStageInternals, } from './structural-facts.js';
|
|
12
12
|
// 200x400 canvas in px for all fixtures unless noted.
|
|
13
13
|
const CANVAS = { left: 0, top: 0, right: 200, bottom: 400 };
|
|
14
14
|
describe('deriveStructuralFacts — containment', () => {
|
|
@@ -518,6 +518,92 @@ describe('derivePresenceFacts — set difference over element ids', () => {
|
|
|
518
518
|
]);
|
|
519
519
|
});
|
|
520
520
|
});
|
|
521
|
+
describe('ciede2000 — CIEDE2000 ΔE against the Sharma supplementary test data', () => {
|
|
522
|
+
// Canonical test vectors from Sharma, Wu & Dalal, "The CIEDE2000 Color-
|
|
523
|
+
// Difference Formula: Implementation Notes, Supplementary Test Data, and
|
|
524
|
+
// Mathematical Observations" (2005). Each row: Lab1, Lab2, expected ΔE00.
|
|
525
|
+
// These exercise the hue-discontinuity and high-chroma edge cases an
|
|
526
|
+
// incorrect implementation gets wrong.
|
|
527
|
+
const SHARMA = [
|
|
528
|
+
[[50, 2.6772, -79.7751], [50, 0, -82.7485], 2.0425],
|
|
529
|
+
[[50, 3.1571, -77.2803], [50, 0, -82.7485], 2.8615],
|
|
530
|
+
[[50, 2.8361, -74.02], [50, 0, -82.7485], 3.4412],
|
|
531
|
+
[[50, -1.3802, -84.2814], [50, 0, -82.7485], 1.0],
|
|
532
|
+
[[50, -1.1848, -84.8006], [50, 0, -82.7485], 1.0],
|
|
533
|
+
[[50, 0, 0], [50, -1, 2], 2.3669],
|
|
534
|
+
[[50, 2.49, -0.001], [50, -2.49, 0.0009], 7.1792],
|
|
535
|
+
[[50, 2.49, -0.001], [50, -2.49, 0.0011], 7.2195],
|
|
536
|
+
[[50, -0.001, 2.49], [50, 0.0009, -2.49], 4.8045],
|
|
537
|
+
[[50, 2.5, 0], [50, 0, -2.5], 4.3065],
|
|
538
|
+
[[50, 2.5, 0], [73, 25, -18], 27.1492],
|
|
539
|
+
[[50, 2.5, 0], [50, 3.1736, 0.5854], 1.0],
|
|
540
|
+
[[60.2574, -34.0099, 36.2677], [60.4626, -34.1751, 39.4387], 1.2644],
|
|
541
|
+
[[63.0109, -31.0961, -5.8663], [62.8187, -29.7946, -4.0864], 1.263],
|
|
542
|
+
[[22.7233, 20.0904, -46.694], [23.0331, 14.973, -42.5619], 2.0373],
|
|
543
|
+
[[90.8027, -2.0831, 1.441], [91.1528, -1.6435, 0.0447], 1.4441],
|
|
544
|
+
[[2.0776, 0.0795, -1.135], [0.9033, -0.0636, -0.5514], 0.9082],
|
|
545
|
+
];
|
|
546
|
+
for (const [lab1, lab2, expected] of SHARMA) {
|
|
547
|
+
test(`ΔE(${lab1.join(',')} ; ${lab2.join(',')}) ≈ ${expected}`, () => {
|
|
548
|
+
expect(ciede2000(lab1, lab2)).toBeCloseTo(expected, 4);
|
|
549
|
+
});
|
|
550
|
+
}
|
|
551
|
+
test('identical colors have ΔE 0 and the metric is symmetric', () => {
|
|
552
|
+
expect(ciede2000([42, 7, -13], [42, 7, -13])).toBe(0);
|
|
553
|
+
expect(ciede2000([50, 2.5, 0], [73, 25, -18])).toBeCloseTo(ciede2000([73, 25, -18], [50, 2.5, 0]), 10);
|
|
554
|
+
});
|
|
555
|
+
});
|
|
556
|
+
describe('hexToLab — sRGB hex → CIELAB (D65)', () => {
|
|
557
|
+
test('white maps to L≈100, a≈0, b≈0', () => {
|
|
558
|
+
const [L, a, b] = hexToLab('#ffffff');
|
|
559
|
+
expect(L).toBeCloseTo(100, 3);
|
|
560
|
+
expect(a).toBeCloseTo(0, 3);
|
|
561
|
+
expect(b).toBeCloseTo(0, 3);
|
|
562
|
+
});
|
|
563
|
+
test('black maps to L≈0', () => {
|
|
564
|
+
const [L] = hexToLab('#000000');
|
|
565
|
+
expect(L).toBeCloseTo(0, 3);
|
|
566
|
+
});
|
|
567
|
+
test('accepts hex with or without a leading # and is case-insensitive', () => {
|
|
568
|
+
expect(hexToLab('FFFFFF')).toEqual(hexToLab('#ffffff'));
|
|
569
|
+
});
|
|
570
|
+
});
|
|
571
|
+
describe('deriveColorFacts — rendered vs reference color per element/channel', () => {
|
|
572
|
+
test('matching colors produce no fact', () => {
|
|
573
|
+
expect(deriveColorFacts({ card: { fill: '#ff0000', text: '#000000' } }, { card: { fill: '#ff0000', text: '#000000' } })).toEqual([]);
|
|
574
|
+
// case-insensitive match
|
|
575
|
+
expect(deriveColorFacts({ card: { fill: '#FF0000' } }, { card: { fill: '#ff0000' } })).toEqual([]);
|
|
576
|
+
});
|
|
577
|
+
test('a fill divergence yields one fill-channel fact with the correct ΔE', () => {
|
|
578
|
+
const facts = deriveColorFacts({ card: { fill: '#ff0000' } }, { card: { fill: '#00ff00' } });
|
|
579
|
+
expect(facts).toHaveLength(1);
|
|
580
|
+
expect(facts[0]).toMatchObject({ kind: 'color', elementId: 'card', channel: 'fill', rendered: '#ff0000', reference: '#00ff00' });
|
|
581
|
+
expect(facts[0].deltaE).toBeCloseTo(ciede2000(hexToLab('#ff0000'), hexToLab('#00ff00')), 10);
|
|
582
|
+
});
|
|
583
|
+
test('fill and text are distinct channels — a wrong text color does not collapse with a correct fill', () => {
|
|
584
|
+
const facts = deriveColorFacts({ card: { fill: '#ffffff', text: '#111111' } }, { card: { fill: '#ffffff', text: '#000000' } });
|
|
585
|
+
expect(facts).toHaveLength(1);
|
|
586
|
+
expect(facts[0]).toMatchObject({ kind: 'color', elementId: 'card', channel: 'text', rendered: '#111111', reference: '#000000' });
|
|
587
|
+
});
|
|
588
|
+
test('both channels diverging yield two facts, fill before text', () => {
|
|
589
|
+
const facts = deriveColorFacts({ card: { fill: '#ff0000', text: '#111111' } }, { card: { fill: '#00ff00', text: '#000000' } });
|
|
590
|
+
expect(facts.map((f) => f.channel)).toEqual(['fill', 'text']);
|
|
591
|
+
});
|
|
592
|
+
test('an element/channel with no color signal produces no fact', () => {
|
|
593
|
+
// reference declares a fill the render never exposes → no signal → no fact
|
|
594
|
+
expect(deriveColorFacts({ card: {} }, { card: { fill: '#ff0000' } })).toEqual([]);
|
|
595
|
+
// render has a color the reference never declared → no reference signal → no fact
|
|
596
|
+
expect(deriveColorFacts({ card: { text: '#abcdef' } }, { card: { fill: '#ff0000' } })).toEqual([]);
|
|
597
|
+
// element absent from the reference entirely → no fact
|
|
598
|
+
expect(deriveColorFacts({ extra: { fill: '#ff0000' } }, {})).toEqual([]);
|
|
599
|
+
});
|
|
600
|
+
test('result is order-independent and deterministic (sorted by element id)', () => {
|
|
601
|
+
const a = deriveColorFacts({ b: { fill: '#ff0000' }, a: { fill: '#000000' } }, { a: { fill: '#ffffff' }, b: { fill: '#ff0000' } });
|
|
602
|
+
const b = deriveColorFacts({ a: { fill: '#000000' }, b: { fill: '#ff0000' } }, { b: { fill: '#ff0000' }, a: { fill: '#ffffff' } });
|
|
603
|
+
expect(a).toEqual(b);
|
|
604
|
+
expect(a.map((f) => f.elementId)).toEqual(['a']);
|
|
605
|
+
});
|
|
606
|
+
});
|
|
521
607
|
describe('deriveCopyFacts — rendered vs reference text per element', () => {
|
|
522
608
|
test('identical text produces no fact', () => {
|
|
523
609
|
expect(deriveCopyFacts({ title: '5 EUR off' }, { title: '5 EUR off' })).toEqual([]);
|
|
@@ -572,6 +658,7 @@ describe('buildStructuralBlock — appearance container (Signal C, additive)', (
|
|
|
572
658
|
{ kind: 'element_extra', elementId: 'copy' },
|
|
573
659
|
{ kind: 'element_extra', elementId: 'node-1' },
|
|
574
660
|
],
|
|
661
|
+
rendered: { elementIds: ['banner', 'copy', 'node-1', 'voucher'] },
|
|
575
662
|
});
|
|
576
663
|
// Additive: the existing Signal A facts and Signal B geometry are untouched.
|
|
577
664
|
expect(block.facts).toEqual(buildStructuralBlock(HUB_PROMO_DUMP, HUB_PROMO_REFERENCE, 2).facts);
|
|
@@ -582,7 +669,11 @@ describe('buildStructuralBlock — appearance container (Signal C, additive)', (
|
|
|
582
669
|
baseline: 'figma',
|
|
583
670
|
elementIds: ['node-1', 'banner', 'voucher', 'copy'],
|
|
584
671
|
});
|
|
585
|
-
expect(block.appearance).toEqual({
|
|
672
|
+
expect(block.appearance).toEqual({
|
|
673
|
+
baseline: 'figma',
|
|
674
|
+
facts: [],
|
|
675
|
+
rendered: { elementIds: ['banner', 'copy', 'node-1', 'voucher'] },
|
|
676
|
+
});
|
|
586
677
|
});
|
|
587
678
|
// A dump whose per-node `text` (Signal C render-side enrichment) drives the
|
|
588
679
|
// copy-fact comparison: `title` renders the wrong string, `cta` renders no
|
|
@@ -610,6 +701,7 @@ describe('buildStructuralBlock — appearance container (Signal C, additive)', (
|
|
|
610
701
|
{ kind: 'text_missing', elementId: 'cta', reference: 'Shop now' },
|
|
611
702
|
{ kind: 'text_mismatch', elementId: 'title', rendered: '5 EUR', reference: '5 EUR off' },
|
|
612
703
|
],
|
|
704
|
+
rendered: { elementIds: ['cta', 'debugOverlay', 'title'], text: { title: '5 EUR' } },
|
|
613
705
|
});
|
|
614
706
|
});
|
|
615
707
|
test('an appearanceReference without text → presence only (issue-01 behavior unchanged)', () => {
|
|
@@ -617,7 +709,245 @@ describe('buildStructuralBlock — appearance container (Signal C, additive)', (
|
|
|
617
709
|
baseline: 'figma',
|
|
618
710
|
elementIds: ['title', 'cta', 'debugOverlay'],
|
|
619
711
|
});
|
|
620
|
-
expect(block.appearance).toEqual({
|
|
712
|
+
expect(block.appearance).toEqual({
|
|
713
|
+
baseline: 'figma',
|
|
714
|
+
facts: [],
|
|
715
|
+
rendered: { elementIds: ['cta', 'debugOverlay', 'title'], text: { title: '5 EUR' } },
|
|
716
|
+
});
|
|
717
|
+
});
|
|
718
|
+
// A dump whose per-node fill/text colors (Signal C render-side enrichment)
|
|
719
|
+
// drive the color-fact comparison: `card` renders the wrong fill, correct text.
|
|
720
|
+
const COLOR_DUMP = {
|
|
721
|
+
canvas: { left: 0, top: 0, right: 200, bottom: 400 },
|
|
722
|
+
nodes: [
|
|
723
|
+
{ id: 'card', bounds: { left: 0, top: 0, right: 100, bottom: 40 }, parentId: null, clipsChildren: false, fillColor: '#ff0000', textColor: '#000000' },
|
|
724
|
+
],
|
|
725
|
+
};
|
|
726
|
+
test('with reference color → color facts are appended after presence/copy facts', () => {
|
|
727
|
+
const block = buildStructuralBlock(COLOR_DUMP, null, 2, undefined, {
|
|
728
|
+
baseline: 'figma',
|
|
729
|
+
elementIds: ['card'],
|
|
730
|
+
color: { card: { fill: '#00ff00', text: '#000000' } },
|
|
731
|
+
});
|
|
732
|
+
expect(block.appearance?.baseline).toBe('figma');
|
|
733
|
+
expect(block.appearance?.facts).toEqual([
|
|
734
|
+
{
|
|
735
|
+
kind: 'color',
|
|
736
|
+
elementId: 'card',
|
|
737
|
+
channel: 'fill',
|
|
738
|
+
rendered: '#ff0000',
|
|
739
|
+
reference: '#00ff00',
|
|
740
|
+
deltaE: ciede2000(hexToLab('#ff0000'), hexToLab('#00ff00')),
|
|
741
|
+
},
|
|
742
|
+
]);
|
|
743
|
+
});
|
|
744
|
+
test('an appearanceReference without color → no color facts (presence only)', () => {
|
|
745
|
+
const block = buildStructuralBlock(COLOR_DUMP, null, 2, undefined, {
|
|
746
|
+
baseline: 'figma',
|
|
747
|
+
elementIds: ['card'],
|
|
748
|
+
});
|
|
749
|
+
expect(block.appearance).toEqual({
|
|
750
|
+
baseline: 'figma',
|
|
751
|
+
facts: [],
|
|
752
|
+
rendered: { elementIds: ['card'], color: { card: { fill: '#ff0000', text: '#000000' } } },
|
|
753
|
+
});
|
|
754
|
+
});
|
|
755
|
+
// ---- Signal C no-Figma baseline (issue 04) ----
|
|
756
|
+
test('the appearance container persists a rendered snapshot (the baseline source for the next render)', () => {
|
|
757
|
+
// The snapshot captures THIS render's own element ids + text + colors so a
|
|
758
|
+
// later no-Figma render can diff against it. Text/color are present only for
|
|
759
|
+
// the nodes that expose them.
|
|
760
|
+
const block = buildStructuralBlock(COPY_DUMP, null, 2, undefined, {
|
|
761
|
+
baseline: 'figma',
|
|
762
|
+
elementIds: ['title', 'cta'],
|
|
763
|
+
});
|
|
764
|
+
expect(block.appearance?.rendered).toEqual({
|
|
765
|
+
elementIds: ['cta', 'debugOverlay', 'title'],
|
|
766
|
+
text: { title: '5 EUR' },
|
|
767
|
+
});
|
|
768
|
+
});
|
|
769
|
+
test('a previous_render baseline marks the facts as regressions (drift), derivers unchanged', () => {
|
|
770
|
+
// The same derivers run; only the reference source + baseline marking differ.
|
|
771
|
+
// Reference here is the *previous render*'s ids/text/color.
|
|
772
|
+
const block = buildStructuralBlock(COLOR_DUMP, null, 2, undefined, {
|
|
773
|
+
baseline: 'previous_render',
|
|
774
|
+
elementIds: ['card'],
|
|
775
|
+
color: { card: { fill: '#00ff00' } },
|
|
776
|
+
});
|
|
777
|
+
expect(block.appearance?.baseline).toBe('previous_render');
|
|
778
|
+
expect(block.appearance?.facts).toEqual([
|
|
779
|
+
{
|
|
780
|
+
kind: 'color',
|
|
781
|
+
elementId: 'card',
|
|
782
|
+
channel: 'fill',
|
|
783
|
+
rendered: '#ff0000',
|
|
784
|
+
reference: '#00ff00',
|
|
785
|
+
deltaE: ciede2000(hexToLab('#ff0000'), hexToLab('#00ff00')),
|
|
786
|
+
},
|
|
787
|
+
]);
|
|
788
|
+
});
|
|
789
|
+
test('a previous_render baseline diffs presence against the previous element-id set', () => {
|
|
790
|
+
// COLOR_DUMP renders only `card`; the previous render had `card` + `legacyBadge`.
|
|
791
|
+
const block = buildStructuralBlock(COLOR_DUMP, null, 2, undefined, {
|
|
792
|
+
baseline: 'previous_render',
|
|
793
|
+
elementIds: ['card', 'legacyBadge'],
|
|
794
|
+
});
|
|
795
|
+
expect(block.appearance).toMatchObject({
|
|
796
|
+
baseline: 'previous_render',
|
|
797
|
+
facts: [{ kind: 'element_missing', elementId: 'legacyBadge' }],
|
|
798
|
+
});
|
|
799
|
+
});
|
|
800
|
+
test('no appearanceReference (neither Figma nor previous render) → no container, no rendered snapshot', () => {
|
|
801
|
+
const block = buildStructuralBlock(COLOR_DUMP, null, 2);
|
|
802
|
+
expect(block.appearance).toBeUndefined();
|
|
803
|
+
});
|
|
804
|
+
});
|
|
805
|
+
// ---- Signal C: previous-render → AppearanceReference mapper (issue 01) ----
|
|
806
|
+
//
|
|
807
|
+
// The no-Figma drift path: a previous catalog render persisted its own
|
|
808
|
+
// appearance snapshot (`appearance.rendered`: element ids + per-element colors).
|
|
809
|
+
// This pure mapper turns that snapshot into the `previous_render`
|
|
810
|
+
// AppearanceReference the next render diffs against — the colors/ids to compare,
|
|
811
|
+
// marked as drift (regression vs the last render), not a design divergence. It is
|
|
812
|
+
// the testable core the thin catalog-fetch adapter wraps; no I/O here.
|
|
813
|
+
describe('appearanceReferenceFromPreviousRender — previous render snapshot → reference', () => {
|
|
814
|
+
test('a previous render with per-element fill colors → a previous_render reference carrying color + ids', () => {
|
|
815
|
+
const previous = {
|
|
816
|
+
elementIds: ['banner', 'voucher'],
|
|
817
|
+
color: { banner: { fill: '#fff0ee' } },
|
|
818
|
+
};
|
|
819
|
+
expect(appearanceReferenceFromPreviousRender(previous)).toEqual({
|
|
820
|
+
baseline: 'previous_render',
|
|
821
|
+
elementIds: ['banner', 'voucher'],
|
|
822
|
+
color: { banner: { fill: '#fff0ee' } },
|
|
823
|
+
});
|
|
824
|
+
});
|
|
825
|
+
test('a previous render with no extractable color → a presence-only reference (ids, no color)', () => {
|
|
826
|
+
const previous = { elementIds: ['banner', 'voucher'] };
|
|
827
|
+
expect(appearanceReferenceFromPreviousRender(previous)).toEqual({
|
|
828
|
+
baseline: 'previous_render',
|
|
829
|
+
elementIds: ['banner', 'voucher'],
|
|
830
|
+
});
|
|
831
|
+
});
|
|
832
|
+
test('an empty color map is treated as no color signal (presence-only)', () => {
|
|
833
|
+
const previous = { elementIds: ['banner'], color: {} };
|
|
834
|
+
expect(appearanceReferenceFromPreviousRender(previous)).toEqual({
|
|
835
|
+
baseline: 'previous_render',
|
|
836
|
+
elementIds: ['banner'],
|
|
837
|
+
});
|
|
838
|
+
});
|
|
839
|
+
test('a genuinely absent previous render → null (no appearance container downstream)', () => {
|
|
840
|
+
expect(appearanceReferenceFromPreviousRender(null)).toBeNull();
|
|
841
|
+
expect(appearanceReferenceFromPreviousRender(undefined)).toBeNull();
|
|
842
|
+
expect(appearanceReferenceFromPreviousRender({})).toBeNull();
|
|
843
|
+
});
|
|
844
|
+
test('fed into buildStructuralBlock, a drifted fill produces a previous_render color fact (the tracer)', () => {
|
|
845
|
+
// The render now paints the banner the wrong fill (#1e88e5); the previous
|
|
846
|
+
// render painted #fff0ee. The mapper turns that previous snapshot into the
|
|
847
|
+
// drift reference, and the assembled block carries one fill color fact with a
|
|
848
|
+
// large positive ΔE — exactly the blue-banner divergence, proven through the
|
|
849
|
+
// public interface (the e2e proves the same on a real render).
|
|
850
|
+
const driftedDump = {
|
|
851
|
+
canvas: { left: 0, top: 0, right: 686, bottom: 282 },
|
|
852
|
+
nodes: [
|
|
853
|
+
{ id: 'banner', bounds: { left: 0, top: 0, right: 686, bottom: 282 }, parentId: null, clipsChildren: false, fillColor: '#1e88e5' },
|
|
854
|
+
],
|
|
855
|
+
};
|
|
856
|
+
const previous = { elementIds: ['banner'], color: { banner: { fill: '#fff0ee' } } };
|
|
857
|
+
const reference = appearanceReferenceFromPreviousRender(previous);
|
|
858
|
+
const block = buildStructuralBlock(driftedDump, null, 2, undefined, reference);
|
|
859
|
+
expect(block.appearance?.baseline).toBe('previous_render');
|
|
860
|
+
const colorFacts = (block.appearance?.facts ?? []).filter((f) => f.kind === 'color');
|
|
861
|
+
expect(colorFacts).toEqual([
|
|
862
|
+
{
|
|
863
|
+
kind: 'color',
|
|
864
|
+
elementId: 'banner',
|
|
865
|
+
channel: 'fill',
|
|
866
|
+
rendered: '#1e88e5',
|
|
867
|
+
reference: '#fff0ee',
|
|
868
|
+
deltaE: ciede2000(hexToLab('#1e88e5'), hexToLab('#fff0ee')),
|
|
869
|
+
},
|
|
870
|
+
]);
|
|
871
|
+
expect(colorFacts[0].kind === 'color' && colorFacts[0].deltaE).toBeGreaterThan(10);
|
|
872
|
+
});
|
|
873
|
+
});
|
|
874
|
+
// ---- Signal C: build the appearance reference from run params (issue 05) ----
|
|
875
|
+
//
|
|
876
|
+
// The runner builds the appearanceReference from the per-screen reference_geometry
|
|
877
|
+
// / reference_text / reference_color params. Issue 05 decouples the container from
|
|
878
|
+
// reference_geometry: it is assembled when ANY of the three is present, with
|
|
879
|
+
// elementIds = the UNION of their keys, so a run with reference_color but no
|
|
880
|
+
// reference_geometry still emits color facts.
|
|
881
|
+
describe('buildAppearanceReferenceFromParams — union of geometry/text/color ids', () => {
|
|
882
|
+
test('color only (no geometry) → a reference carrying color, ids from the color keys', () => {
|
|
883
|
+
const ref = buildAppearanceReferenceFromParams({
|
|
884
|
+
refColor: { banner: { fill: '#fff0ee' } },
|
|
885
|
+
baseline: 'previous_render',
|
|
886
|
+
});
|
|
887
|
+
expect(ref).toEqual({
|
|
888
|
+
baseline: 'previous_render',
|
|
889
|
+
elementIds: ['banner'],
|
|
890
|
+
color: { banner: { fill: '#fff0ee' } },
|
|
891
|
+
});
|
|
892
|
+
});
|
|
893
|
+
test('geometry only → ids from the geometry keys, no text/color attached', () => {
|
|
894
|
+
const ref = buildAppearanceReferenceFromParams({
|
|
895
|
+
refGeom: { banner: { w: 343, h: 96 }, voucher: { w: 81, h: 81 } },
|
|
896
|
+
baseline: 'figma',
|
|
897
|
+
});
|
|
898
|
+
expect(ref).toEqual({ baseline: 'figma', elementIds: ['banner', 'voucher'] });
|
|
899
|
+
});
|
|
900
|
+
test('geometry + color (color ids ⊆ geometry ids) → ids unchanged (additive, no regression)', () => {
|
|
901
|
+
const ref = buildAppearanceReferenceFromParams({
|
|
902
|
+
refGeom: { banner: { w: 343, h: 96 }, voucher: { w: 81, h: 81 } },
|
|
903
|
+
refColor: { banner: { fill: '#fff0ee' } },
|
|
904
|
+
baseline: 'figma',
|
|
905
|
+
});
|
|
906
|
+
expect(ref).toEqual({
|
|
907
|
+
baseline: 'figma',
|
|
908
|
+
elementIds: ['banner', 'voucher'],
|
|
909
|
+
color: { banner: { fill: '#fff0ee' } },
|
|
910
|
+
});
|
|
911
|
+
});
|
|
912
|
+
test('text + color, no geometry → union ids, both attached', () => {
|
|
913
|
+
const ref = buildAppearanceReferenceFromParams({
|
|
914
|
+
refText: { copy: 'Get 5 € off' },
|
|
915
|
+
refColor: { banner: { fill: '#fff0ee' } },
|
|
916
|
+
baseline: 'previous_render',
|
|
917
|
+
});
|
|
918
|
+
expect(ref).toEqual({
|
|
919
|
+
baseline: 'previous_render',
|
|
920
|
+
elementIds: ['copy', 'banner'],
|
|
921
|
+
text: { copy: 'Get 5 € off' },
|
|
922
|
+
color: { banner: { fill: '#fff0ee' } },
|
|
923
|
+
});
|
|
924
|
+
});
|
|
925
|
+
test('none present → null (no appearance container)', () => {
|
|
926
|
+
expect(buildAppearanceReferenceFromParams({ baseline: 'figma' })).toBeNull();
|
|
927
|
+
expect(buildAppearanceReferenceFromParams({ baseline: 'figma', refGeom: {}, refColor: {}, refText: {} })).toBeNull();
|
|
928
|
+
});
|
|
929
|
+
test('fed into buildStructuralBlock, a color-only reference still emits the color fact', () => {
|
|
930
|
+
const dump = {
|
|
931
|
+
canvas: { left: 0, top: 0, right: 686, bottom: 282 },
|
|
932
|
+
nodes: [
|
|
933
|
+
{ id: 'banner', bounds: { left: 0, top: 0, right: 686, bottom: 282 }, parentId: null, clipsChildren: false, fillColor: '#1e88e5' },
|
|
934
|
+
],
|
|
935
|
+
};
|
|
936
|
+
const ref = buildAppearanceReferenceFromParams({
|
|
937
|
+
refColor: { banner: { fill: '#fff0ee' } },
|
|
938
|
+
baseline: 'previous_render',
|
|
939
|
+
});
|
|
940
|
+
const block = buildStructuralBlock(dump, null, 2, undefined, ref);
|
|
941
|
+
expect(block.appearance?.facts).toEqual([
|
|
942
|
+
{
|
|
943
|
+
kind: 'color',
|
|
944
|
+
elementId: 'banner',
|
|
945
|
+
channel: 'fill',
|
|
946
|
+
rendered: '#1e88e5',
|
|
947
|
+
reference: '#fff0ee',
|
|
948
|
+
deltaE: ciede2000(hexToLab('#1e88e5'), hexToLab('#fff0ee')),
|
|
949
|
+
},
|
|
950
|
+
]);
|
|
621
951
|
});
|
|
622
952
|
});
|
|
623
953
|
describe('embedded geometry stage parity', () => {
|
|
@@ -676,6 +1006,59 @@ describe('embedded geometry stage parity', () => {
|
|
|
676
1006
|
};
|
|
677
1007
|
expect(embedded.buildStructuralBlock(dumpWithText, null, 2, undefined, appearanceReference)).toEqual(buildStructuralBlock(dumpWithText, null, 2, undefined, appearanceReference));
|
|
678
1008
|
});
|
|
1009
|
+
test('embedded ciede2000 + hexToLab match the module (Signal C)', () => {
|
|
1010
|
+
const labCases = [
|
|
1011
|
+
[[50, 2.6772, -79.7751], [50, 0, -82.7485]],
|
|
1012
|
+
[[50, 2.5, 0], [73, 25, -18]],
|
|
1013
|
+
[[60.2574, -34.0099, 36.2677], [60.4626, -34.1751, 39.4387]],
|
|
1014
|
+
];
|
|
1015
|
+
for (const [a, b] of labCases) {
|
|
1016
|
+
expect(embedded.ciede2000(a, b)).toBeCloseTo(ciede2000(a, b), 12);
|
|
1017
|
+
}
|
|
1018
|
+
for (const hex of ['#ffffff', '#000000', '#ff0000', '#3a7bd5', 'abcdef']) {
|
|
1019
|
+
expect(embedded.hexToLab(hex)).toEqual(hexToLab(hex));
|
|
1020
|
+
}
|
|
1021
|
+
});
|
|
1022
|
+
test('embedded buildAppearanceReferenceFromParams matches the module (Signal C, issue 05)', () => {
|
|
1023
|
+
const cases = [
|
|
1024
|
+
{ refColor: { banner: { fill: '#fff0ee' } }, baseline: 'previous_render' },
|
|
1025
|
+
{ refGeom: { banner: { w: 343, h: 96 }, voucher: { w: 81, h: 81 } }, baseline: 'figma' },
|
|
1026
|
+
{ refGeom: { banner: { w: 343 } }, refColor: { banner: { fill: '#fff0ee' } }, baseline: 'figma' },
|
|
1027
|
+
{ refText: { copy: 'Get 5 € off' }, refColor: { banner: { fill: '#fff0ee' } }, baseline: 'previous_render' },
|
|
1028
|
+
{ refGeom: { banner: { w: 1 } }, refText: { copy: 'x' }, refColor: { logo: { fill: '#000000' } }, baseline: 'figma' },
|
|
1029
|
+
{ baseline: 'figma' },
|
|
1030
|
+
{ refGeom: {}, refText: {}, refColor: {}, baseline: 'figma' },
|
|
1031
|
+
];
|
|
1032
|
+
for (const c of cases) {
|
|
1033
|
+
expect(embedded.buildAppearanceReferenceFromParams(c)).toEqual(buildAppearanceReferenceFromParams(c));
|
|
1034
|
+
}
|
|
1035
|
+
});
|
|
1036
|
+
test('embedded deriveColorFacts matches the module (Signal C)', () => {
|
|
1037
|
+
const cases = [
|
|
1038
|
+
[{ card: { fill: '#ff0000' } }, { card: { fill: '#ff0000' } }],
|
|
1039
|
+
[{ card: { fill: '#ff0000' } }, { card: { fill: '#00ff00' } }],
|
|
1040
|
+
[{ card: { fill: '#ffffff', text: '#111111' } }, { card: { fill: '#ffffff', text: '#000000' } }],
|
|
1041
|
+
[{ card: {} }, { card: { fill: '#ff0000' } }],
|
|
1042
|
+
[{ extra: { fill: '#ff0000' } }, {}],
|
|
1043
|
+
];
|
|
1044
|
+
for (const [rendered, reference] of cases) {
|
|
1045
|
+
expect(embedded.deriveColorFacts(rendered, reference)).toEqual(deriveColorFacts(rendered, reference));
|
|
1046
|
+
}
|
|
1047
|
+
});
|
|
1048
|
+
test('embedded buildStructuralBlock matches the module with an appearanceReference carrying color', () => {
|
|
1049
|
+
const dumpWithColor = {
|
|
1050
|
+
canvas: { left: 0, top: 0, right: 200, bottom: 400 },
|
|
1051
|
+
nodes: [
|
|
1052
|
+
{ id: 'card', bounds: { left: 0, top: 0, right: 100, bottom: 40 }, parentId: null, clipsChildren: false, fillColor: '#ff0000', textColor: '#000000' },
|
|
1053
|
+
],
|
|
1054
|
+
};
|
|
1055
|
+
const appearanceReference = {
|
|
1056
|
+
baseline: 'figma',
|
|
1057
|
+
elementIds: ['card'],
|
|
1058
|
+
color: { card: { fill: '#00ff00', text: '#000000' } },
|
|
1059
|
+
};
|
|
1060
|
+
expect(embedded.buildStructuralBlock(dumpWithColor, null, 2, undefined, appearanceReference)).toEqual(buildStructuralBlock(dumpWithColor, null, 2, undefined, appearanceReference));
|
|
1061
|
+
});
|
|
679
1062
|
const parityCases = [
|
|
680
1063
|
{ name: 'factsOnly', dump: HUB_PROMO_DUMP, ref: null },
|
|
681
1064
|
{ name: 'withGeometry', dump: HUB_PROMO_DUMP, ref: HUB_PROMO_REFERENCE },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-fidelity-render-android.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/ui-fidelity-render-android.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAKpE,sDAAsD;AACtD,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAE1D,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAEzD,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,8EAA8E;AAC9E,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;
|
|
1
|
+
{"version":3,"file":"ui-fidelity-render-android.d.ts","sourceRoot":"","sources":["../../../../src/yaml/steps/ui-fidelity-render-android.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAKpE,sDAAsD;AACtD,MAAM,WAAW,6BAA6B;IAC5C;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,eAAO,MAAM,mBAAmB,yBAAyB,CAAC;AAE1D,gFAAgF;AAChF,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AAEzD,4DAA4D;AAC5D,eAAO,MAAM,gBAAgB,0BAA0B,CAAC;AAExD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD;AAED,8EAA8E;AAC9E,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;CACpB;AA8xBD;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,yBAAyB,GAAG,MAAM,CAYrF;AAED;;;GAGG;AACH,qBAAa,mCAAoC,SAAQ,gBAAgB;IACvE,yBAAyB,CACvB,OAAO,EAAE,6BAA6B,EACtC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,QAAQ,GAChB,qBAAqB,EAAE;IAepB,OAAO,CACX,MAAM,EAAE,6BAA6B,EACrC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,EAAE,QAAQ,GAChB,OAAO,CAAC,OAAO,CAAC;CAgBpB"}
|