Skip to content

Flows: compare two runs of a flows file checkpoint by checkpoint (compare:flows) - #78

Draft
brentvatne wants to merge 1 commit into
@brent/capture-strategies-modularfrom
@brent/flow-compare
Draft

brentvatne wants to merge 1 commit into
@brent/capture-strategies-modularfrom
@brent/flow-compare

Conversation

@brentvatne

Copy link
Copy Markdown
Member

What and why

A flows run records named checkpoints so that two runs line up step by step (#74), but nothing paired them. This adds the comparison:

npx @expo/explore compare:flows --before <run dir> --after <run dir> [--output FILE]
  • Pairing. It pairs the two runs' checkpoints by flow name and checkpoint name, ignoring case, as the flows file compares them (src/contracts/flow-comparison.ts, a pure function).
  • Diffing. It diffs each pair with the review's screenshot diff, and sets aside the status bar and home indicator as a review does (src/review/flow-comparison.ts).
  • Verdicts. Each checkpoint comes back as:
    • unchanged;
    • changed, with the regions that differ;
    • missing, with why one side has no picture;
    • different-size, for another device or orientation, so it isn't diffed;
    • added or removed, when only one run's flows file has it.
  • Differences between the runs are listed, not refused. The result lists how the two runs were captured differently: the app, platform, device, OS version, locale, orientation and appearance. The README promises that an iPhone run and an Android run line up, so refusing those would break it.
  • Foldables. A run doesn't record which panel was in use, so on a foldable the status bar is not set aside, and the result says so.

cli now imports review. That points down a layer, as the dependency rule allows, and ARCHITECTURE lists it.

The output is JSON for now. A step-by-step view in the Viewer is a separate step.

Screenshots

Live demo on euxy: https://explore-flows-compare.expo.app

The same flows file was run on two euxy builds, then compared:

  • Before: main (07d5aab). Full report
  • After: the Explore 0.21.0 test build (d43c586c), which changes four labels. Full report

Results:

  • Settings › Settings: changed, 0.21% of pixels. One region (x 8–35%, y 62–64%), exactly the "Latency offset" → "Output latency" label.
  • The other four checkpoints: unchanged. On main, the Settings screenshot shows the Dynamic Island in the status bar and the other doesn't; that difference is set aside.
  • Patterns: the build's "Restore factory presets" → "Restore the factory presets" change is at the bottom of the list, below the first screenful the checkpoint photographs, so unchanged is correct there.
  • The device picker and the share sheet also changed, but no flow visits them.

The demo page is a one-off static page made from the JSON. It is not part of this PR.

Code examples

{
  "flow": "Settings", "checkpoint": "Settings",
  "before": { "observationId": "obs_…", "screenshot": "assets/….png" },
  "after": { "observationId": "obs_…", "screenshot": "assets/….png" },
  "verdict": "changed", "mismatchPercentage": 0.21,
  "regions": [{ "x": 8.21, "y": 62.01, "width": 26.37, "height": 1.83 }]
}

Try it

npx @expo/explore explore:binary ./build-a.tar.gz --simulator local --flows flows.json --output run-a
npx @expo/explore explore:binary ./build-b.tar.gz --simulator local --flows flows.json --output run-b
npx @expo/explore compare:flows --before run-a --after run-b --output comparison.json

Testing

  • test/node/flow-comparison.test.mjs (6 tests):
    • pairing by name, ignoring case and in order, including checkpoints on one side only;
    • conditions listed;
    • every verdict, with only same-size pairs diffed;
    • a status-bar-only difference set aside;
    • the foldable note;
    • the CLI reading two output directories and refusing a run without flows.
  • Each part was broken on purpose, and a test fails.
  • On real runs:
    • two runs of the same euxy build give 5 of 5 unchanged;
    • a copy with a block painted onto one screenshot gives that checkpoint changed, with the region where it was painted;
    • the two-build demo above.
  • npm test passes (1740 tests), tsc is clean, and lint shows only the 6 existing Viewer warnings.

🤖 Generated with Claude Code

…pare:flows)

compare:flows --before DIR --after DIR [--output FILE] pairs the checkpoints of two runs by
flow and checkpoint name and diffs each pair with the review's screenshot diff, setting aside
the status bar and home indicator as a review does. Each checkpoint is unchanged, changed
(with the regions that differ), missing (no picture on one side, with why), different-size
(another device or orientation, so not diffed), added or removed.

The runs' conditions that differ (app, platform, device, OS version, locale, orientation,
appearance) are listed rather than refused, so an iPhone run and an Android run still line
up. On a foldable the status bar is not set aside, because a run does not record which panel
was in use; the result says so.

The pairing is a pure function in contracts/flow-comparison.ts; the diff is in
review/flow-comparison.ts. cli now imports review, which ARCHITECTURE lists.
@github-actions

Copy link
Copy Markdown

Viewer preview of d6b9733 · reports from brentvatne/euxy#163

Report Changes Open
Android · sdk_gphone64_x86_64 15.0 5 Map · Screens · Compare
iPhone 17 · iPhone 17 26.5 · light + dark 11 Map · Screens · Compare
iPhone Duo (closed) · iPhone Duo 27.1 · light + dark 34 Map · Screens · Compare
iPhone Duo (open) · iPhone Duo 27.1 · light + dark 34 Map · Screens · Compare

Going live: this link can take up to 5 minutes to show d6b9733; until then it shows the previous push, or nothing on a new pull request. This push's deployment is live now.

The link stays the same on every push. Deploy run

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant