Module: Browserctl::Replay::SnapshotDiff
- Defined in:
- lib/browserctl/replay/snapshot_diff.rb
Overview
Stable digest + element-set comparison for post-step snapshots.
The digest is intentionally cheap and stable across cosmetic DOM noise: only the (selector, role, tag) triples drive the hash, sorted to remove ordering effects. That’s enough to flag structural drift (a step that used to land on /dashboard now lands on /login) without flapping on every reflow or class rename.
Class Method Summary collapse
-
.compare(prev, current) ⇒ Object
Returns { added: […], removed: […] } of element selectors that differ between two snapshots.
- .digest(snapshot) ⇒ Object
- .element_set(snapshot) ⇒ Object
- .identity_tuple(entry) ⇒ Object
Class Method Details
.compare(prev, current) ⇒ Object
Returns { added: […], removed: […] } of element selectors that differ between two snapshots. Empty arrays mean structurally identical.
26 27 28 29 30 31 32 33 |
# File 'lib/browserctl/replay/snapshot_diff.rb', line 26 def compare(prev, current) prev_set = element_set(prev) current_set = element_set(current) { added: (current_set - prev_set).sort, removed: (prev_set - current_set).sort } end |
.digest(snapshot) ⇒ Object
17 18 19 20 21 22 |
# File 'lib/browserctl/replay/snapshot_diff.rb', line 17 def digest(snapshot) return nil if snapshot.nil? keys = Array(snapshot).map { |el| identity_tuple(el) }.compact.sort Digest::SHA1.hexdigest(keys.join("\n"))[0, 16] end |
.element_set(snapshot) ⇒ Object
46 47 48 |
# File 'lib/browserctl/replay/snapshot_diff.rb', line 46 def element_set(snapshot) Array(snapshot).map { |entry| entry[:selector] || entry["selector"] }.compact end |
.identity_tuple(entry) ⇒ Object
35 36 37 38 39 40 41 42 43 44 |
# File 'lib/browserctl/replay/snapshot_diff.rb', line 35 def identity_tuple(entry) return nil unless entry.is_a?(Hash) sel = entry[:selector] || entry["selector"] role = entry[:role] || entry["role"] tag = entry[:tag] || entry["tag"] return nil unless sel "#{sel}|#{role}|#{tag}" end |