Implement VT52 mode as a standalone delegate class (Vt52Parser), activated via CSI ?2l (DECANM reset) and exited via ESC <. Supports all VT52 escape sequences: cursor movement (A-D), direct addressing (ESC Y row col), erase (J/K), reverse index (I), home (H), and DECID response (ESC /Z). Graphics character mode (ESC F/G) maps ASCII 0x5F-0x7E to DEC Special Graphics glyphs (box-drawing, math symbols) — same charset as VT100's G0 '0'. 37 unit tests, all vttest tests 1-11 now pass including test 7 (VT52 mode). New docs/TERMINAL_PARSER.md with full parser architecture, state machine, DECCOLM quirks, VT52 implementation details, and graphics charset table. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5.2 KiB
5.2 KiB
Terminal Testing via ADB
Overview
Automated tests can be sent to the terminal via ADB broadcast receiver.
The app registers com.roundingmobile.sshworkbench.INPUT in debug builds.
Prerequisites
- App installed on device:
adb install -r app/build/deploy/ssh-workbench.v1.0.0.pro.dbg.YYYY-MM-DD.apk - Connected to a session (e.g. Duero)
- Device connected via ADB:
adb devices
Broadcast API
Action: com.roundingmobile.sshworkbench.INPUT
| Extra | Type | Description |
|---|---|---|
text |
String | Send text to the terminal |
enter |
Boolean | Send Enter (0x0D) |
esc |
String | Send ESC + string (e.g. [D for left arrow) |
bytes |
String | Send raw hex bytes (e.g. 1b 62 for ESC b) |
log |
Boolean | Log cursor position after 100ms delay |
Examples
# Send text
adb shell "am broadcast -a com.roundingmobile.sshworkbench.INPUT --es text 'hello world'"
# Send Enter
adb shell "am broadcast -a com.roundingmobile.sshworkbench.INPUT --ez enter true"
# Send left arrow (ESC [D)
adb shell "am broadcast -a com.roundingmobile.sshworkbench.INPUT --es esc '[D'"
# Send ESC b (word back)
adb shell "am broadcast -a com.roundingmobile.sshworkbench.INPUT --es bytes '1b 62'"
# Send Ctrl+U (kill line)
adb shell "am broadcast -a com.roundingmobile.sshworkbench.INPUT --es bytes '15'"
# Log cursor position
adb shell "am broadcast -a com.roundingmobile.sshworkbench.INPUT --ez log true"
Cursor Position Logging
When log extra is sent, or before any input, the app logs cursor position:
[cursor] before-text 'hello': row=3 col=14 line='jima@duero:~$ |'
[cursor] query: row=3 col=19 line='jima@duero:~$ hello|'
The | in the line preview shows the cursor position. Read logs via:
adb shell cat /sdcard/Download/SshWorkbench/sshworkbench_debug.txt | grep "\[cursor\]"
Common Escape Sequences
| Key | Escape | Bytes |
|---|---|---|
| Left arrow | [D |
1b 5b 44 |
| Right arrow | [C |
1b 5b 43 |
| Up arrow | [A |
1b 5b 41 |
| Down arrow | [B |
1b 5b 42 |
| Home | [H |
1b 5b 48 |
| End | [F |
1b 5b 46 |
| Word back (Alt+Left) | — | 1b 62 |
| Word forward (Alt+Right) | — | 1b 66 |
| Ctrl+U (kill line) | — | 15 |
| Ctrl+C (interrupt) | — | 03 |
| Tab | — | 09 |
Running the Test Script
# Make sure you're connected to a session first, then:
./scripts/test_terminal.sh
The script tests:
- Text input and cursor tracking
- Word navigation (ESC b / ESC f)
- Arrow key movement
- Home / End keys
Screenshots are saved to /tmp/zebra_test_*.png.
Connecting Automatically
Use the --es profile launch intent extra to auto-connect:
adb -s 22160523026079 shell am start \
-n com.roundingmobile.sshworkbench.pro/com.roundingmobile.sshworkbench.ui.MainActivity \
--es profile "SSHTest"
The profile name matches against SavedConnection.name or SavedConnection.nickname (case-insensitive). Also supports --ez clearLog true to clear the debug log on launch.
vttest Verification
vttest is the standard VT100/VT220 terminal conformance test. Run it on Duero:
# Connect and launch vttest
adb -s 22160523026079 shell "am broadcast -a com.roundingmobile.sshworkbench.INPUT --es text 'vttest'"
adb -s 22160523026079 shell "am broadcast -a com.roundingmobile.sshworkbench.INPUT --es text $'\r'"
# Select a test (e.g. test 1 = cursor movements)
adb -s 22160523026079 shell "am broadcast -a com.roundingmobile.sshworkbench.INPUT --es text '1'"
adb -s 22160523026079 shell "am broadcast -a com.roundingmobile.sshworkbench.INPUT --es text $'\r'"
# Advance screens with Enter
adb -s 22160523026079 shell "am broadcast -a com.roundingmobile.sshworkbench.INPUT --es text $'\r'"
# Take screenshot for verification
adb -s 22160523026079 shell screencap -p /sdcard/Download/screen.png
adb -s 22160523026079 pull /sdcard/Download/screen.png /tmp/vttest_screen.png
vttest Results (all passing as of 2026-03-31)
| Test | Name | Notes |
|---|---|---|
| 1 | Cursor movements | 80 + 132 column borders, autowrap, leading zeros |
| 2 | Screen features | SGR, soft/jump scroll, save/restore cursor |
| 3 | Character sets | 13 sub-tests, DEC special graphics |
| 4 | Double-sized characters | DHDW top/bottom halves |
| 5 | Keyboard | Skipped (requires physical key presses) |
| 6 | Terminal reports | DA, DSR, CPR, DECREQTPARM |
| 7 | VT52 mode | Cursor, erase, ESC Y, graphics charset, DECID |
| 8 | VT102 features | Insert/delete char/line |
| 9 | Known bugs | Smooth scroll, origin mode, wrap-around |
| 10 | Reset and self-test | RIS, DECTST |
| 11 | Non-VT100 | VT220 reports, XTERM, colors, BCE |
Debugging vttest failures
- Check debug log:
adb shell cat /sdcard/Download/SshWorkbench/sshworkbench_debug.txt | tail -50 - Chunks < 128 bytes are hex-dumped in the log; larger chunks are silent
- Session recordings capture all bytes:
/sdcard/Download/SshWorkbench/recordings/ - Decode recordings with:
python3 -c "import struct, sys; f=open(sys.argv[1],'rb'); [print(f.read(struct.unpack('>I',f.read(4))[0])) for _ in iter(lambda:f.read(4),b'')]" - DECCOLM issues: Check if the vttest menu disappears after a column mode switch — see
docs/TERMINAL_PARSER.mdfor the mid-chunk fix