another integration test
This commit is contained in:
@@ -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)
|
||||
|
||||
107
pkg/gui/input.go
107
pkg/gui/input.go
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user