Skip to content

Scripting the shell

codingncaffeine edited this page Sep 4, 2026 · 19 revisions

Scripting the shell

sashfold --script <file> [--update-goldens] [--width N] [--height N] [--theme <file.json>] [--downloads <dir>]

--script replays a text file of commands against the shell, headless, and checks its assertions. It is the shell's test harness (the same script runs on every OS in CI and its screenshots are byte-identical) and the proof that a browser can be driven, and read back, from a text file.

  • One command per line; # starts a comment.
  • Relative paths resolve against the script's own directory.
  • Coordinates are window coordinates; the window is 1024×720 unless --width/--height say otherwise.
  • The built-in face alone is used, so screenshots match across machines (--fonts system opts out).
  • The clipboard is private to the process.

Navigation

Command Does
open <url|path> Navigate; a bare path becomes a file: URL
navigate <typed> Address-bar semantics (https-first for a bare host)
back, forward, reload History
new-tab, close-tab [n], select-tab <n> Tabs
resize <w> <h> Resize the window
tick Let queued work run

Input

Command Does
click <x> <y>, middle-click <x> <y> A click at window coordinates
click-text <text> Click the center of the first run containing the text (one run: a single word is safest)
move <x> <y> Hover
wheel <notches> Scroll the content (positive rolls up)
wheel-at <x> <y> <notches> The same, over one window point — the box under it takes it if it can
type <text> Type into whatever has focus
key <chord> A key, e.g. Enter, Escape, ctrl+l, alt+left, ctrl+shift+tab, f12
drag <x1> <y1> <x2> <y2> Press, move, release the left button
focus <name> Focus the first form control with that name
select-text <text> Select the first run's occurrence of the text
reader Toggle reader mode
inspect-text <text> Devtools: inspect the element of the first run containing the text

Assertions

Command Checks
assert-url <url>, assert-address <text>, assert-title <text> The current page
assert-text <text>, assert-no-text <text> Text present or absent on the page
assert-status <text> The status bar
assert-tabs <n>, assert-scroll <n>, assert-scrolled Tabs and the page's scrolling
assert-box-scroll <x> <y> <dx> <dy> How far the box that scrolls under that window point has moved its content
assert-pixel <x> <y> <#rrggbb> One pixel of the frame
assert-focus address|page Where keyboard focus is
assert-value <name> <text> A control's current value
assert-focused <name> The focused control ("" for none)
assert-selection <text> The selected text (one line)
assert-find <text> The find bar's count: 3 of 12, No matches, "" when closed
assert-hints <n> The number of link-hint labels showing
assert-inspected <tag#id.class> The inspected element
assert-golden <png> The frame's bytes equal the file; --update-goldens blesses

Output

Command Does
screenshot <path> Write the frame as a PNG
echo <text> Print a line

The scripts in the repository

tests/shell/ holds smoke.script, forms.script, selection.script, find.script, reader.script, hints.script and devtools.script, each with its goldens under tests/shell/goldens/, all run by CI; and live.script, which needs the network (Wikipedia, Hacker News, a real link click, example.org from the cache, badssl.com's certificate page, a Wikipedia search through a form, and Acid1) and is run by hand.

Clone this wiki locally