You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add full resolved Flex-token snapshots to the design package for every
supported appearance and platform, matching the coverage that the legacy default-theme package already provides for Fluent themes. Commit the snapshot
files alongside the tests and define an explicit update policy so token-value
changes are always surfaced in PR diffs and reviewed intentionally.
The design package currently has no snapshot of the resolved FlexTokens
object for any appearance. This gap means a codegen or mapping change that
silently shifts a token value cannot be detected by CI.
Goal
Produce one committed Jest snapshot per appearance and platform that captures
the complete resolved FlexTokens object, written with toMatchSnapshot() so
the test source contains no duplicated literal values and the .snap files are
the single authoritative record. Define and document the update policy so teams
know when a snapshot update is safe and what reviewing a diff requires.
Stage
Stage 2 - Beta delivery. The snapshots are only meaningful once Default Values Codegen generates the
per-appearance value sets they will capture.
Why it matters
Observed. The legacy default-theme package has per-platform snapshot
files for the resolved Fluent theme at every appearance: packages/theming/default-theme/src/__tests__
contains defaultThemes.test.win32.ts, defaultThemes.test.macos.ts, defaultThemes.test.ios.ts, defaultThemes.test.windows.ts, and defaultThemes.test.android.ts, each calling toMatchSnapshot() for the
light, dark, and high-contrast themes it exports.
Observed. The design package has no equivalent. Its current token tests, flex.test.ts
and flexTokensFromTheme.test.ts,
contain spot assertions against named literal values. They verify a small
number of tokens and cannot detect a silent shift elsewhere in the resolved
set.
Observed.defaultTokens.ts is 473 lines and contains 249 color
literals with only 80 distinct values
(packages/agentic/design/src/tokens/defaultTokens.ts); Default Values Codegen will replace it with
generated output. Without a before-and-after snapshot comparison, a codegen
bug that shifts a single color value in one appearance would not be caught
by any existing test.
Observed.codegen.cts currently generates only one appearance per
platform (e.g., win32/colorful and macos/light)
(packages/agentic/design/scripts/codegen.cts).
Once codegen is extended to emit all appearances, there is no test harness
to assert those additional sets are correct.
Inferred. Snapshots in PR diffs are the lowest-friction way to make
cross-appearance token changes visible to reviewers. A value that differs
between a colorful and a darkgray appearance will appear in the diff
only if both are captured.
Observed current state
Observed. The design package's Jest platform is macos by default
("furn": { "jestPlatform": "macos" } in packages/agentic/design/package.json).
Tests run with @rnx-kit/jest-preset via scripts/configs/jest/jest.config.cjs,
which selects a React Native platform and resolves platform-suffixed modules
accordingly.
Observed. Platform-specific test files use the .test.<platform>.ts
suffix convention, as demonstrated by the legacy package files and
recognized by the @rnx-kit/jest-preset runner.
Observed.AppearanceOptions in the design package is 'light' | 'dark' | 'darkElevated' | 'highContrast'
(packages/agentic/design/src/theming/types/Theme.types.ts).
The installed @fluentui-react-native/design-tokens-macos package ships light, dark, hclight, and hcdark variants, and @fluentui-react-native/design-tokens-win32 ships colorful, darkgray, hc, and black; these do not map one-to-one to AppearanceOptions.
Observed.flexTokensFromTheme derives Flex token values from a Fluent Theme via a declarative lookup table and is tested with value assertions
against a hand-constructed mock theme
(flexTokensFromTheme.test.ts).
That test covers the projection path but not the per-appearance shape of
the resolved defaults.
Observed. The design package's package.json already includes an update-snapshots script (fluentui-scripts jest -u), so the runner
infrastructure is in place.
Observed. Legacy snapshot test files in default-theme use toMatchSnapshot() without any embedded literal values in the test source;
all resolved values live only in the committed .snap files alongside each
test file.
Scope
Add snapshot tests to the design package that call toMatchSnapshot() on
the full resolved FlexTokens object for every supported appearance and
platform. Test source must not embed literal token values; the .snap files
are the only record of resolved values.
Follow the .test.<platform>.ts file naming convention used by the legacy
packages so the Jest platform runner can load the correct React Native fork
for each file.
Cover, at minimum: win32 (colorful/light, darkgray/dark, hc/high-contrast,
black/dark-alternate), macos (light, dark, hclight, hcdark), windows
(light, dark), ios (light), and android (light). The exact
appearance-to-AppearanceOptions mapping is resolved by System Appearance Handling and Default Values Codegen; the snapshot files
must be updated to match once that mapping is stable.
Commit all .snap files in the repository alongside the test files so they
appear in CI diff output when token values change.
Define and document the update policy: when an intentional token change is
made (e.g., by regenerating defaults), the author runs yarn update-snapshots
in the design package, reviews the diff to confirm only expected tokens
changed, and commits the updated .snap files with the same change. An
unreviewed snapshot update is a regression indicator.
Add a note to the codegen task's change protocol that a defaultTokens
regeneration requires re-running yarn update-snapshots.
Snapshotting the legacy Fluent Theme shape; the legacy packages already
own that coverage.
Snapshotting component render output; those are component-level concerns.
Automated detection of mapping file drift; see the combined drift detection
task that covers both flex-token-map.yaml and upstream x3 pins.
Deliverables
Per-platform snapshot test files in the design package, one per platform
(defaultFlexTokens.test.win32.ts, defaultFlexTokens.test.macos.ts, defaultFlexTokens.test.windows.ts, defaultFlexTokens.test.ios.ts, defaultFlexTokens.test.android.ts), each exercising all appearances
available for that platform.
Initial committed .snap files generated from the current resolved
defaults plus each generated per-appearance set once Default Values Codegen lands.
A documented update policy in the design package's CONTRIBUTING.md or
inline in the test source, covering when and how to run yarn update-snapshots and what constitutes a safe diff to commit.
A note in the Default Values Codegen task
acceptance criteria requiring that its first generation pass produces
snapshot files with no unexpected value changes.
Changesets for the design package.
Acceptance criteria
One .test.<platform>.ts file exists for each of win32, macos, windows,
ios, and android, and each calls toMatchSnapshot() on the fully
resolved FlexTokens for every appearance that platform supports.
No test source file embeds literal token values; all resolved values are
in .snap files only.
All .snap files are committed to the repository and appear in CI diff
output when token values change.
Running yarn test in the design package with no code changes passes
cleanly, confirming the committed snapshots match the current resolved
values.
A flexTokens change that shifts a single color value in any appearance
causes exactly those snapshot entries to fail and no others.
The update procedure (yarn update-snapshots -> diff review -> commit)
is documented and produces a reproducible result, verified by re-running yarn test after the snapshot update.
yarn build, yarn lage test, and yarn lage lint pass at the
repository root, and changesets are present.
Dependencies and ordering
Depends on Dynamic Theme Building. The
snapshot tests exercise per-appearance FlexTokens resolution, which
requires the context-aware useFlexTokens that this task defines. Without
that, all appearances would snapshot identically.
Depends on Default Values Codegen. The
per-appearance token sets being snapshotted are generated by this task. The
initial snapshot files should be generated and committed as part of the same
change that lands the codegen output, so the first committed snapshots are
known-correct against the generated values.
Pairs with System Appearance Handling. The
appearance-to-AppearanceOptions mapping determines which appearances each
platform test file must cover. The snapshot coverage list should be
finalized once that mapping is stable.
Does not block any other task in this workstream but provides regression
protection for all subsequent token-value changes.
Risks and open decisions
Open decision. Which appearance names each platform snapshot file should
use as test-case labels. Observed: the design-tokens packages use
appearance names from the token package (e.g., colorful, darkgray) while AppearanceOptions uses light, dark, highContrast. Whether the test
labels follow the token package names, the AppearanceOptions names, or
both depends on the resolution in System Appearance Handling.
Open decision. Whether darkElevated and black (win32) map to the
same snapshot or require distinct entries. Observed:getAliasTokens
folds darkElevated into the dark branch
(packages/theming/theme-tokens/src/getTokens.ts),
but win32 black is a distinct token set; the snapshot strategy must reflect
whatever the codegen emits.
Open decision. Whether the snapshot tests should use the context path
(injecting a ThemeProvider in a test renderer) or call the default export
functions directly. Inferred: the legacy tests snapshot exported
constants, not a rendered tree; the same pattern is simpler and avoids
React-tree overhead for a token-value test.
Risk. If snapshots are introduced before Default Values Codegen
lands, they will capture the current hand-authored single-appearance defaults
and will need a full re-generation pass when codegen lands. Introducing them
in the same change as the codegen output is strongly preferred to avoid a
transitional state where snapshots exist but are known to be incomplete.
Risk. A snapshot file that is too large to review in a PR diff becomes
rubber-stamped rather than reviewed. The FlexTokens object has nine groups
and roughly 300 token paths; at roughly 5 bytes per value, a single-appearance
snapshot is around 1,500 characters, which is reviewable. Per-appearance
files keep each snapshot small enough to inspect.
Risk. Snapshot tests are only as stable as the Jest platform and module
resolver configuration. The design package pins its Jest platform to macos;
running yarn test on a developer machine with a different platform override
will pick up the wrong platform-suffixed file. The update policy must state
that yarn update-snapshots must be run per platform or through CI to avoid
committing host-machine artifacts.
Evidence and references
packages/theming/default-theme/src/__tests__:
the legacy snapshot pattern this task matches, with one .test.<platform>.ts
file per platform and toMatchSnapshot() for each appearance export.
Summary
Add full resolved Flex-token snapshots to the design package for every
supported appearance and platform, matching the coverage that the legacy
default-themepackage already provides for Fluent themes. Commit the snapshotfiles alongside the tests and define an explicit update policy so token-value
changes are always surfaced in PR diffs and reviewed intentionally.
The design package currently has no snapshot of the resolved
FlexTokensobject for any appearance. This gap means a codegen or mapping change that
silently shifts a token value cannot be detected by CI.
Goal
Produce one committed Jest snapshot per appearance and platform that captures
the complete resolved
FlexTokensobject, written withtoMatchSnapshot()sothe test source contains no duplicated literal values and the
.snapfiles arethe single authoritative record. Define and document the update policy so teams
know when a snapshot update is safe and what reviewing a diff requires.
Stage
Stage 2 - Beta delivery. The snapshots are only meaningful once
Default Values Codegen generates the
per-appearance value sets they will capture.
Why it matters
default-themepackage has per-platform snapshotfiles for the resolved Fluent theme at every appearance:
packages/theming/default-theme/src/__tests__contains
defaultThemes.test.win32.ts,defaultThemes.test.macos.ts,defaultThemes.test.ios.ts,defaultThemes.test.windows.ts, anddefaultThemes.test.android.ts, each callingtoMatchSnapshot()for thelight, dark, and high-contrast themes it exports.
flex.test.tsand
flexTokensFromTheme.test.ts,contain spot assertions against named literal values. They verify a small
number of tokens and cannot detect a silent shift elsewhere in the resolved
set.
defaultTokens.tsis 473 lines and contains 249 colorliterals with only 80 distinct values
(
packages/agentic/design/src/tokens/defaultTokens.ts);Default Values Codegen will replace it with
generated output. Without a before-and-after snapshot comparison, a codegen
bug that shifts a single color value in one appearance would not be caught
by any existing test.
codegen.ctscurrently generates only one appearance perplatform (e.g.,
win32/colorfulandmacos/light)(
packages/agentic/design/scripts/codegen.cts).Once codegen is extended to emit all appearances, there is no test harness
to assert those additional sets are correct.
cross-appearance token changes visible to reviewers. A value that differs
between a
colorfuland adarkgrayappearance will appear in the diffonly if both are captured.
Observed current state
macosby default(
"furn": { "jestPlatform": "macos" }inpackages/agentic/design/package.json).Tests run with
@rnx-kit/jest-presetviascripts/configs/jest/jest.config.cjs,which selects a React Native platform and resolves platform-suffixed modules
accordingly.
.test.<platform>.tssuffix convention, as demonstrated by the legacy package files and
recognized by the
@rnx-kit/jest-presetrunner.AppearanceOptionsin the design package is'light' | 'dark' | 'darkElevated' | 'highContrast'(
packages/agentic/design/src/theming/types/Theme.types.ts).The installed
@fluentui-react-native/design-tokens-macospackage shipslight,dark,hclight, andhcdarkvariants, and@fluentui-react-native/design-tokens-win32shipscolorful,darkgray,hc, andblack; these do not map one-to-one toAppearanceOptions.useFlexTokensreturnsdefaultFlexTokensunconditionallyand ignores context
(
packages/agentic/design/src/tokens/useFlexTokens.ts),so there is currently no per-appearance resolution to snapshot.
flexTokensFromThemederives Flex token values from a FluentThemevia a declarative lookup table and is tested with value assertionsagainst a hand-constructed mock theme
(
flexTokensFromTheme.test.ts).That test covers the projection path but not the per-appearance shape of
the resolved defaults.
package.jsonalready includes anupdate-snapshotsscript (fluentui-scripts jest -u), so the runnerinfrastructure is in place.
default-themeusetoMatchSnapshot()without any embedded literal values in the test source;all resolved values live only in the committed
.snapfiles alongside eachtest file.
Scope
toMatchSnapshot()onthe full resolved
FlexTokensobject for every supported appearance andplatform. Test source must not embed literal token values; the
.snapfilesare the only record of resolved values.
.test.<platform>.tsfile naming convention used by the legacypackages so the Jest platform runner can load the correct React Native fork
for each file.
win32(colorful/light, darkgray/dark, hc/high-contrast,black/dark-alternate),
macos(light, dark, hclight, hcdark),windows(light, dark),
ios(light), andandroid(light). The exactappearance-to-
AppearanceOptionsmapping is resolved bySystem Appearance Handling and
Default Values Codegen; the snapshot files
must be updated to match once that mapping is stable.
.snapfiles in the repository alongside the test files so theyappear in CI diff output when token values change.
made (e.g., by regenerating defaults), the author runs
yarn update-snapshotsin the design package, reviews the diff to confirm only expected tokens
changed, and commits the updated
.snapfiles with the same change. Anunreviewed snapshot update is a regression indicator.
defaultTokensregeneration requires re-running
yarn update-snapshots.Out of scope
Default Values Codegen.
System Appearance Handling.
Themeshape; the legacy packages alreadyown that coverage.
task that covers both
flex-token-map.yamland upstream x3 pins.Deliverables
(
defaultFlexTokens.test.win32.ts,defaultFlexTokens.test.macos.ts,defaultFlexTokens.test.windows.ts,defaultFlexTokens.test.ios.ts,defaultFlexTokens.test.android.ts), each exercising all appearancesavailable for that platform.
.snapfiles generated from the current resolveddefaults plus each generated per-appearance set once
Default Values Codegen lands.
CONTRIBUTING.mdorinline in the test source, covering when and how to run
yarn update-snapshotsand what constitutes a safe diff to commit.acceptance criteria requiring that its first generation pass produces
snapshot files with no unexpected value changes.
Acceptance criteria
.test.<platform>.tsfile exists for each of win32, macos, windows,ios, and android, and each calls
toMatchSnapshot()on the fullyresolved
FlexTokensfor every appearance that platform supports.in
.snapfiles only..snapfiles are committed to the repository and appear in CI diffoutput when token values change.
yarn testin the design package with no code changes passescleanly, confirming the committed snapshots match the current resolved
values.
flexTokenschange that shifts a single color value in any appearancecauses exactly those snapshot entries to fail and no others.
yarn update-snapshots-> diff review -> commit)is documented and produces a reproducible result, verified by re-running
yarn testafter the snapshot update.yarn build,yarn lage test, andyarn lage lintpass at therepository root, and changesets are present.
Dependencies and ordering
snapshot tests exercise per-appearance
FlexTokensresolution, whichrequires the context-aware
useFlexTokensthat this task defines. Withoutthat, all appearances would snapshot identically.
per-appearance token sets being snapshotted are generated by this task. The
initial snapshot files should be generated and committed as part of the same
change that lands the codegen output, so the first committed snapshots are
known-correct against the generated values.
appearance-to-
AppearanceOptionsmapping determines which appearances eachplatform test file must cover. The snapshot coverage list should be
finalized once that mapping is stable.
protection for all subsequent token-value changes.
Risks and open decisions
use as test-case labels. Observed: the design-tokens packages use
appearance names from the token package (e.g.,
colorful,darkgray) whileAppearanceOptionsuseslight,dark,highContrast. Whether the testlabels follow the token package names, the
AppearanceOptionsnames, orboth depends on the resolution in System Appearance Handling.
darkElevatedandblack(win32) map to thesame snapshot or require distinct entries. Observed:
getAliasTokensfolds
darkElevatedinto the dark branch(
packages/theming/theme-tokens/src/getTokens.ts),but win32
blackis a distinct token set; the snapshot strategy must reflectwhatever the codegen emits.
(injecting a
ThemeProviderin a test renderer) or call the default exportfunctions directly. Inferred: the legacy tests snapshot exported
constants, not a rendered tree; the same pattern is simpler and avoids
React-tree overhead for a token-value test.
lands, they will capture the current hand-authored single-appearance defaults
and will need a full re-generation pass when codegen lands. Introducing them
in the same change as the codegen output is strongly preferred to avoid a
transitional state where snapshots exist but are known to be incomplete.
rubber-stamped rather than reviewed. The
FlexTokensobject has nine groupsand roughly 300 token paths; at roughly 5 bytes per value, a single-appearance
snapshot is around 1,500 characters, which is reviewable. Per-appearance
files keep each snapshot small enough to inspect.
resolver configuration. The design package pins its Jest platform to
macos;running
yarn teston a developer machine with a different platform overridewill pick up the wrong platform-suffixed file. The update policy must state
that
yarn update-snapshotsmust be run per platform or through CI to avoidcommitting host-machine artifacts.
Evidence and references
packages/theming/default-theme/src/__tests__:the legacy snapshot pattern this task matches, with one
.test.<platform>.tsfile per platform and
toMatchSnapshot()for each appearance export.packages/theming/default-theme/src/__tests__/default-theme.test.ts:the platform-neutral test that snapshots
createColorAliasTokensandcreateShadowAliasTokensperAppearanceOptions, analogous to what the newtests should do for
FlexTokens.packages/theming/default-theme/src/__tests__/defaultThemes.test.win32.ts:three-appearance win32 snapshot file, illustrating the minimal test shape.
packages/agentic/design/src/tokens/flex.test.ts:current spot-assertion tests for
defaultFlexTokens, which the new snapshottests supplement but do not replace.
packages/agentic/design/src/tokens/flexTokensFromTheme.test.ts:projection test that remains the canonical coverage for the Fluent-to-Flex
mapping path.
packages/agentic/design/src/tokens/defaultTokens.ts:the current single-appearance hand-authored defaults that the snapshots will
initially capture.
packages/agentic/design/scripts/codegen.cts:the codegen entry point that will emit the per-appearance sets the snapshots
will cover once extended.
packages/agentic/design/package.json:the
update-snapshotsscript andfurn.jestPlatformsetting.scripts/configs/jest/jest.config.cjs:platform selection and
.test.<platform>.tsresolution logic.packages/theming/theme-tokens/src/getTokens.ts:AppearanceOptionsconsumer withassertNever; illustrates the currentappearance-to-token-set mapping in the legacy path.
the per-appearance
FlexTokenssets these snapshots will capture.useFlexTokenscontext-aware and enables per-appearance resolution.the stable
AppearanceOptions-to-platform-variant mapping.