Testing
Classes in the Phui\Testing and Phui\Debug namespaces, and the phui-snapshot command.
TestScreen
final class Phui\Testing\TestScreen
Mounts a component against a fake terminal and drives it a frame at a time.
Mounting
static mount(
Component|string $component,
int $width = 80,
int $height = 24,
): selfMounts $component on a fake terminal of the given cell size.
TestScreen::mount(Counter::class)
->press(Keypress::ENTER)
->assertSee('1');theme(Theme $theme): static
colours(ColourMode $mode): static
service(string $class, object $instance): static
inline(int $height = 15): staticMirror the same setters on the Screen.
Driving input
press(
Keypress|string $key,
array $modifiers = [],
): staticSends a keypress.
type(string $text): staticSends each character of $text as a separate keypress.
click(
int $x,
int $y,
string $button = MouseClickEvent::LEFT,
): staticSends a full click — a press then a release — at a screen cell.
mouseDown(
int $x,
int $y,
string $button = MouseClickEvent::LEFT,
): static
mouseUp(
int $x,
int $y,
string $button = MouseClickEvent::LEFT,
): staticSend a lone press or release at a screen cell, for driving a drag or the two phases of a click apart.
scroll(
int $x,
int $y,
string $direction = MouseScrollEvent::DOWN,
int $amount = 1,
): staticSends a scroll at a screen cell.
paste(string $content): staticSends a paste.
resize(int $width, int $height): staticResizes the fake terminal.
Controlling time
advance(int $milliseconds): staticMoves the fake clock forward, running any timers that fall due.
tick(): staticProcesses pending work and renders one frame.
hasPendingHandlers(): boolReturns whether handlers are still suspended and waiting to resume.
settle(
?Closure $using = null,
int $maxTicks = 25,
): staticTicks until nothing is pending or $maxTicks is reached. $using runs between ticks to drive an external event loop.
Reading the result
capture(): CaptureReturns a Capture of the current frame.
assertSee(string $text): staticAsserts the rendered frame contains $text.
assertDontSee(string $text): staticAsserts the rendered frame does not contain $text.
completed(): boolReturns whether the app has completed.
result(): mixedReturns the value passed to complete().
commands(?string $commandClass = null): arrayReturns the terminal commands issued, optionally filtered to one command class.
Capture
final readonly class Phui\Testing\Capture implements Stringable
A rendered frame, readable as text or cell by cell.
public int $width
public int $heightThe captured frame's cell dimensions.
cellAt(int $x, int $y): ?CellReturns the cell at a position, or null when out of bounds.
toText(): stringReturns the frame as plain text, without styling.
toAnsi(): stringReturns the frame with its ANSI escape sequences intact.
diff(self $other): arrayReturns the cells that differ between this capture and $other.
Snapshot CLI
vendor/bin/phui-snapshot renders a component to an ANSI frame or an image, with no TTY and no running app. For what it's for and how to write a target file, see Agents & Snapshotting.
vendor/bin/phui-snapshot <target.php> [options]The target is a PHP file that returns a Component instance or class name; --class constructs a class directly instead.
Options
| Option | Default | Does |
|---|---|---|
--size=WxH | 120x32 | Terminal dimensions |
--keys=TOKENS | — | Space-separated input tokens, played in order |
--settle=N | 2 | Frames run after each token |
--trim | off | Crops blank rows and columns off the right and bottom |
--out=PATH | <target>.ansi | Where the ANSI frame goes |
--png[=PATH] | off | Also renders a PNG, via freeze |
--film[=PATH] | off | Filmstrip PNG, one frame per token |
--gif[=PATH] | off | Animated GIF, one frame per token |
--font=NAME | Menlo | Font family passed to freeze |
--class=NAME | — | Constructs this class instead of requiring a return |
The image options shell out to freeze (brew install charmbracelet/tap/freeze); --film and --gif additionally need ImageMagick. The ANSI path needs neither.
Input tokens
The tokens --keys takes:
| Token | Does |
|---|---|
a 1 ? | Types the character |
enter tab esc space | Presses that key |
up down left right home end pageup pagedown | Moves |
backspace delete | Deletes |
ctrl:X alt:X | Presses X with a modifier, e.g. ctrl:enter |
click:X,Y | Left-clicks cell X,Y |
wheel:up:X,Y wheel:down:X,Y | Scrolls at cell X,Y |
advance:MS | Advances the clock, for timers and animation |
settle | Ticks until suspended handlers finish |
resize:WxH | Resizes the terminal |
Logger
final class Phui\Debug\Logger
Writes to a file rather than the terminal, which the rendered frame owns.
static configure(?string $path): voidSets the log file path. null disables logging.
static installErrorHandler(): voidRoutes PHP errors and uncaught exceptions to the log.
static debug(string $message): void
static info(string $message): void
static warn(string $message): void
static error(string $message): voidWrite a message at that level.