feat: add text locator python api - #154
Closed
cpendery (cpendery) wants to merge 1 commit into
Closed
Conversation
Signed-off-by: cpendery <cpendery@vt.edu>
Member
Author
|
Superseded by #149, which now contains the complete text-locator change. |
cpendery (cpendery)
added a commit
that referenced
this pull request
Aug 29, 2026
## Summary
Adds lazy, reusable locators to Rust, Python, and JavaScript. The APIs
are `getByText` / `getByStyle` in JavaScript and `get_by_text` /
`get_by_style` in Python and Rust. Text and contiguous per-row style-run
stages can be chained with `within`, `after`, or `before`. Repeated
parent matches divide relative regions into separate segments.
Locators support literal and regex matching, viewport and
full-scrollback searches, whitespace normalization, and match locations.
Occurrences are selected only by chaining `any`, `unique`, `first`,
`last`, or `nth`. Every read or action resolves against the current
terminal. Clicks target the middle matched cell, and highlights appear
in the live monitor and SVG screenshots. Bare `wait`, `highlight`, and
`expect` accept any match; `location` and `click` require one match; and
`unique().expect()` requires exactly one.
Style expectations use nested `getByStyle` / `get_by_style` stages. In
the default `within` direction, the style stage keeps a parent match
only when all its visible cells satisfy the style.
The CLI exposes `find|expect|click|highlight text "T"` with the same
selector and optional style flags. This removes `wait text`, redundant
`--no-strict`, and the one-shot `findText` / `find_text`, `waitText` /
`wait_text`, and `expectText` / `expect_text` APIs.
N-API and PyO3 receive typed locator stage arrays and action parameters
without locator JSON serialization. Dense regex match offsets are
converted in one forward pass. Occurrences are selected before match
cells are materialized unless a style filter must run first.
Full-scrollback locations use 32-bit row coordinates, preserving rows
beyond 65,535.
Tests cover `any` / `unique` / `first` / `last` / `nth` expectations,
negation with zero, one, or multiple matches, exact counts, and partial
style filtering in all three libraries. The package version is the sole
daemon compatibility version.
Text matching and actions use the generic locator engine. The four
cleanup revisions remove 3,081 lines and add 1,978, for a net reduction
of 1,103 lines.
## Examples
```js
const save = terminal
.getByText("Settings")
.getByText("Save", {
whitespace: "normalize",
direction: "after",
})
.unique();
await save.wait();
await save.expect();
await save.click();
await terminal
.getByText("Warning")
.getByStyle({ bold: true })
.unique()
.expect();
```
```python
from tui_test import TextStyle
save = (
terminal
.get_by_text("Settings")
.get_by_text(
"Save",
whitespace="normalize",
direction="after",
)
.unique()
)
await save.wait()
await save.expect()
await save.click()
await (
terminal
.get_by_text("Warning")
.get_by_style(TextStyle(bold=True))
.unique()
.expect()
)
```
```rust
use tui_test::LocatorDirection;
let save = terminal
.get_by_text("Settings")
.get_by_text_relative("Save", LocatorDirection::After)
.unique();
save.wait()?;
save.expect()?;
save.click()?;
```
```sh
tui-test find text "Add to cart" --fg green
tui-test expect text "Add to cart" --fg green --timeout 5000
tui-test expect text "Add to cart" --match unique --timeout 5000
tui-test click text "Add to cart" --fg green --timeout 5000
tui-test highlight text "Add to cart" --fg green
```
## Test plan
- `cargo fmt --all -- --check`
- `cargo clippy --workspace --all-targets --all-features -- -D warnings`
- `cargo clippy -p tui-test-rs --all-targets --no-default-features -- -D
warnings`
- `cargo build`
- `cargo test --workspace -- --test-threads=1`
- `python -m unittest discover -s bindings/python/tests -v`
- `python bindings/python/scripts/generate_stubs.py --check`
- `npm run test:node --prefix bindings/js`
Replaces #150, #151, #152, and #154.
---------
Signed-off-by: cpendery <cpendery@vt.edu>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.