|
| 1 | +(snapshots)= |
| 2 | + |
| 3 | +# Snapshots and Recordings |
| 4 | + |
| 5 | +libtmux provides functionality to capture and analyze the state of tmux panes through snapshots and recordings. |
| 6 | + |
| 7 | +## Taking Snapshots |
| 8 | + |
| 9 | +A snapshot captures the content and metadata of a pane at a specific point in time: |
| 10 | + |
| 11 | +```python |
| 12 | +>>> pane = session.active_window.active_pane |
| 13 | +>>> snapshot = pane.snapshot() |
| 14 | +>>> print(snapshot.content_str) |
| 15 | +$ echo "Hello World" |
| 16 | +Hello World |
| 17 | +$ |
| 18 | +``` |
| 19 | + |
| 20 | +Snapshots are immutable and include: |
| 21 | +- Pane content |
| 22 | +- Timestamp (in UTC) |
| 23 | +- Pane, window, session, and server IDs |
| 24 | +- All tmux pane metadata |
| 25 | + |
| 26 | +You can also capture specific ranges of the pane history: |
| 27 | + |
| 28 | +```python |
| 29 | +>>> # Capture lines 1-3 only |
| 30 | +>>> snapshot = pane.snapshot(start=1, end=3) |
| 31 | + |
| 32 | +>>> # Capture from start of history |
| 33 | +>>> snapshot = pane.snapshot(start="-") |
| 34 | + |
| 35 | +>>> # Capture up to current view |
| 36 | +>>> snapshot = pane.snapshot(end="-") |
| 37 | +``` |
| 38 | + |
| 39 | +## Recording Pane Activity |
| 40 | + |
| 41 | +To track changes in a pane over time, use recordings: |
| 42 | + |
| 43 | +```python |
| 44 | +>>> recording = pane.record() |
| 45 | +>>> recording.add_snapshot(pane) |
| 46 | +>>> pane.send_keys("echo 'Hello'") |
| 47 | +>>> recording.add_snapshot(pane) |
| 48 | +>>> pane.send_keys("echo 'World'") |
| 49 | +>>> recording.add_snapshot(pane) |
| 50 | + |
| 51 | +>>> # Access snapshots |
| 52 | +>>> print(recording[0].content_str) # First snapshot |
| 53 | +>>> print(recording.latest.content_str) # Most recent |
| 54 | + |
| 55 | +>>> # Filter by time |
| 56 | +>>> recent = recording.get_snapshots_between( |
| 57 | +... start_time=datetime.datetime.now() - datetime.timedelta(minutes=5), |
| 58 | +... end_time=datetime.datetime.now(), |
| 59 | +... ) |
| 60 | +``` |
| 61 | + |
| 62 | +## Output Formats |
| 63 | + |
| 64 | +Snapshots can be formatted in different ways for various use cases: |
| 65 | + |
| 66 | +### Terminal Output |
| 67 | + |
| 68 | +```python |
| 69 | +>>> from libtmux.snapshot import TerminalOutputAdapter |
| 70 | +>>> print(snapshot.format(TerminalOutputAdapter())) |
| 71 | +=== Pane Snapshot === |
| 72 | +Pane: %1 |
| 73 | +Window: @1 |
| 74 | +Session: $1 |
| 75 | +Server: default |
| 76 | +Timestamp: 2024-01-01T12:00:00Z |
| 77 | +=== Content === |
| 78 | +$ echo "Hello World" |
| 79 | +Hello World |
| 80 | +$ |
| 81 | +``` |
| 82 | + |
| 83 | +### CLI Output (No Colors) |
| 84 | + |
| 85 | +```python |
| 86 | +>>> from libtmux.snapshot import CLIOutputAdapter |
| 87 | +>>> print(snapshot.format(CLIOutputAdapter())) |
| 88 | +=== Pane Snapshot === |
| 89 | +Pane: %1 |
| 90 | +Window: @1 |
| 91 | +Session: $1 |
| 92 | +Server: default |
| 93 | +Timestamp: 2024-01-01T12:00:00Z |
| 94 | +=== Content === |
| 95 | +$ echo "Hello World" |
| 96 | +Hello World |
| 97 | +$ |
| 98 | +``` |
| 99 | + |
| 100 | +### Pytest Assertion Diffs |
| 101 | + |
| 102 | +```python |
| 103 | +>>> from libtmux.snapshot import PytestDiffAdapter |
| 104 | +>>> expected = """ |
| 105 | +... PaneSnapshot( |
| 106 | +... pane_id='%1', |
| 107 | +... window_id='@1', |
| 108 | +... session_id='$1', |
| 109 | +... server_name='default', |
| 110 | +... timestamp='2024-01-01T12:00:00Z', |
| 111 | +... content=[ |
| 112 | +... '$ echo "Hello World"', |
| 113 | +... 'Hello World', |
| 114 | +... '$', |
| 115 | +... ], |
| 116 | +... metadata={ |
| 117 | +... 'pane_height': '24', |
| 118 | +... 'pane_width': '80', |
| 119 | +... }, |
| 120 | +... ) |
| 121 | +... """ |
| 122 | +>>> assert snapshot.format(PytestDiffAdapter()) == expected |
| 123 | +``` |
| 124 | + |
| 125 | +### Syrupy Snapshot Testing |
| 126 | + |
| 127 | +```python |
| 128 | +>>> from libtmux.snapshot import SyrupySnapshotAdapter |
| 129 | +>>> snapshot.format(SyrupySnapshotAdapter()) |
| 130 | +{ |
| 131 | + "pane_id": "%1", |
| 132 | + "window_id": "@1", |
| 133 | + "session_id": "$1", |
| 134 | + "server_name": "default", |
| 135 | + "timestamp": "2024-01-01T12:00:00Z", |
| 136 | + "content": [ |
| 137 | + "$ echo \"Hello World\"", |
| 138 | + "Hello World", |
| 139 | + "$" |
| 140 | + ], |
| 141 | + "metadata": { |
| 142 | + "pane_height": "24", |
| 143 | + "pane_width": "80" |
| 144 | + } |
| 145 | +} |
| 146 | +``` |
| 147 | + |
| 148 | +## Custom Output Formats |
| 149 | + |
| 150 | +You can create custom output formats by implementing the `SnapshotOutputAdapter` interface: |
| 151 | + |
| 152 | +```python |
| 153 | +from libtmux.snapshot import SnapshotOutputAdapter |
| 154 | + |
| 155 | +class MyCustomAdapter(SnapshotOutputAdapter): |
| 156 | + def format(self, snapshot: PaneSnapshot) -> str: |
| 157 | + # Format snapshot data as needed |
| 158 | + return f"Custom format: {snapshot.content_str}" |
| 159 | + |
| 160 | +# Use custom adapter |
| 161 | +print(snapshot.format(MyCustomAdapter())) |
| 162 | +``` |
0 commit comments