From 261f30f49c552e3abe3bb7378208b0b355595c86 Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sat, 3 Jun 2023 16:10:53 +1000 Subject: [PATCH] Add integration tests for searching/filtering --- pkg/gui/context.go | 3 +- pkg/gui/controllers/helpers/search_helper.go | 11 +- pkg/integration/components/int_matcher.go | 12 +- pkg/integration/components/menu_driver.go | 12 ++ pkg/integration/components/view_driver.go | 61 ++++++-- pkg/integration/tests/commit/search.go | 1 + .../filter_and_search/filter_commit_files.go | 84 ++++++++++ .../tests/filter_and_search/filter_files.go | 76 +++++++++ .../tests/filter_and_search/filter_menu.go | 48 ++++++ .../tests/filter_and_search/nested_filter.go | 147 ++++++++++++++++++ .../nested_filter_transient.go | 105 +++++++++++++ pkg/integration/tests/test_list.go | 6 + 12 files changed, 540 insertions(+), 26 deletions(-) create mode 100644 pkg/integration/tests/filter_and_search/filter_commit_files.go create mode 100644 pkg/integration/tests/filter_and_search/filter_files.go create mode 100644 pkg/integration/tests/filter_and_search/filter_menu.go create mode 100644 pkg/integration/tests/filter_and_search/nested_filter.go create mode 100644 pkg/integration/tests/filter_and_search/nested_filter_transient.go diff --git a/pkg/gui/context.go b/pkg/gui/context.go index fde888a1c..38e1212c7 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -201,7 +201,6 @@ func (self *ContextMgr) deactivateContext(c types.Context, opts types.OnFocusLos view, _ := self.gui.c.GocuiGui().View(c.GetViewName()) if opts.NewContextKey != context.SEARCH_CONTEXT_KEY { - self.gui.helpers.Search.HidePrompt() if c.GetKind() == types.MAIN_CONTEXT || c.GetKind() == types.TEMPORARY_POPUP { self.gui.helpers.Search.CancelSearchIfSearching(c) } @@ -235,7 +234,7 @@ func (self *ContextMgr) ActivateContext(c types.Context, opts types.OnFocusOpts) return err } - self.gui.helpers.Search.DisplaySearchStatusIfSearching(c) + self.gui.helpers.Search.RenderSearchStatus(c) desiredTitle := c.Title() if desiredTitle != "" { diff --git a/pkg/gui/controllers/helpers/search_helper.go b/pkg/gui/controllers/helpers/search_helper.go index 9f0e51e88..b244f20e4 100644 --- a/pkg/gui/controllers/helpers/search_helper.go +++ b/pkg/gui/controllers/helpers/search_helper.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/jesseduffield/gocui" + "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/keybindings" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/theme" @@ -198,19 +199,27 @@ func (self *SearchHelper) OnPromptContentChanged(searchString string) { } } -func (self *SearchHelper) DisplaySearchStatusIfSearching(c types.Context) { +func (self *SearchHelper) RenderSearchStatus(c types.Context) { + if c.GetKey() == context.SEARCH_CONTEXT_KEY { + return + } + if searchableContext, ok := c.(types.ISearchableContext); ok { if searchableContext.IsSearching() { self.setSearchingFrameColor() self.DisplaySearchStatus(searchableContext) + return } } if filterableContext, ok := c.(types.IFilterableContext); ok { if filterableContext.IsFiltering() { self.setSearchingFrameColor() self.DisplayFilterStatus(filterableContext) + return } } + + self.HidePrompt() } func (self *SearchHelper) CancelSearchIfSearching(c types.Context) { diff --git a/pkg/integration/components/int_matcher.go b/pkg/integration/components/int_matcher.go index c80a60c85..4cfd0f958 100644 --- a/pkg/integration/components/int_matcher.go +++ b/pkg/integration/components/int_matcher.go @@ -10,9 +10,9 @@ type IntMatcher struct { func (self *IntMatcher) EqualsInt(target int) *IntMatcher { self.appendRule(matcherRule[int]{ - name: fmt.Sprintf("equals '%d'", target), + name: fmt.Sprintf("equals %d", target), testFn: func(value int) (bool, string) { - return value == target, fmt.Sprintf("Expected '%d' to equal '%d'", value, target) + return value == target, fmt.Sprintf("Expected %d to equal %d", value, target) }, }) @@ -21,9 +21,9 @@ func (self *IntMatcher) EqualsInt(target int) *IntMatcher { func (self *IntMatcher) GreaterThan(target int) *IntMatcher { self.appendRule(matcherRule[int]{ - name: fmt.Sprintf("greater than '%d'", target), + name: fmt.Sprintf("greater than %d", target), testFn: func(value int) (bool, string) { - return value > target, fmt.Sprintf("Expected '%d' to greater than '%d'", value, target) + return value > target, fmt.Sprintf("Expected %d to greater than %d", value, target) }, }) @@ -32,9 +32,9 @@ func (self *IntMatcher) GreaterThan(target int) *IntMatcher { func (self *IntMatcher) LessThan(target int) *IntMatcher { self.appendRule(matcherRule[int]{ - name: fmt.Sprintf("less than '%d'", target), + name: fmt.Sprintf("less than %d", target), testFn: func(value int) (bool, string) { - return value < target, fmt.Sprintf("Expected '%d' to less than '%d'", value, target) + return value < target, fmt.Sprintf("Expected %d to less than %d", value, target) }, }) diff --git a/pkg/integration/components/menu_driver.go b/pkg/integration/components/menu_driver.go index ac620f5a4..4e0b0f6da 100644 --- a/pkg/integration/components/menu_driver.go +++ b/pkg/integration/components/menu_driver.go @@ -48,6 +48,18 @@ func (self *MenuDriver) TopLines(matchers ...*TextMatcher) *MenuDriver { return self } +func (self *MenuDriver) Filter(text string) *MenuDriver { + self.getViewDriver().FilterOrSearch(text) + + return self +} + +func (self *MenuDriver) LineCount(matcher *IntMatcher) *MenuDriver { + self.getViewDriver().LineCount(matcher) + + return self +} + func (self *MenuDriver) checkNecessaryChecksCompleted() { if !self.hasCheckedTitle { self.t.Fail("You must check the title of a menu popup by calling Title() before calling Confirm()/Cancel().") diff --git a/pkg/integration/components/view_driver.go b/pkg/integration/components/view_driver.go index db7e76134..2c4a23572 100644 --- a/pkg/integration/components/view_driver.go +++ b/pkg/integration/components/view_driver.go @@ -66,7 +66,7 @@ func (self *ViewDriver) Title(expected *TextMatcher) *ViewDriver { // If you only care about a subset of lines, use the ContainsLines method instead. func (self *ViewDriver) Lines(matchers ...*TextMatcher) *ViewDriver { self.validateMatchersPassed(matchers) - self.LineCount(len(matchers)) + self.LineCount(EqualsInt(len(matchers))) return self.assertLines(0, matchers...) } @@ -470,33 +470,60 @@ func (self *ViewDriver) IsEmpty() *ViewDriver { return self } -func (self *ViewDriver) LineCount(expectedCount int) *ViewDriver { - if expectedCount == 0 { - return self.IsEmpty() - } - +func (self *ViewDriver) LineCount(matcher *IntMatcher) *ViewDriver { view := self.getView() self.t.assertWithRetries(func() (bool, string) { - lines := view.BufferLines() - return len(lines) == expectedCount, fmt.Sprintf("unexpected number of lines in view '%s'. Expected %d, got %d", view.Name(), expectedCount, len(lines)) + lineCount := self.getLineCount() + ok, _ := matcher.test(lineCount) + return ok, fmt.Sprintf("unexpected number of lines in view '%s'. Expected %s, got %d", view.Name(), matcher.name(), lineCount) }) + return self +} + +func (self *ViewDriver) getLineCount() int { + // can't rely entirely on view.BufferLines because it returns 1 even if there's nothing in the view + if strings.TrimSpace(self.getView().Buffer()) == "" { + return 0 + } + + view := self.getView() + return len(view.BufferLines()) +} + +func (self *ViewDriver) IsVisible() *ViewDriver { self.t.assertWithRetries(func() (bool, string) { - lines := view.BufferLines() - - // if the view has a single blank line (often the case) we want to treat that as having no lines - if len(lines) == 1 && expectedCount == 1 { - actual := strings.TrimSpace(view.Buffer()) - return actual != "", fmt.Sprintf("unexpected number of lines in view '%s'. Expected 1, got 0", view.Name()) - } - - return len(lines) == expectedCount, fmt.Sprintf("unexpected number of lines in view '%s'. Expected %d, got %d", view.Name(), expectedCount, len(lines)) + return self.getView().Visible, fmt.Sprintf("%s: Expected view to be visible, but it was not", self.context) }) return self } +func (self *ViewDriver) IsInvisible() *ViewDriver { + self.t.assertWithRetries(func() (bool, string) { + return !self.getView().Visible, fmt.Sprintf("%s: Expected view to be visible, but it was not", self.context) + }) + + return self +} + +// will filter or search depending on whether the view supports filtering/searching +func (self *ViewDriver) FilterOrSearch(text string) *ViewDriver { + self.IsFocused() + + self.Press(self.t.keys.Universal.StartSearch). + Tap(func() { + self.t.ExpectSearch(). + Type(text). + Confirm() + + self.t.Views().Search().IsVisible().Content(Contains(fmt.Sprintf("matches for '%s'", text))) + }) + + return self +} + // for when you want to make some assertion unrelated to the current view // without breaking the method chain func (self *ViewDriver) Tap(f func()) *ViewDriver { diff --git a/pkg/integration/tests/commit/search.go b/pkg/integration/tests/commit/search.go index 1d9390dc7..c0a9dfd0b 100644 --- a/pkg/integration/tests/commit/search.go +++ b/pkg/integration/tests/commit/search.go @@ -42,6 +42,7 @@ var Search = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Universal.StartSearch). Tap(func() { t.ExpectSearch(). + Clear(). Type("o"). Confirm() diff --git a/pkg/integration/tests/filter_and_search/filter_commit_files.go b/pkg/integration/tests/filter_and_search/filter_commit_files.go new file mode 100644 index 000000000..a1a39f1f4 --- /dev/null +++ b/pkg/integration/tests/filter_and_search/filter_commit_files.go @@ -0,0 +1,84 @@ +package filter_and_search + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var FilterCommitFiles = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Basic commit file filtering by text", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.CreateDir("folder1") + shell.CreateFileAndAdd("folder1/apple-grape", "apple-grape") + shell.CreateFileAndAdd("folder1/apple-orange", "apple-orange") + shell.CreateFileAndAdd("folder1/grape-orange", "grape-orange") + shell.Commit("first commit") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + Lines( + Contains(`first commit`).IsSelected(), + ). + Press(keys.Universal.Confirm) + + t.Views().CommitFiles(). + IsFocused(). + Lines( + Contains(`folder1`).IsSelected(), + Contains(`apple-grape`), + Contains(`apple-orange`), + Contains(`grape-orange`), + ). + Press(keys.Files.ToggleTreeView). + Lines( + Contains(`folder1/apple-grape`).IsSelected(), + Contains(`folder1/apple-orange`), + Contains(`folder1/grape-orange`), + ). + FilterOrSearch("apple"). + Lines( + Contains(`folder1/apple-grape`).IsSelected(), + Contains(`folder1/apple-orange`), + ). + Press(keys.Files.ToggleTreeView). + // filter still applies when we toggle tree view + Lines( + Contains(`folder1`), + Contains(`apple-grape`).IsSelected(), + Contains(`apple-orange`), + ). + Press(keys.Files.ToggleTreeView). + Lines( + Contains(`folder1/apple-grape`).IsSelected(), + Contains(`folder1/apple-orange`), + ). + NavigateToLine(Contains(`folder1/apple-orange`)). + Press(keys.Universal.Return). + Lines( + Contains(`folder1/apple-grape`), + // selection is retained after escaping filter mode + Contains(`folder1/apple-orange`).IsSelected(), + Contains(`folder1/grape-orange`), + ). + Tap(func() { + t.Views().Search().IsInvisible() + }). + Press(keys.Files.ToggleTreeView). + Lines( + Contains(`folder1`), + Contains(`apple-grape`), + Contains(`apple-orange`).IsSelected(), + Contains(`grape-orange`), + ). + FilterOrSearch("folder1/grape"). + Lines( + // first item is always selected after filtering + Contains(`folder1`).IsSelected(), + Contains(`grape-orange`), + ) + }, +}) diff --git a/pkg/integration/tests/filter_and_search/filter_files.go b/pkg/integration/tests/filter_and_search/filter_files.go new file mode 100644 index 000000000..5a029b146 --- /dev/null +++ b/pkg/integration/tests/filter_and_search/filter_files.go @@ -0,0 +1,76 @@ +package filter_and_search + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var FilterFiles = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Basic file filtering by text", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.CreateDir("folder1") + shell.CreateFile("folder1/apple-grape", "apple-grape") + shell.CreateFile("folder1/apple-orange", "apple-orange") + shell.CreateFile("folder1/grape-orange", "grape-orange") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + Focus(). + Lines( + Contains(`folder1`).IsSelected(), + Contains(`apple-grape`), + Contains(`apple-orange`), + Contains(`grape-orange`), + ). + Press(keys.Files.ToggleTreeView). + Lines( + Contains(`folder1/apple-grape`).IsSelected(), + Contains(`folder1/apple-orange`), + Contains(`folder1/grape-orange`), + ). + FilterOrSearch("apple"). + Lines( + Contains(`folder1/apple-grape`).IsSelected(), + Contains(`folder1/apple-orange`), + ). + Press(keys.Files.ToggleTreeView). + // filter still applies when we toggle tree view + Lines( + Contains(`folder1`), + Contains(`apple-grape`).IsSelected(), + Contains(`apple-orange`), + ). + Press(keys.Files.ToggleTreeView). + Lines( + Contains(`folder1/apple-grape`).IsSelected(), + Contains(`folder1/apple-orange`), + ). + NavigateToLine(Contains(`folder1/apple-orange`)). + Press(keys.Universal.Return). + Lines( + Contains(`folder1/apple-grape`), + // selection is retained after escaping filter mode + Contains(`folder1/apple-orange`).IsSelected(), + Contains(`folder1/grape-orange`), + ). + Tap(func() { + t.Views().Search().IsInvisible() + }). + Press(keys.Files.ToggleTreeView). + Lines( + Contains(`folder1`), + Contains(`apple-grape`), + Contains(`apple-orange`).IsSelected(), + Contains(`grape-orange`), + ). + FilterOrSearch("folder1/grape"). + Lines( + // first item is always selected after filtering + Contains(`folder1`).IsSelected(), + Contains(`grape-orange`), + ) + }, +}) diff --git a/pkg/integration/tests/filter_and_search/filter_menu.go b/pkg/integration/tests/filter_and_search/filter_menu.go new file mode 100644 index 000000000..5dc15b663 --- /dev/null +++ b/pkg/integration/tests/filter_and_search/filter_menu.go @@ -0,0 +1,48 @@ +package filter_and_search + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var FilterMenu = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Filtering the keybindings menu", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + shell.CreateFile("myfile", "myfile") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Files(). + IsFocused(). + Lines( + Contains(`??`).Contains(`myfile`).IsSelected(), + ). + Press(keys.Universal.OptionMenu). + Tap(func() { + t.ExpectPopup().Menu(). + Title(Equals("Keybindings")). + Filter("Toggle staged"). + Lines( + // menu has filtered down to the one item that matches the filter + Contains(`Toggle staged`).IsSelected(), + ). + Confirm() + }) + + t.Views().Files(). + IsFocused(). + Lines( + // file has been staged + Contains(`A `).Contains(`myfile`).IsSelected(), + ). + // Upon opening the menu again, the filter should have been reset + Press(keys.Universal.OptionMenu). + Tap(func() { + t.ExpectPopup().Menu(). + Title(Equals("Keybindings")). + LineCount(GreaterThan(1)) + }) + }, +}) diff --git a/pkg/integration/tests/filter_and_search/nested_filter.go b/pkg/integration/tests/filter_and_search/nested_filter.go new file mode 100644 index 000000000..7dad9d61a --- /dev/null +++ b/pkg/integration/tests/filter_and_search/nested_filter.go @@ -0,0 +1,147 @@ +package filter_and_search + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var NestedFilter = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Filter in the several nested panels and verify the filters are preserved as you escape back to the surface", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + // need to create some branches, each with their own commits + shell.NewBranch("branch-gold") + shell.CreateFileAndAdd("apple", "apple") + shell.CreateFileAndAdd("orange", "orange") + shell.CreateFileAndAdd("grape", "grape") + shell.Commit("commit-knife") + + shell.NewBranch("branch-silver") + shell.UpdateFileAndAdd("apple", "apple-2") + shell.UpdateFileAndAdd("orange", "orange-2") + shell.UpdateFileAndAdd("grape", "grape-2") + shell.Commit("commit-spoon") + + shell.NewBranch("branch-bronze") + shell.UpdateFileAndAdd("apple", "apple-3") + shell.UpdateFileAndAdd("orange", "orange-3") + shell.UpdateFileAndAdd("grape", "grape-3") + shell.Commit("commit-fork") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). + Focus(). + Lines( + Contains(`branch-bronze`).IsSelected(), + Contains(`branch-silver`), + Contains(`branch-gold`), + ). + FilterOrSearch("sil"). + Lines( + Contains(`branch-silver`).IsSelected(), + ). + PressEnter() + + t.Views().SubCommits(). + IsFocused(). + Lines( + Contains(`commit-spoon`).IsSelected(), + Contains(`commit-knife`), + ). + FilterOrSearch("knife"). + Lines( + // sub-commits view searches, it doesn't filter, so we haven't filtered down the list + Contains(`commit-spoon`), + Contains(`commit-knife`).IsSelected(), + ). + PressEnter() + + t.Views().CommitFiles(). + IsFocused(). + Lines( + Contains(`apple`).IsSelected(), + Contains(`grape`), + Contains(`orange`), + ). + FilterOrSearch("grape"). + Lines( + Contains(`grape`).IsSelected(), + ). + PressEnter() + + t.Views().PatchBuilding(). + IsFocused(). + FilterOrSearch("newline"). + SelectedLine(Contains("No newline at end of file")). + PressEscape(). // cancel search + Tap(func() { + t.Views().Search().IsInvisible() + }). + // escape to commit-files view + PressEscape() + + t.Views().CommitFiles(). + IsFocused(). + Lines( + Contains(`grape`).IsSelected(), + ). + Tap(func() { + t.Views().Search().IsVisible().Content(Contains("matches for 'grape'")) + }). + // cancel search + PressEscape(). + Tap(func() { + t.Views().Search().IsInvisible() + }). + Lines( + Contains(`apple`), + Contains(`grape`).IsSelected(), + Contains(`orange`), + ). + // escape to sub-commits view + PressEscape() + + t.Views().SubCommits(). + IsFocused(). + Lines( + Contains(`commit-spoon`), + Contains(`commit-knife`).IsSelected(), + ). + Tap(func() { + t.Views().Search().IsVisible().Content(Contains("matches for 'knife'")) + }). + // cancel search + PressEscape(). + Tap(func() { + t.Views().Search().IsInvisible() + }). + Lines( + Contains(`commit-spoon`), + // still selected + Contains(`commit-knife`).IsSelected(), + ). + // escape to branches view + PressEscape() + + t.Views().Branches(). + IsFocused(). + Lines( + Contains(`branch-silver`).IsSelected(), + ). + Tap(func() { + t.Views().Search().IsVisible().Content(Contains("matches for 'sil'")) + }). + // cancel search + PressEscape(). + Tap(func() { + t.Views().Search().IsInvisible() + }). + Lines( + Contains(`branch-bronze`), + Contains(`branch-silver`).IsSelected(), + Contains(`branch-gold`), + ) + }, +}) diff --git a/pkg/integration/tests/filter_and_search/nested_filter_transient.go b/pkg/integration/tests/filter_and_search/nested_filter_transient.go new file mode 100644 index 000000000..300519784 --- /dev/null +++ b/pkg/integration/tests/filter_and_search/nested_filter_transient.go @@ -0,0 +1,105 @@ +package filter_and_search + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +// This one requires some explanation: the sub-commits and diff-file contexts are +// 'transient' in that they are spawned inside a window when you need them, but +// can be relocated elsewhere if you need them somewhere else. So for example if +// I hit enter on a branch I'll see the sub-commits view, but if I then navigate +// to the reflog context and hit enter on a reflog, the sub-commits view is moved +// to the reflog window. This is because we re-use the same view (it's a limitation +// that would be nice to remove in the future). +// Nonetheless, we need to ensure that upon moving the view, the filter is cancelled. + +var NestedFilterTransient = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Filter in a transient panel (sub-commits and diff-files) and ensure filter is cancelled when the panel is moved", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) {}, + SetupRepo: func(shell *Shell) { + // need to create some branches, each with their own commits + shell.NewBranch("mybranch") + shell.CreateFileAndAdd("file-one", "file-one") + shell.CreateFileAndAdd("file-two", "file-two") + shell.Commit("commit-one") + shell.EmptyCommit("commit-two") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Branches(). + Focus(). + Lines( + Contains(`mybranch`).IsSelected(), + ). + PressEnter() + + t.Views().SubCommits(). + IsFocused(). + Lines( + Contains(`commit-two`).IsSelected(), + Contains(`commit-one`), + ). + FilterOrSearch("one"). + Lines( + Contains(`commit-two`), + Contains(`commit-one`).IsSelected(), + ) + + t.Views().ReflogCommits(). + Focus(). + SelectedLine(Contains("commit: commit-two")). + PressEnter() + + t.Views().SubCommits(). + IsFocused(). + // the search on the sub-commits context has been cancelled + Lines( + Contains(`commit-two`).IsSelected(), + Contains(`commit-one`), + ). + Tap(func() { + t.Views().Search().IsInvisible() + }). + NavigateToLine(Contains("commit-one")). + PressEnter() + + // Now let's test the commit files context + t.Views().CommitFiles(). + IsFocused(). + Lines( + Contains(`file-one`).IsSelected(), + Contains(`file-two`), + ). + FilterOrSearch("one"). + Lines( + Contains(`file-one`).IsSelected(), + ) + + t.Views().Branches(). + Focus(). + SelectedLine(Contains("mybranch")). + PressEnter() + + t.Views().SubCommits(). + IsFocused(). + Lines( + Contains(`commit-two`).IsSelected(), + Contains(`commit-one`), + ). + NavigateToLine(Contains("commit-one")). + PressEnter() + + t.Views().CommitFiles(). + IsFocused(). + // the search on the commit-files context has been cancelled + Lines( + Contains(`file-one`).IsSelected(), + Contains(`file-two`), + ). + Tap(func() { + t.Views().Search().IsInvisible() + }) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 9665f616e..e3a6e51dd 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -13,6 +13,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/integration/tests/custom_commands" "github.com/jesseduffield/lazygit/pkg/integration/tests/diff" "github.com/jesseduffield/lazygit/pkg/integration/tests/file" + "github.com/jesseduffield/lazygit/pkg/integration/tests/filter_and_search" "github.com/jesseduffield/lazygit/pkg/integration/tests/filter_by_path" "github.com/jesseduffield/lazygit/pkg/integration/tests/interactive_rebase" "github.com/jesseduffield/lazygit/pkg/integration/tests/misc" @@ -94,6 +95,11 @@ var tests = []*components.IntegrationTest{ file.DiscardUnstagedFileChanges, file.Gitignore, file.RememberCommitMessageAfterFail, + filter_and_search.FilterCommitFiles, + filter_and_search.FilterFiles, + filter_and_search.FilterMenu, + filter_and_search.NestedFilter, + filter_and_search.NestedFilterTransient, filter_by_path.CliArg, filter_by_path.SelectFile, filter_by_path.TypeFile,