another integration test

This commit is contained in:
Jesse Duffield
2022-08-08 21:32:58 +10:00
parent 77881a9c7d
commit 225c563c63
46 changed files with 326 additions and 26 deletions

View File

@@ -2,8 +2,10 @@ package gui
import (
"fmt"
"strings"
"time"
guiTypes "github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/integration/types"
)
@@ -67,8 +69,23 @@ func (self *AssertImpl) CurrentBranchName(expectedViewName string) {
})
}
func (self *AssertImpl) InListContext() {
self.assertWithRetries(func() (bool, string) {
currentContext := self.gui.currentContext()
_, ok := currentContext.(guiTypes.IListContext)
return ok, fmt.Sprintf("Expected current context to be a list context, but got %s", currentContext.GetKey())
})
}
func (self *AssertImpl) SelectedLineContains(text string) {
self.assertWithRetries(func() (bool, string) {
line := self.gui.currentContext().GetView().SelectedLine()
return strings.Contains(line, text), fmt.Sprintf("Expected selected line to contain '%s', but got '%s'", text, line)
})
}
func (self *AssertImpl) assertWithRetries(test func() (bool, string)) {
waitTimes := []int{0, 100, 200, 400, 800, 1600}
waitTimes := []int{0, 1, 5, 10, 200, 500, 1000}
var message string
for _, waitTime := range waitTimes {
@@ -81,6 +98,10 @@ func (self *AssertImpl) assertWithRetries(test func() (bool, string)) {
}
}
self.Fail(message)
}
func (self *AssertImpl) Fail(message string) {
self.gui.g.Close()
// need to give the gui time to close
time.Sleep(time.Millisecond * 100)

View File

@@ -1,29 +1,45 @@
package gui
import (
"fmt"
"strings"
"time"
"github.com/gdamore/tcell/v2"
"github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
guiTypes "github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/integration/types"
)
type InputImpl struct {
g *gocui.Gui
keys config.KeybindingConfig
gui *Gui
keys config.KeybindingConfig
assert types.Assert
pushKeyDelay int
}
func NewInputImpl(gui *Gui, keys config.KeybindingConfig, assert types.Assert, pushKeyDelay int) *InputImpl {
return &InputImpl{
gui: gui,
keys: keys,
assert: assert,
pushKeyDelay: pushKeyDelay,
}
}
var _ types.Input = &InputImpl{}
func (self *InputImpl) PushKeys(keyStrs ...string) {
func (self *InputImpl) PressKeys(keyStrs ...string) {
for _, keyStr := range keyStrs {
self.pushKey(keyStr)
self.pressKey(keyStr)
}
}
func (self *InputImpl) pushKey(keyStr string) {
func (self *InputImpl) pressKey(keyStr string) {
self.Wait(self.pushKeyDelay)
key := keybindings.GetKey(keyStr)
var r rune
@@ -36,58 +52,115 @@ func (self *InputImpl) pushKey(keyStr string) {
tcellKey = tcell.Key(v)
}
self.g.ReplayedEvents.Keys <- gocui.NewTcellKeyEventWrapper(
self.gui.g.ReplayedEvents.Keys <- gocui.NewTcellKeyEventWrapper(
tcell.NewEventKey(tcellKey, r, tcell.ModNone),
0,
)
}
func (self *InputImpl) SwitchToStatusWindow() {
self.pushKey(self.keys.Universal.JumpToBlock[0])
self.pressKey(self.keys.Universal.JumpToBlock[0])
}
func (self *InputImpl) SwitchToFilesWindow() {
self.pushKey(self.keys.Universal.JumpToBlock[1])
self.pressKey(self.keys.Universal.JumpToBlock[1])
}
func (self *InputImpl) SwitchToBranchesWindow() {
self.pushKey(self.keys.Universal.JumpToBlock[2])
self.pressKey(self.keys.Universal.JumpToBlock[2])
}
func (self *InputImpl) SwitchToCommitsWindow() {
self.pushKey(self.keys.Universal.JumpToBlock[3])
self.pressKey(self.keys.Universal.JumpToBlock[3])
}
func (self *InputImpl) SwitchToStashWindow() {
self.pushKey(self.keys.Universal.JumpToBlock[4])
self.pressKey(self.keys.Universal.JumpToBlock[4])
}
func (self *InputImpl) Type(content string) {
for _, char := range content {
self.pushKey(string(char))
self.pressKey(string(char))
}
}
func (self *InputImpl) Confirm() {
self.pushKey(self.keys.Universal.Confirm)
self.pressKey(self.keys.Universal.Confirm)
}
func (self *InputImpl) Cancel() {
self.pushKey(self.keys.Universal.Return)
self.pressKey(self.keys.Universal.Return)
}
func (self *InputImpl) Select() {
self.pushKey(self.keys.Universal.Select)
self.pressKey(self.keys.Universal.Select)
}
func (self *InputImpl) NextItem() {
self.pushKey(self.keys.Universal.NextItem)
self.pressKey(self.keys.Universal.NextItem)
}
func (self *InputImpl) PreviousItem() {
self.pushKey(self.keys.Universal.PrevItem)
self.pressKey(self.keys.Universal.PrevItem)
}
func (self *InputImpl) ContinueMerge() {
self.PressKeys(self.keys.Universal.CreateRebaseOptionsMenu)
self.assert.SelectedLineContains("continue")
self.Confirm()
}
func (self *InputImpl) ContinueRebase() {
self.ContinueMerge()
}
func (self *InputImpl) Wait(milliseconds int) {
time.Sleep(time.Duration(milliseconds) * time.Millisecond)
}
func (self *InputImpl) log(message string) {
self.gui.c.LogAction(message)
}
// NOTE: this currently assumes that ViewBufferLines returns all the lines that can be accessed.
// If this changes in future, we'll need to update this code to first attempt to find the item
// in the current page and failing that, jump to the top of the view and iterate through all of it,
// looking for the item.
func (self *InputImpl) NavigateToListItemContainingText(text string) {
self.assert.InListContext()
currentContext := self.gui.currentContext().(guiTypes.IListContext)
view := currentContext.GetView()
// first we look for a duplicate on the current screen. We won't bother looking beyond that though.
matchCount := 0
matchIndex := -1
for i, line := range view.ViewBufferLines() {
if strings.Contains(line, text) {
matchCount++
matchIndex = i
}
}
if matchCount > 1 {
self.assert.Fail(fmt.Sprintf("Found %d matches for %s, expected only a single match", matchCount, text))
}
if matchCount == 1 {
selectedLineIdx := view.SelectedLineIdx()
if selectedLineIdx == matchIndex {
return
}
if selectedLineIdx < matchIndex {
for i := selectedLineIdx; i < matchIndex; i++ {
self.NextItem()
}
return
} else {
for i := selectedLineIdx; i > matchIndex; i-- {
self.PreviousItem()
}
return
}
}
self.assert.Fail(fmt.Sprintf("Could not find item containing text: %s", text))
}

View File

@@ -21,10 +21,15 @@ func (gui *Gui) handleTestMode() {
go func() {
time.Sleep(time.Millisecond * 100)
shell := &integration.ShellImpl{}
assert := &AssertImpl{gui: gui}
keys := gui.Config.GetUserConfig().Keybinding
input := NewInputImpl(gui, keys, assert, integration.KeyPressDelay())
test.Run(
&integration.ShellImpl{},
&InputImpl{g: gui.g, keys: gui.Config.GetUserConfig().Keybinding},
&AssertImpl{gui: gui},
shell,
input,
assert,
gui.c.UserConfig.Keybinding,
)