Documentation
¶
Overview ¶
Package e2e drives the compiled binary inside a real terminal so that rendering, key handling and resize behaviour can be asserted on the frames a user would actually see.
It uses tmux as a scriptable terminal. Two tmux facts shape this package and were verified empirically rather than assumed:
- resize-window changes the size of a detached session's pseudo-terminal and the process receives SIGWINCH. resize-pane does not: on a window with a single pane it silently does nothing, so a resize test built on it would pass while never resizing anything.
- capture-pane without a scrollback range captures the visible screen, which for a full-screen program is the alternate screen buffer. Scrollback captures do not contain alternate-screen output at all.
Every Terminal runs on its own tmux server socket, so a test can never disturb a tmux session the user is working in.
Index ¶
- Variables
- func Available() error
- type Options
- type Terminal
- func (tm *Terminal) Alive() bool
- func (tm *Terminal) AssertFits()
- func (tm *Terminal) Capture() string
- func (tm *Terminal) CaptureANSI() string
- func (tm *Terminal) Close()
- func (tm *Terminal) ExitStatus() (int, bool)
- func (tm *Terminal) Lines() []string
- func (tm *Terminal) MustWaitFor(substr string, timeout time.Duration) string
- func (tm *Terminal) Resize(width, height int)
- func (tm *Terminal) ResizeAndWait(width, height int, timeout time.Duration) string
- func (tm *Terminal) SendKeys(keys ...string)
- func (tm *Terminal) SendText(text string)
- func (tm *Terminal) Size() (width, height int)
- func (tm *Terminal) WaitChanged(previous string, timeout time.Duration) string
- func (tm *Terminal) WaitFor(substr string, timeout time.Duration) (string, error)
- func (tm *Terminal) WaitSettled(timeout time.Duration) string
Constants ¶
This section is empty.
Variables ¶
var ErrTimeout = errors.New("timed out waiting for the terminal")
ErrTimeout is returned when a wait gives up.
Functions ¶
Types ¶
type Options ¶
type Options struct {
// Width and Height are the initial terminal size in character cells.
Width, Height int
// Dir is the working directory for the command.
Dir string
// Env holds extra environment entries in KEY=VALUE form. TERM and the
// colour-related variables are set for you unless you override them.
Env []string
// Color leaves colour enabled. By default colour is switched off so that
// captured frames are stable text.
Color bool
}
Options configures a Terminal.
type Terminal ¶
type Terminal struct {
// contains filtered or unexported fields
}
Terminal is a tmux-hosted terminal running one command.
func Start ¶
Start launches command in a new terminal of the requested size. The command is run through the shell, so it may contain arguments. The Terminal is closed automatically when the test finishes.
func (*Terminal) AssertFits ¶
func (tm *Terminal) AssertFits()
AssertFits checks the invariant every frame must satisfy: no line wider than the terminal and no more lines than it has rows. A frame that breaks this corrupts the display and is the most common resize bug.
func (*Terminal) Capture ¶
Capture returns the visible screen as plain text with trailing blanks trimmed from each line.
func (*Terminal) CaptureANSI ¶
CaptureANSI returns the visible screen including escape sequences, for assertions where styling is the thing under test.
func (*Terminal) Close ¶
func (tm *Terminal) Close()
Close kills the tmux server backing this terminal.
func (*Terminal) ExitStatus ¶
ExitStatus returns the program's exit status, and whether it has exited.
func (*Terminal) MustWaitFor ¶
MustWaitFor is WaitFor with the error turned into a test failure.
func (*Terminal) ResizeAndWait ¶
ResizeAndWait changes the size and waits for the program to redraw, which is the only safe way to assert on a frame after a resize.
func (*Terminal) SendKeys ¶
SendKeys sends key names to the program. Names are tmux key names, so "Enter", "Escape", "C-c", "Up" and plain characters all work.
func (*Terminal) SendText ¶
SendText sends literal text, which is safer than SendKeys for characters tmux would interpret as key names.
func (*Terminal) Size ¶
Size returns the size tmux reports for the pane, which is the size the program actually sees. It is not necessarily the size passed to Start or Resize, so assertions about wrapping should use this.
func (*Terminal) WaitChanged ¶
WaitChanged blocks until the screen differs from previous and has then stopped changing, and returns the new screen.
This is the wait to use after anything that should redraw. WaitSettled alone is not enough: it returns as soon as the screen has held still for a moment, and immediately after a resize the screen is still the old one and perfectly still, so a caller can be handed the frame from before the change and assert against it. That is not a hypothetical — it is how a genuine recovery from the too-small state looked like a failure to recover.
func (*Terminal) WaitFor ¶
WaitFor blocks until the screen contains substr. It returns the screen that matched.
func (*Terminal) WaitSettled ¶
WaitSettled blocks until the screen has stopped changing, and returns it. Polling for a stable frame is deterministic where sleeping for a guessed duration is not: a slow machine makes a sleep too short, never too long.