1package e2e23import (4 "strings"5 "testing"67 ghostty "go.mitchellh.com/libghostty"8)910// With the kitty keyboard protocol, as Ghostty has it, 012 turns on key11// events; Shift+Enter moves up after an entry and Ctrl+I is italic. A12// terminal without it sends Shift+Enter as Enter and Ctrl+I as Tab, and13// 012 does what those do.14func TestKittyKeyboard(t *testing.T) {15 t.Parallel()16 t.Run("on", func(t *testing.T) {17 s := start(t, "")18 s.eventually("key events on", func() bool {19 return s.kittyFlags()&ghostty.KittyKeyReportEvents != 020 })21 s.keys("<down>", "<down>", "5", "<shift+enter>")22 s.waitForBar("A2", "")23 s.keys("<down>", "<ctrl+i>")24 s.waitFor("Italic on for A3")25 // Alt+letter opens its menu; Esc then a letter, however quick, is26 // Esc, then the letter typed.27 s.keys("<alt+f>")28 s.waitFor("MENU")29 s.keys("<esc>", "j")30 s.waitFor("ENTER")31 s.waitForBar("A3", "j")32 })33 t.Run("off", func(t *testing.T) {34 s := startWith(t, options{legacyKeys: true})35 if f := s.kittyFlags(); f != 0 {36 t.Fatalf("flags %v on a terminal without the protocol", f)37 }38 s.keys("<down>", "<down>", "5", "<shift+enter>")39 s.waitForBar("A4", "")40 s.keys("<up>", "<ctrl+i>")41 s.waitForBar("B3", "")42 s.keys("<alt+f>")43 s.waitFor("MENU")44 })45}4647// Holding Space on a selected chart shows it across the grid until it's48// let go; without key events Space deselects the chart and starts an49// entry, as it always has.50func TestHoldSpaceOnChart(t *testing.T) {51 t.Parallel()52 t.Run("on", func(t *testing.T) {53 s := start(t, "")54 spending(s)55 insertChart(s)56 s.keys("<enter>")57 s.waitFor("hold Space to zoom")58 s.hold("<space>")59 s.eventually("chart over column A", func() bool {60 return !strings.Contains(s.line(gridRow1), "Month") && strings.Contains(s.screen(), "let go")61 })62 s.release("<space>")63 s.eventually("chart back at D1", func() bool { return strings.Contains(s.line(gridRow1), "Month") })64 s.waitFor("hold Space to zoom")65 if !strings.Contains(s.line(0), "CHART") {66 t.Errorf("released: %q", s.line(0))67 }68 })69 t.Run("off", func(t *testing.T) {70 s := startWith(t, options{legacyKeys: true})71 spending(s)72 insertChart(s)73 s.keys("<enter>")74 s.waitFor("drag the corner to resize")75 if strings.Contains(s.screen(), "hold Space") {76 t.Errorf("hint without key events:\n%s", s.screen())77 }78 s.keys(" ") // as typed: the terminal sends the space itself79 s.waitFor("ENTER")80 })81}8283// Holding Space in the theme picker hides the list, showing the sheet in84// the highlighted theme, until it's let go; with a search typed, or85// without key events, Space is typed.86func TestHoldSpaceInThemePicker(t *testing.T) {87 t.Parallel()88 t.Run("on", func(t *testing.T) {89 s := start(t, "")90 openTheme(s)91 s.waitFor("hold to peek")92 s.hold("<space>")93 s.eventually("list hidden", func() bool { return !strings.Contains(s.screen(), "─ Theme ─") })94 s.release("<space>")95 s.waitFor("─ Theme ─")96 s.keys("tokyo", "<space>")97 s.waitFor("› tokyo ")98 })99 t.Run("off", func(t *testing.T) {100 s := startWith(t, options{legacyKeys: true})101 openTheme(s)102 if strings.Contains(s.screen(), "hold to peek") {103 t.Errorf("hint without key events:\n%s", s.screen())104 }105 s.keys(" x")106 s.waitFor("› x")107 })108}