diff --git a/pkg/gui/gui_driver.go b/pkg/gui/gui_driver.go index 7bd31d93d..74a8109a7 100644 --- a/pkg/gui/gui_driver.go +++ b/pkg/gui/gui_driver.go @@ -25,17 +25,27 @@ type GuiDriver struct { var _ integrationTypes.GuiDriver = &GuiDriver{} func (self *GuiDriver) PressKey(keyStr string) { + self.PressKeysRapidly(keyStr) +} + +// PressKeysRapidly presses the given keys in immediate succession, waiting for +// lazygit to become idle only after the last one. Keys pressed this way can +// arrive while the previous key's processing is still in flight, like a user +// typing faster than lazygit handles the input. +func (self *GuiDriver) PressKeysRapidly(keyStrs ...string) { self.CheckAllToastsAcknowledged() - key, ok := config.KeyFromLabel(keyStr) - if !ok { - self.Fail("Unrecognized key: " + keyStr) - } + for _, keyStr := range keyStrs { + key, ok := config.KeyFromLabel(keyStr) + if !ok { + self.Fail("Unrecognized key: " + keyStr) + } - self.gui.g.ReplayKeyEvent(gocui.NewTcellKeyEventWrapper( - tcell.NewEventKey(tcell.Key(key.KeyName()), key.Str(), tcell.ModMask(key.Mod())), - 0, - )) + self.gui.g.ReplayKeyEvent(gocui.NewTcellKeyEventWrapper( + tcell.NewEventKey(tcell.Key(key.KeyName()), key.Str(), tcell.ModMask(key.Mod())), + 0, + )) + } self.waitTillIdle() } diff --git a/pkg/integration/components/test_driver.go b/pkg/integration/components/test_driver.go index 376b0f4d6..42ce8ac35 100644 --- a/pkg/integration/components/test_driver.go +++ b/pkg/integration/components/test_driver.go @@ -2,6 +2,7 @@ package components import ( "fmt" + "strings" "time" "github.com/jesseduffield/lazygit/pkg/config" @@ -42,6 +43,15 @@ func (self *TestDriver) pressFast(keyStr string) { self.Wait(self.inputDelay / 5) } +// presses the keys in immediate succession, without waiting for lazygit to +// become idle in between, to simulate a user typing faster than lazygit +// processes the input +func (self *TestDriver) pressRapidly(keyStrs []string) { + self.SetCaption(fmt.Sprintf("Pressing %s", strings.Join(keyStrs, ", "))) + self.gui.PressKeysRapidly(keyStrs...) + self.Wait(self.inputDelay) +} + func (self *TestDriver) click(x, y int) { self.SetCaption(fmt.Sprintf("Clicking %d, %d", x, y)) self.gui.Click(x, y) diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go index e7fd0b66a..8fd4417ea 100644 --- a/pkg/integration/components/test_test.go +++ b/pkg/integration/components/test_test.go @@ -30,6 +30,10 @@ func (self *fakeGuiDriver) PressKey(key string) { self.pressedKeys = append(self.pressedKeys, key) } +func (self *fakeGuiDriver) PressKeysRapidly(keys ...string) { + self.pressedKeys = append(self.pressedKeys, keys...) +} + func (self *fakeGuiDriver) Click(x, y int) { self.clickedCoordinates = append(self.clickedCoordinates, coordinate{x: x, y: y}) } diff --git a/pkg/integration/components/view_driver.go b/pkg/integration/components/view_driver.go index df4b9d7d8..920c610be 100644 --- a/pkg/integration/components/view_driver.go +++ b/pkg/integration/components/view_driver.go @@ -454,6 +454,19 @@ func (self *ViewDriver) PressFast(key config.Keybinding) *ViewDriver { return self } +// Presses the given keys in immediate succession, without waiting for lazygit +// to become idle in between (Press waits after every key). Use this to +// simulate a user typing faster than lazygit processes the input. +func (self *ViewDriver) PressRapidly(keys ...config.Keybinding) *ViewDriver { + self.IsFocused() + + self.t.pressRapidly(lo.Map(keys, func(key config.Keybinding, _ int) string { + return key[0] + })) + + return self +} + func (self *ViewDriver) Click(x, y int) *ViewDriver { offsetX, offsetY, _, _ := self.getView().Dimensions() diff --git a/pkg/integration/types/types.go b/pkg/integration/types/types.go index 34ce499cc..12009315a 100644 --- a/pkg/integration/types/types.go +++ b/pkg/integration/types/types.go @@ -23,6 +23,10 @@ type IntegrationTest interface { // this is the interface through which our integration tests interact with the lazygit gui type GuiDriver interface { PressKey(string) + // Like PressKey, but presses several keys in immediate succession, waiting + // for lazygit to become idle only after the last one. Use it to simulate a + // user typing faster than lazygit processes the input. + PressKeysRapidly(...string) Click(int, int) // Simulate the terminal window regaining focus (which triggers a reload of // changed config files)