fix(mock): do not persist snapshots on close in playback mode#5359
Merged
metcoder95 merged 1 commit intoJun 5, 2026
Merged
Conversation
SnapshotAgent.close() unconditionally delegated to the recorder's close(), which saves to disk whenever any snapshots are held, regardless of mode. In playback mode, findSnapshot() mutates each matched snapshot's callCount on every match, so closing a playback agent rewrote the snapshot file even though nothing new was recorded. This produced spurious diffs in committed fixtures (and persisted callCount values, which loadSnapshots() does not reset). Gate persistence at close() — the only mode-aware layer: record and update modes still save via recorder.close(), while playback only cleans up timers via recorder.destroy(). The public saveSnapshots() is left untouched, so explicit saves continue to work in any mode. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Geoffrey Booth <webadmin@geoffreybooth.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #5359 +/- ##
=======================================
Coverage 93.23% 93.23%
=======================================
Files 110 110
Lines 36668 36676 +8
=======================================
+ Hits 34187 34196 +9
+ Misses 2481 2480 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
metcoder95
approved these changes
Jun 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
SnapshotAgent.close()unconditionally delegates to the recorder'sclose(), which saves snapshots to disk whenever any are held — with no regard for the current mode:In playback mode this is a problem because
findSnapshot()mutates each matched snapshot on every call:And
callCountis serialized bysaveSnapshots(). So the chain is:The result is spurious diffs in committed snapshot fixtures after a plain playback run (no recording involved). For projects that store fixtures in git (e.g. via Git LFS), every test run produces a new file hash and noisy, meaningless diffs. The persisted
callCountis also stale state —loadSnapshots()does not reset it — so it has no business being written back during playback.Fix
Gate persistence at
SnapshotAgent.close(), which is the only layer that knows the mode. Record/update modes still save viarecorder.close(); playback only cleans up timers viarecorder.destroy():The public
saveSnapshots()is intentionally left untouched, so an explicit save still works in any mode — only the automatic save-on-close is suppressed during playback.Test
Added a regression test in the existing Close Method block (
test/snapshot-testing.js): record a fixture, capture its exact on-disk bytes, run a playback session with several matched requests (mutatingcallCountin memory),close(), and assert the file is byte-for-byte unchanged. It fails onmainand passes with this change.Note / possible follow-up
The opt-in auto-flush timer (
autoFlush: true) also callssaveSnapshots()and is likewise not mode-gated, so it could still rewrite a fixture during a long-running playback session. That's a separate, opt-in path (default off) and out of scope here, but worth flagging — happy to address it in a follow-up if maintainers prefer.