#[non_exhaustive]pub struct SteppableTerminal {
pub shadow_terminal: ShadowTerminal,
pub pty_task_handle: Arc<Mutex<JoinHandle<Result<(), PTYError>>>>,
pub pty_input_tx: Sender<BytesFromSTDIN>,
}Expand description
This Steppable Terminal is likely more useful for running end to end tests.
It doesn’t run [ShadowTerminal] in a loop and so requires calling certain methods manually to advance the
terminal frontend. It also exposes the underyling [Wezterm] terminal that has a wealth of useful methods
for interacting with it.
Fields (Non-exhaustive)§
This struct is marked as non-exhaustive
Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.shadow_terminal: ShadowTerminalThe [ShadowTerminal] frontend combines a PTY process and a [Wezterm] terminal instance.
pty_task_handle: Arc<Mutex<JoinHandle<Result<(), PTYError>>>>The underlying PTY’s Tokio task handle.
pty_input_tx: Sender<BytesFromSTDIN>A Tokio channel that forwards bytes to the underlying PTY’s STDIN.
Implementations§
Source§impl SteppableTerminal
impl SteppableTerminal
Sourcepub async fn start(config: Config) -> Result<Self, SteppableTerminalError>
pub async fn start(config: Config) -> Result<Self, SteppableTerminalError>
Starts the terminal. Waits for first output before returning.
§Errors
If it doesn’t receive any output in time.
Sourcepub fn kill(&self) -> Result<(), SteppableTerminalError>
pub fn kill(&self) -> Result<(), SteppableTerminalError>
Broadcast the shutdown signal. This should exit both the underlying PTY process and the
main ShadowTerminal loop.
§Errors
If the End messaage could not be sent.
Sourcepub fn send_input(&self, input: Input) -> Result<(), PTYError>
pub fn send_input(&self, input: Input) -> Result<(), PTYError>
Send input directly into the underlying PTY process. This doesn’t go through the shadow terminal’s “frontend”.
For some reason this function is unreliable when sending more than one character. It is
better to send larger strings using the OSC Paste mode. See [self.paste_string()]
§Errors
If sending the string fails
Sourcepub fn send_command(&self, command: &str) -> Result<(), PTYError>
pub fn send_command(&self, command: &str) -> Result<(), PTYError>
Send a command to the terminal REPL. This pastes the command body, then sends a single newline to tell the TTY to run the command.
§Errors
If sending the string fails
Sourcepub fn send_command_with_osc_paste(&self, command: &str) -> Result<(), PTYError>
pub fn send_command_with_osc_paste(&self, command: &str) -> Result<(), PTYError>
Send a command using an OSC paste event.
This is generally the preferred way to send commands. It’s just more efficient then sending each character separately. However, for some reason, that I haven’t been able to get to the bottom of, some PTY processes parse out the OSC paste ANSI codes and some don’t. I didn’t even know that PTY’s had anything to do with parsing ANSI, so I could well be mistaken and would appreciate being corrected.
So if you have problems with this function then just use send_command() instead.
@tombh July 2025.
§Errors
If sending the string fails
Sourcepub fn paste_string(&self, string: &str) -> Result<(), PTYError>
pub fn paste_string(&self, string: &str) -> Result<(), PTYError>
Use OSC Paste codes to send a large amount of text at once to the terminal.
§Errors
If sending the string fails
Sourcepub async fn render_all_output(&mut self) -> Result<(), PTYError>
pub async fn render_all_output(&mut self) -> Result<(), PTYError>
Consume all the new output from the underlying PTY and have Wezterm render it in the shadow terminal.
Warning: this function could block if there is no end to the output from the PTY.
§Errors
If PTY output can’t be handled.
Sourcepub fn get_scrollback_position(
&mut self,
) -> Result<usize, SteppableTerminalError>
pub fn get_scrollback_position( &mut self, ) -> Result<usize, SteppableTerminalError>
Get the position of the top of the screen in the scrollback history.
§Errors
If it can’t convert the position from isize to usize
Sourcepub fn screen_as_string(&mut self) -> Result<String, SteppableTerminalError>
pub fn screen_as_string(&mut self) -> Result<String, SteppableTerminalError>
Convert the current Wezterm shadow terminal screen to a plain string.
§Errors
If it can’t write into the output string
Sourcepub fn get_coords_of_cell_by_content(
&mut self,
content: &str,
) -> Option<(usize, usize)>
pub fn get_coords_of_cell_by_content( &mut self, content: &str, ) -> Option<(usize, usize)>
Return the screen coordinates of a matching cell’s contents.
§Errors
If it can’t write into the output string
Sourcepub fn get_cell_at(
&mut self,
x: usize,
y: usize,
) -> Result<Option<Cell>, SteppableTerminalError>
pub fn get_cell_at( &mut self, x: usize, y: usize, ) -> Result<Option<Cell>, SteppableTerminalError>
Get the wezterm_term::Cell at the given coordinates.
§Errors
If the cell at the given coordinates cannot be fetched.
Sourcepub fn get_string_at(
&mut self,
x: usize,
y: usize,
length: usize,
) -> Result<String, SteppableTerminalError>
pub fn get_string_at( &mut self, x: usize, y: usize, length: usize, ) -> Result<String, SteppableTerminalError>
Get the string, of the given length, at the given coordinates.
§Errors
If any of the cells at the given coordinates cannot be fetched.
Sourcepub fn dump_screen(&mut self) -> Result<(), SteppableTerminalError>
pub fn dump_screen(&mut self) -> Result<(), SteppableTerminalError>
Sourcepub async fn get_prompt_string(
command: Vec<OsString>,
) -> Result<String, SteppableTerminalError>
pub async fn get_prompt_string( command: Vec<OsString>, ) -> Result<String, SteppableTerminalError>
Get the prompt as a string. Useful for reproducibility as prompts can change between machines.
§Errors
- If a steppable terminal can’t be created.
- If the terminal’s screen can’t be parsed.
Sourcepub async fn wait_for_any_change(
&mut self,
) -> Result<(), SteppableTerminalError>
pub async fn wait_for_any_change( &mut self, ) -> Result<(), SteppableTerminalError>
Wait for the screen to change in any way.
§Errors
- If it can’t get the screen contents.
- If no change is found within a certain time.
Sourcepub async fn wait_for_string(
&mut self,
string: &str,
maybe_timeout: Option<u32>,
) -> Result<(), SteppableTerminalError>
pub async fn wait_for_string( &mut self, string: &str, maybe_timeout: Option<u32>, ) -> Result<(), SteppableTerminalError>
Wait for the given string to appear anywhere in the screen.
§Errors
- If it can’t get the screen contents.
- If no change is found within a certain time.
Sourcepub async fn wait_for_string_at(
&mut self,
string_to_find: &str,
x: usize,
y: usize,
maybe_timeout: Option<u32>,
) -> Result<(), SteppableTerminalError>
pub async fn wait_for_string_at( &mut self, string_to_find: &str, x: usize, y: usize, maybe_timeout: Option<u32>, ) -> Result<(), SteppableTerminalError>
Wait for the given string to appear at the given coordinates.
§Errors
- If it can’t get the screen contents.
- If no change is found within a certain time.
Sourcepub async fn wait_for_bg_color_at(
&mut self,
maybe_colour: Option<(f32, f32, f32, f32)>,
x: usize,
y: usize,
maybe_timeout: Option<u32>,
) -> Result<(), SteppableTerminalError>
pub async fn wait_for_bg_color_at( &mut self, maybe_colour: Option<(f32, f32, f32, f32)>, x: usize, y: usize, maybe_timeout: Option<u32>, ) -> Result<(), SteppableTerminalError>
Wait for the given background colour at the given coordinates
§Errors
- If it can’t get the screen contents.
- If it no cell is found at the coords
Sourcepub async fn wait_for_fg_color_at(
&mut self,
maybe_colour: Option<(f32, f32, f32, f32)>,
x: usize,
y: usize,
maybe_timeout: Option<u32>,
) -> Result<(), SteppableTerminalError>
pub async fn wait_for_fg_color_at( &mut self, maybe_colour: Option<(f32, f32, f32, f32)>, x: usize, y: usize, maybe_timeout: Option<u32>, ) -> Result<(), SteppableTerminalError>
Wait for the given foreground colour at the given coordinates
§Errors
- If it can’t get the screen contents.
- If it no cell is found at the coords
Sourcepub async fn wait_for_colors_at(
&mut self,
background_colour: Option<(f32, f32, f32, f32)>,
foreground_colour: Option<(f32, f32, f32, f32)>,
x: usize,
y: usize,
maybe_timeout: Option<u32>,
) -> Result<(), SteppableTerminalError>
pub async fn wait_for_colors_at( &mut self, background_colour: Option<(f32, f32, f32, f32)>, foreground_colour: Option<(f32, f32, f32, f32)>, x: usize, y: usize, maybe_timeout: Option<u32>, ) -> Result<(), SteppableTerminalError>
Wait for the given foreground and background colour at the given coordinates
§Errors
- If it can’t get the screen contents.
- If it no cell is found at the coords
Sourcepub const fn extract_colour(
colour_attribute: ColorAttribute,
) -> Option<SrgbaTuple>
pub const fn extract_colour( colour_attribute: ColorAttribute, ) -> Option<SrgbaTuple>
Get the colour of a cell from its colour attribute.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for SteppableTerminal
impl !RefUnwindSafe for SteppableTerminal
impl Send for SteppableTerminal
impl !Sync for SteppableTerminal
impl Unpin for SteppableTerminal
impl !UnwindSafe for SteppableTerminal
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more