Repository navigation
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/--heightsay otherwise. - The built-in face alone is used, so screenshots match across machines (
--fonts systemopts out). - The clipboard is private to the process.
| 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 |
| 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 |
| 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 |
| Command | Does |
|---|---|
screenshot <path> |
Write the frame as a PNG |
echo <text> |
Print a line |
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.
Getting started
What works today
Measured
Design decisions
Testing and tools