|
| 1 | +(waiter)= |
| 2 | + |
| 3 | +# Waiters - `libtmux._internal.waiter` |
| 4 | + |
| 5 | +The waiter module provides utilities for waiting on specific content to appear in tmux panes, making it easier to write reliable tests that interact with terminal output. |
| 6 | + |
| 7 | +## Key Features |
| 8 | + |
| 9 | +- **Fluent API**: Playwright-inspired chainable API for expressive, readable test code |
| 10 | +- **Multiple Match Types**: Wait for exact matches, substring matches, regex patterns, or custom predicate functions |
| 11 | +- **Composable Waiting**: Wait for any of multiple conditions or all conditions to be met |
| 12 | +- **Flexible Timeout Handling**: Configure timeout behavior and error handling to suit your needs |
| 13 | +- **Shell Prompt Detection**: Easily wait for shell readiness with built-in prompt detection |
| 14 | +- **Robust Error Handling**: Improved exception handling and result reporting |
| 15 | +- **Clean Code**: Well-formatted, linted code with proper type annotations |
| 16 | + |
| 17 | +## Basic Concepts |
| 18 | + |
| 19 | +When writing tests that interact with tmux sessions and panes, it's often necessary to wait for specific content to appear before proceeding with the next step. The waiter module provides a set of functions to help with this. |
| 20 | + |
| 21 | +There are multiple ways to match content: |
| 22 | +- **Exact match**: The content exactly matches the specified string |
| 23 | +- **Contains**: The content contains the specified string |
| 24 | +- **Regex**: The content matches the specified regular expression |
| 25 | +- **Predicate**: A custom function that takes the pane content and returns a boolean |
| 26 | + |
| 27 | +## Quick Start Examples |
| 28 | + |
| 29 | +### Simple Waiting |
| 30 | + |
| 31 | +Wait for specific text to appear in a pane: |
| 32 | + |
| 33 | +```{literalinclude} ../../tests/examples/_internal/waiter/test_wait_for_text.py |
| 34 | +:language: python |
| 35 | +``` |
| 36 | + |
| 37 | +### Advanced Matching |
| 38 | + |
| 39 | +Use regex patterns or custom predicates for more complex matching: |
| 40 | + |
| 41 | +```{literalinclude} ../../tests/examples/_internal/waiter/test_wait_for_regex.py |
| 42 | +:language: python |
| 43 | +``` |
| 44 | + |
| 45 | +```{literalinclude} ../../tests/examples/_internal/waiter/test_custom_predicate.py |
| 46 | +:language: python |
| 47 | +``` |
| 48 | + |
| 49 | +### Timeout Handling |
| 50 | + |
| 51 | +Control how long to wait and what happens when a timeout occurs: |
| 52 | + |
| 53 | +```{literalinclude} ../../tests/examples/_internal/waiter/test_timeout_handling.py |
| 54 | +:language: python |
| 55 | +``` |
| 56 | + |
| 57 | +### Waiting for Shell Readiness |
| 58 | + |
| 59 | +A common use case is waiting for a shell prompt to appear, indicating the command has completed. The example below uses a regular expression to match common shell prompt characters (`$`, `%`, `>`, `#`): |
| 60 | + |
| 61 | +```{literalinclude} ../../tests/examples/_internal/waiter/test_wait_until_ready.py |
| 62 | +:language: python |
| 63 | +``` |
| 64 | + |
| 65 | +> Note: This test is skipped in CI environments due to timing issues but works well for local development. |
| 66 | +
|
| 67 | +## Fluent API (Playwright-inspired) |
| 68 | + |
| 69 | +For a more expressive and chainable API, you can use the fluent interface provided by the `PaneContentWaiter` class: |
| 70 | + |
| 71 | +```{literalinclude} ../../tests/examples/_internal/waiter/test_fluent_basic.py |
| 72 | +:language: python |
| 73 | +``` |
| 74 | + |
| 75 | +```{literalinclude} ../../tests/examples/_internal/waiter/test_fluent_chaining.py |
| 76 | +:language: python |
| 77 | +``` |
| 78 | + |
| 79 | +## Multiple Conditions |
| 80 | + |
| 81 | +The waiter module also supports waiting for multiple conditions at once: |
| 82 | + |
| 83 | +```{literalinclude} ../../tests/examples/_internal/waiter/test_wait_for_any_content.py |
| 84 | +:language: python |
| 85 | +``` |
| 86 | + |
| 87 | +```{literalinclude} ../../tests/examples/_internal/waiter/test_wait_for_all_content.py |
| 88 | +:language: python |
| 89 | +``` |
| 90 | + |
| 91 | +```{literalinclude} ../../tests/examples/_internal/waiter/test_mixed_pattern_types.py |
| 92 | +:language: python |
| 93 | +``` |
| 94 | + |
| 95 | +## Implementation Notes |
| 96 | + |
| 97 | +### Error Handling |
| 98 | + |
| 99 | +The waiting functions are designed to be robust and handle timing and error conditions gracefully: |
| 100 | + |
| 101 | +- All wait functions properly calculate elapsed time for performance tracking |
| 102 | +- Functions handle exceptions consistently and provide clear error messages |
| 103 | +- Proper handling of return values ensures consistent behavior whether or not raises=True |
| 104 | + |
| 105 | +### Type Safety |
| 106 | + |
| 107 | +The waiter module is fully type-annotated to ensure compatibility with static type checkers: |
| 108 | + |
| 109 | +- All functions include proper type hints for parameters and return values |
| 110 | +- The ContentMatchType enum ensures that only valid match types are used |
| 111 | +- Combined with runtime checks, this prevents type-related errors during testing |
| 112 | + |
| 113 | +### Example Usage in Documentation |
| 114 | + |
| 115 | +All examples in this documentation are actual test files from the libtmux test suite. The examples are included using `literalinclude` directives, ensuring that the documentation remains synchronized with the actual code. |
| 116 | + |
| 117 | +## API Reference |
| 118 | + |
| 119 | +```{eval-rst} |
| 120 | +.. automodule:: libtmux._internal.waiter |
| 121 | + :members: |
| 122 | + :undoc-members: |
| 123 | + :show-inheritance: |
| 124 | + :member-order: bysource |
| 125 | +``` |
| 126 | + |
| 127 | +## Extended Retry Functionality |
| 128 | + |
| 129 | +```{eval-rst} |
| 130 | +.. automodule:: libtmux.test.retry_extended |
| 131 | + :members: |
| 132 | + :undoc-members: |
| 133 | + :show-inheritance: |
| 134 | + :member-order: bysource |
| 135 | +``` |
0 commit comments