Skip to content

Commit 98ea878

Browse files
committed
docs(textframe): Document capture_frame() integration
why: Show users how to use capture_frame() for testing terminal output. what: - Add Pane.capture_frame() integration section - Document parameters with table - Explain design decisions (truncate default, refresh) - Add retry_until usage example
1 parent cecf545 commit 98ea878

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

docs/internals/textframe.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,74 @@ When installed with `pip install libtmux[textframe]`:
223223
| `src/libtmux/textframe/plugin.py` | Syrupy extension, pytest hooks, and fixtures |
224224
| `src/libtmux/textframe/__init__.py` | Public API exports |
225225

226+
## Pane.capture_frame() Integration
227+
228+
The `Pane.capture_frame()` method provides a high-level way to capture pane content as a TextFrame:
229+
230+
```python
231+
from libtmux.test.retry import retry_until
232+
233+
def test_cli_output(pane, textframe_snapshot):
234+
"""Test CLI output with visual snapshot."""
235+
pane.send_keys("echo 'Hello, World!'", enter=True)
236+
237+
# Wait for output to appear
238+
def output_appeared():
239+
return "Hello" in "\n".join(pane.capture_pane())
240+
retry_until(output_appeared, 2, raises=True)
241+
242+
# Capture as frame for snapshot comparison
243+
frame = pane.capture_frame(content_width=40, content_height=10)
244+
assert frame == textframe_snapshot
245+
```
246+
247+
### Parameters
248+
249+
| Parameter | Type | Default | Description |
250+
|-----------|------|---------|-------------|
251+
| `start` | `int \| "-" \| None` | `None` | Starting line (same as `capture_pane`) |
252+
| `end` | `int \| "-" \| None` | `None` | Ending line (same as `capture_pane`) |
253+
| `content_width` | `int \| None` | Pane width | Frame width in characters |
254+
| `content_height` | `int \| None` | Pane height | Frame height in lines |
255+
| `overflow_behavior` | `"error" \| "truncate"` | `"truncate"` | How to handle overflow |
256+
257+
### Design Decisions
258+
259+
**Why `overflow_behavior="truncate"` by default?**
260+
261+
Pane content can exceed nominal dimensions during:
262+
- Terminal resize transitions
263+
- Shell startup (MOTD, prompts)
264+
- ANSI escape sequences in output
265+
266+
Using `truncate` avoids spurious test failures in CI environments.
267+
268+
**Why does it call `self.refresh()`?**
269+
270+
Pane dimensions can change (resize, zoom). `refresh()` ensures we use current values when `content_width` or `content_height` are not specified.
271+
272+
### Using with retry_until
273+
274+
For asynchronous terminal output, combine with `retry_until`:
275+
276+
```python
277+
from libtmux.test.retry import retry_until
278+
279+
def test_async_output(session):
280+
"""Wait for output using capture_frame in retry loop."""
281+
window = session.new_window()
282+
pane = window.active_pane
283+
284+
pane.send_keys('for i in 1 2 3; do echo "line $i"; done', enter=True)
285+
286+
def all_lines_present():
287+
frame = pane.capture_frame(content_width=40, content_height=10)
288+
rendered = frame.render()
289+
return all(f"line {i}" in rendered for i in [1, 2, 3])
290+
291+
retry_until(all_lines_present, 3, raises=True)
292+
```
293+
226294
## Public API
227295

228296
```python

0 commit comments

Comments
 (0)