@@ -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