diff --git a/pkg/app/app.go b/pkg/app/app.go index f8e267ee9..a16fbcc1f 100644 --- a/pkg/app/app.go +++ b/pkg/app/app.go @@ -23,6 +23,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/env" "github.com/jesseduffield/lazygit/pkg/gui" "github.com/jesseduffield/lazygit/pkg/i18n" + integrationTypes "github.com/jesseduffield/lazygit/pkg/integration/types" "github.com/jesseduffield/lazygit/pkg/logs" "github.com/jesseduffield/lazygit/pkg/updates" ) @@ -42,7 +43,7 @@ func Run( common *common.Common, startArgs appTypes.StartArgs, ) { - app, err := NewApp(config, common) + app, err := NewApp(config, startArgs.IntegrationTest, common) if err == nil { err = app.Run(startArgs) @@ -94,7 +95,7 @@ func newLogger(cfg config.AppConfigurer) *logrus.Entry { } // NewApp bootstrap a new application -func NewApp(config config.AppConfigurer, common *common.Common) (*App, error) { +func NewApp(config config.AppConfigurer, test integrationTypes.IntegrationTest, common *common.Common) (*App, error) { app := &App{ closers: []io.Closer{}, Config: config, @@ -128,7 +129,7 @@ func NewApp(config config.AppConfigurer, common *common.Common) (*App, error) { showRecentRepos = true } - app.Gui, err = gui.NewGui(common, config, gitVersion, updater, showRecentRepos, dirName) + app.Gui, err = gui.NewGui(common, config, gitVersion, updater, showRecentRepos, dirName, test) if err != nil { return app, err } diff --git a/pkg/cheatsheet/generate.go b/pkg/cheatsheet/generate.go index 392e9d64d..205abf7cb 100644 --- a/pkg/cheatsheet/generate.go +++ b/pkg/cheatsheet/generate.go @@ -61,7 +61,7 @@ func generateAtDir(cheatsheetDir string) { if err != nil { log.Fatal(err) } - mApp, _ := app.NewApp(mConfig, common) + mApp, _ := app.NewApp(mConfig, nil, common) path := cheatsheetDir + "/Keybindings_" + lang + ".md" file, err := os.Create(path) if err != nil { diff --git a/pkg/gui/dummies.go b/pkg/gui/dummies.go index 90bd094d8..144df1019 100644 --- a/pkg/gui/dummies.go +++ b/pkg/gui/dummies.go @@ -17,6 +17,6 @@ func NewDummyUpdater() *updates.Updater { func NewDummyGui() *Gui { newAppConfig := config.NewDummyAppConfig() - dummyGui, _ := NewGui(utils.NewDummyCommon(), newAppConfig, &git_commands.GitVersion{}, NewDummyUpdater(), false, "") + dummyGui, _ := NewGui(utils.NewDummyCommon(), newAppConfig, &git_commands.GitVersion{}, NewDummyUpdater(), false, "", nil) return dummyGui } diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index dd685dc72..6eaa1b8db 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -467,6 +467,7 @@ func NewGui( updater *updates.Updater, showRecentRepos bool, initialDir string, + test integrationTypes.IntegrationTest, ) (*Gui, error) { gui := &Gui{ Common: cmn, diff --git a/pkg/gui/gui_driver.go b/pkg/gui/gui_driver.go index c36e68e93..ddeb3fab4 100644 --- a/pkg/gui/gui_driver.go +++ b/pkg/gui/gui_driver.go @@ -20,6 +20,7 @@ import ( type GuiDriver struct { gui *Gui isIdleChan chan struct{} + toastChan chan string } var _ integrationTypes.GuiDriver = &GuiDriver{} @@ -133,3 +134,12 @@ func (self *GuiDriver) SetCaptionPrefix(prefix string) { self.gui.setCaptionPrefix(prefix) self.waitTillIdle() } + +func (self *GuiDriver) NextToast() *string { + select { + case t := <-self.toastChan: + return &t + default: + return nil + } +} diff --git a/pkg/gui/popup/popup_handler.go b/pkg/gui/popup/popup_handler.go index 33c01e0cc..82bf846e0 100644 --- a/pkg/gui/popup/popup_handler.go +++ b/pkg/gui/popup/popup_handler.go @@ -66,6 +66,10 @@ func (self *PopupHandler) Toast(message string) { self.toastFn(message) } +func (self *PopupHandler) SetToastFunc(f func(string)) { + self.toastFn = f +} + func (self *PopupHandler) WithWaitingStatus(message string, f func(gocui.Task) error) error { self.withWaitingStatusFn(message, f) return nil diff --git a/pkg/gui/test_mode.go b/pkg/gui/test_mode.go index 151cb7246..bc4436053 100644 --- a/pkg/gui/test_mode.go +++ b/pkg/gui/test_mode.go @@ -6,6 +6,7 @@ import ( "time" "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/gui/popup" "github.com/jesseduffield/lazygit/pkg/integration/components" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -32,7 +33,11 @@ func (gui *Gui) handleTestMode() { go func() { waitUntilIdle() - test.Run(&GuiDriver{gui: gui, isIdleChan: isIdleChan}) + toastChan := make(chan string, 100) + gui.PopupHandler.(*popup.PopupHandler).SetToastFunc( + func(message string) { toastChan <- message }) + + test.Run(&GuiDriver{gui: gui, isIdleChan: isIdleChan, toastChan: toastChan}) gui.g.Update(func(*gocui.Gui) error { return gocui.ErrQuit diff --git a/pkg/gui/types/common.go b/pkg/gui/types/common.go index 366b0fcf0..6e16df6b0 100644 --- a/pkg/gui/types/common.go +++ b/pkg/gui/types/common.go @@ -144,6 +144,7 @@ type IPopupHandler interface { WithWaitingStatusSync(message string, f func() error) error Menu(opts CreateMenuOptions) error Toast(message string) + SetToastFunc(func(string)) GetPromptInput() string } diff --git a/pkg/integration/components/test_driver.go b/pkg/integration/components/test_driver.go index a862dce06..d266dfb73 100644 --- a/pkg/integration/components/test_driver.go +++ b/pkg/integration/components/test_driver.go @@ -102,8 +102,19 @@ func (self *TestDriver) ExpectPopup() *Popup { return &Popup{t: self} } -func (self *TestDriver) ExpectToast(matcher *TextMatcher) { - self.Views().AppStatus().Content(matcher) +func (self *TestDriver) ExpectToast(matcher *TextMatcher) *TestDriver { + t := self.gui.NextToast() + if t == nil { + self.gui.Fail("Expected toast, but didn't get one") + } else { + self.matchString(matcher, "Unexpected toast message", + func() string { + return *t + }, + ) + } + + return self } func (self *TestDriver) ExpectClipboard(matcher *TextMatcher) { diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go index 99e52f5e9..fa4401de5 100644 --- a/pkg/integration/components/test_test.go +++ b/pkg/integration/components/test_test.go @@ -78,6 +78,10 @@ func (self *fakeGuiDriver) SetCaption(string) { func (self *fakeGuiDriver) SetCaptionPrefix(string) { } +func (self *fakeGuiDriver) NextToast() *string { + return nil +} + func TestManualFailure(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, diff --git a/pkg/integration/tests/tag/crud_annotated.go b/pkg/integration/tests/tag/crud_annotated.go index 930859c90..12fa16645 100644 --- a/pkg/integration/tests/tag/crud_annotated.go +++ b/pkg/integration/tests/tag/crud_annotated.go @@ -65,6 +65,7 @@ var CrudAnnotated = NewIntegrationTest(NewIntegrationTestArgs{ Title(Equals("Delete tag 'new-tag'?")). Content(Equals("Are you sure you want to delete the remote tag 'new-tag' from 'origin'?")). Confirm() + t.ExpectToast(Equals("Remote tag deleted")) }). Lines( MatchesRegexp(`new-tag.*message`).IsSelected(), diff --git a/pkg/integration/tests/tag/crud_lightweight.go b/pkg/integration/tests/tag/crud_lightweight.go index 6aab10dd1..dd6614683 100644 --- a/pkg/integration/tests/tag/crud_lightweight.go +++ b/pkg/integration/tests/tag/crud_lightweight.go @@ -70,6 +70,7 @@ var CrudLightweight = NewIntegrationTest(NewIntegrationTestArgs{ Title(Equals("Delete tag 'new-tag'?")). Content(Equals("Are you sure you want to delete the remote tag 'new-tag' from 'origin'?")). Confirm() + t.ExpectToast(Equals("Remote tag deleted")) }). Lines( MatchesRegexp(`new-tag.*initial commit`).IsSelected(), diff --git a/pkg/integration/types/types.go b/pkg/integration/types/types.go index 15a2d514f..b9b981d74 100644 --- a/pkg/integration/types/types.go +++ b/pkg/integration/types/types.go @@ -43,4 +43,6 @@ type GuiDriver interface { View(viewName string) *gocui.View SetCaption(caption string) SetCaptionPrefix(prefix string) + // Pop the next toast that was displayed; returns nil if there was none + NextToast() *string }