From f7e8b2dd7194ef32f6644481c974602bd8059c9c Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sun, 26 Feb 2023 11:49:15 +1100 Subject: [PATCH] cleanup integration test code --- .gitignore | 2 +- .../hosting_service/hosting_service_test.go | 4 +- pkg/{test => fakes}/log.go | 2 +- pkg/integration/README.md | 32 +++++---- pkg/integration/clients/cli.go | 9 ++- pkg/integration/clients/tui.go | 2 +- .../components/assertion_helper.go | 2 +- .../components/{actions.go => common.go} | 16 ++--- pkg/integration/components/menu_driver.go | 2 +- pkg/integration/components/paths.go | 4 +- pkg/integration/components/prompt_driver.go | 2 +- pkg/integration/components/runner.go | 8 ++- pkg/integration/components/shell.go | 25 ++++++- pkg/integration/components/test.go | 2 +- pkg/integration/components/test_driver.go | 4 +- pkg/integration/components/test_test.go | 2 + pkg/integration/components/viewDriver.go | 6 +- pkg/integration/components/views.go | 10 --- pkg/integration/tests/bisect/basic.go | 4 +- pkg/integration/tests/branch/rebase.go | 4 +- .../tests/branch/rebase_and_drop.go | 4 +- .../cherry_pick/cherry_pick_conflicts.go | 4 +- .../tests/conflicts/resolve_externally.go | 2 +- .../tests/conflicts/resolve_multiple_files.go | 2 +- pkg/integration/tests/file/discard_changes.go | 2 +- .../tests/filter_by_path/select_file.go | 37 ---------- .../tests/filter_by_path/shared.go | 42 ++++++++++++ .../interactive_rebase/amend_first_commit.go | 2 +- .../interactive_rebase/edit_first_commit.go | 4 +- .../interactive_rebase/fixup_first_commit.go | 2 +- .../interactive_rebase/fixup_second_commit.go | 2 +- .../interactive_rebase/move_in_rebase.go | 4 +- .../tests/interactive_rebase/rebase.go | 6 +- .../interactive_rebase/reword_first_commit.go | 2 +- .../tests/interactive_rebase/shared.go | 68 +++++++++++++++++++ .../squash_down_first_commit.go | 2 +- .../squash_down_second_commit.go | 2 +- .../squash_fixups_above_first_commit.go | 4 +- .../swap_in_rebase_with_conflict.go | 67 +----------------- pkg/integration/tests/patch_building/apply.go | 2 +- .../tests/patch_building/apply_in_reverse.go | 2 +- .../patch_building/copy_patch_to_clipboard.go | 2 +- .../tests/patch_building/move_to_index.go | 2 +- .../patch_building/move_to_index_partial.go | 4 +- .../move_to_index_with_conflict.go | 6 +- .../patch_building/move_to_new_commit.go | 2 +- .../patch_building/remove_from_commit.go | 2 +- .../patch_building/specific_selection.go | 10 +-- .../tests/patch_building/start_new_patch.go | 2 +- .../tests/staging/discard_all_changes.go | 4 +- pkg/integration/tests/staging/stage_hunks.go | 2 +- pkg/integration/tests/staging/stage_ranges.go | 6 +- pkg/integration/tests/submodule/add.go | 2 +- pkg/integration/tests/submodule/enter.go | 3 +- pkg/integration/tests/submodule/remove.go | 3 +- pkg/integration/tests/submodule/reset.go | 3 +- .../sync/force_push_multiple_upstream.go | 19 ------ .../tests/sync/pull_merge_conflict.go | 4 +- .../tests/sync/pull_rebase_conflict.go | 4 +- .../sync/pull_rebase_interactive_conflict.go | 4 +- .../pull_rebase_interactive_conflict_drop.go | 4 +- pkg/integration/tests/sync/push.go | 25 ------- .../tests/sync/push_with_credential_prompt.go | 3 +- pkg/integration/tests/sync/shared.go | 49 +++++++++++++ .../tests/{tests_gen.go => test_list.go} | 0 ...ts_generator.go => test_list_generator.go} | 6 +- pkg/integration/tests/tests.go | 15 ++-- test/README.md | 2 + test/{hooks => files}/pre-push | 0 test/global_git_config | 2 + 70 files changed, 322 insertions(+), 272 deletions(-) rename pkg/{test => fakes}/log.go (98%) rename pkg/integration/components/{actions.go => common.go} (67%) create mode 100644 pkg/integration/tests/filter_by_path/shared.go create mode 100644 pkg/integration/tests/interactive_rebase/shared.go create mode 100644 pkg/integration/tests/sync/shared.go rename pkg/integration/tests/{tests_gen.go => test_list.go} (100%) rename pkg/integration/tests/{tests_generator.go => test_list_generator.go} (95%) create mode 100644 test/README.md rename test/{hooks => files}/pre-push (100%) mode change 100644 => 100755 diff --git a/.gitignore b/.gitignore index 57f63c955..09b2235f1 100644 --- a/.gitignore +++ b/.gitignore @@ -35,7 +35,7 @@ lazygit.exe test/git_server/data -test/integration/** +test/results/** oryxBuildBinary __debug_bin diff --git a/pkg/commands/hosting_service/hosting_service_test.go b/pkg/commands/hosting_service/hosting_service_test.go index ded310c85..d67d94ed8 100644 --- a/pkg/commands/hosting_service/hosting_service_test.go +++ b/pkg/commands/hosting_service/hosting_service_test.go @@ -3,8 +3,8 @@ package hosting_service import ( "testing" + "github.com/jesseduffield/lazygit/pkg/fakes" "github.com/jesseduffield/lazygit/pkg/i18n" - "github.com/jesseduffield/lazygit/pkg/test" "github.com/stretchr/testify/assert" ) @@ -328,7 +328,7 @@ func TestGetPullRequestURL(t *testing.T) { s := s t.Run(s.testName, func(t *testing.T) { tr := i18n.EnglishTranslationSet() - log := &test.FakeFieldLogger{} + log := &fakes.FakeFieldLogger{} hostingServiceMgr := NewHostingServiceMgr(log, &tr, s.remoteUrl, s.configServiceDomains) s.test(hostingServiceMgr.GetPullRequestURL(s.from, s.to)) log.AssertErrors(t, s.expectedLoggedErrors) diff --git a/pkg/test/log.go b/pkg/fakes/log.go similarity index 98% rename from pkg/test/log.go rename to pkg/fakes/log.go index 32d79b987..fc68f23c1 100644 --- a/pkg/test/log.go +++ b/pkg/fakes/log.go @@ -1,4 +1,4 @@ -package test +package fakes import ( "fmt" diff --git a/pkg/integration/README.md b/pkg/integration/README.md index 598810a82..6dfadd8f8 100644 --- a/pkg/integration/README.md +++ b/pkg/integration/README.md @@ -16,7 +16,7 @@ go run cmd/integration_test/main.go cli [--slow or --sandbox] [testname or testp ## Writing tests -The tests live in pkg/integration/tests. Each test is listed in `pkg/integration/tests/tests_gen.go` which is an auto-generated file. You can re-generate that file by running `go generate ./...` at the root of the Lazygit repo. +The tests live in pkg/integration/tests. Each test is registered in `pkg/integration/tests/test_list.go` which is an auto-generated file. You can re-generate that file by running `go generate ./...` at the root of the Lazygit repo. Each test has two important steps: the setup step and the run step. @@ -34,18 +34,6 @@ The run step has two arguments passed in: `t` is for driving the gui by pressing certain keys, selecting list items, etc. `keys` is for use when getting the test to press a particular key e.g. `t.Views().Commits().Focus().PressKey(keys.Universal.Confirm)` -### Tips - -#### Handle most setup in the `shell` part of the test - -Try to do as much setup work as possible in your setup step. For example, if all you're testing is that the user is able to resolve merge conflicts, create the merge conflicts in the setup step. On the other hand, if you're testing to see that lazygit can warn the user about merge conflicts after an attempted merge, it's fine to wait until the run step to actually create the conflicts. If the run step is focused on the thing you're trying to test, the test will run faster and its intent will be clearer. - -#### Create helper functions for (very) frequently used test logic - -If you find yourself doing something frequently in a test, consider making it a method in one of the helper arguments. For example, instead of calling `t.PressKey(keys.Universal.Confirm)` in 100 places, it's better to have a method `t.Confirm()`. This is not to say that everything should be made into a helper method: just things that are particularly common in tests. - -Also, given how often we need to select a menu item or type into a prompt panel, there are some helper functions for that. See `ExpectConfirmation` for an example. - ## Running tests There are three ways to invoke a test: @@ -62,7 +50,7 @@ The name of a test is based on its path, so the name of the test at `pkg/integra You can pass the KEY_PRESS_DELAY env var to the test runner in order to set a delay in milliseconds between keypresses, which helps for watching a test at a realistic speed to understand what it's doing. Or you can pass the '--slow' flag which sets a pre-set 'slow' key delay. In the tui you can press 't' to run the test in slow mode. -The resultant repo will be stored in `test/integration`, so if you're not sure what went wrong you can go there and inspect the repo. +The resultant repo will be stored in `test/results`, so if you're not sure what went wrong you can go there and inspect the repo. ### Running tests in VSCode @@ -78,3 +66,19 @@ The test will run in a VSCode terminal: Say you want to do a manual test of how lazygit handles merge-conflicts, but you can't be bothered actually finding a way to create merge conflicts in a repo. To make your life easier, you can simply run a merge-conflicts test in sandbox mode, meaning the setup step is run for you, and then instead of the test driving the lazygit session, you're allowed to drive it yourself. To run a test in sandbox mode you can press 's' on a test in the test TUI or in the test runner pass the --sandbox argument. + +## Tips for writing tests + +### Handle most setup in the `shell` part of the test + +Try to do as much setup work as possible in your setup step. For example, if all you're testing is that the user is able to resolve merge conflicts, create the merge conflicts in the setup step. On the other hand, if you're testing to see that lazygit can warn the user about merge conflicts after an attempted merge, it's fine to wait until the run step to actually create the conflicts. If the run step is focused on the thing you're trying to test, the test will run faster and its intent will be clearer. + +### Create helper functions for (very) frequently used test logic + +If within a test directory you find several tests need to share some logic, you can create a file called `shared.go` in that directory to hold shared helper functions (see `pkg/integration/tests/filter_by_path/shared.go` for an example). + +If you need to share test logic across test directories you can put helper functions in the `tests/shared` package. If you find yourself frequently doing the same thing from within a test across test directories, for example, responding a particular popup, consider adding a helper method to `pkg/integration/components/common.go`. If you look around the code in the `components` directory you may find another place that's sensible to put your helper function. + +### Don't do too much in one test + +If you're testing different pieces of functionality, it's better to test them in isolation using multiple short tests, compared to one larger longer test. Sometimes it's appropriate to have a longer test which tests how various different pieces interact, but err on the side of keeping things short. diff --git a/pkg/integration/clients/cli.go b/pkg/integration/clients/cli.go index 1030d7690..8ac9947e9 100644 --- a/pkg/integration/clients/cli.go +++ b/pkg/integration/clients/cli.go @@ -11,6 +11,7 @@ import ( "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/integration/components" "github.com/jesseduffield/lazygit/pkg/integration/tests" + "github.com/samber/lo" ) // see pkg/integration/README.md @@ -65,6 +66,12 @@ func getTestsToRun(testNames []string) []*components.IntegrationTest { ) }) + if lo.SomeBy(testNames, func(name string) bool { + return strings.HasSuffix(name, "/shared") + }) { + log.Fatalf("'shared' is a reserved name for tests that are shared between multiple test files. Please rename your test.") + } + outer: for _, testName := range testNames { // check if our given test name actually exists @@ -74,7 +81,7 @@ outer: continue outer } } - log.Fatalf("test %s not found. Perhaps you forgot to add it to `pkg/integration/integration_tests/tests_gen.go`? This can be done by running `go generate ./...` from the Lazygit root. You'll need to ensure that your test name and the file name match (where the test name is in PascalCase and the file name is in snake_case).", testName) + log.Fatalf("test %s not found. Perhaps you forgot to add it to `pkg/integration/integration_tests/test_list.go`? This can be done by running `go generate ./...` from the Lazygit root. You'll need to ensure that your test name and the file name match (where the test name is in PascalCase and the file name is in snake_case).", testName) } return testsToRun diff --git a/pkg/integration/clients/tui.go b/pkg/integration/clients/tui.go index 10bfcf748..f93f4589a 100644 --- a/pkg/integration/clients/tui.go +++ b/pkg/integration/clients/tui.go @@ -137,7 +137,7 @@ func RunTUI() { return nil } - cmd := secureexec.Command("sh", "-c", fmt.Sprintf("code test/integration/%s", currentTest.Name())) + cmd := secureexec.Command("sh", "-c", fmt.Sprintf("code test/results/%s", currentTest.Name())) if err := cmd.Run(); err != nil { return err } diff --git a/pkg/integration/components/assertion_helper.go b/pkg/integration/components/assertion_helper.go index b60bda17b..4ae785db2 100644 --- a/pkg/integration/components/assertion_helper.go +++ b/pkg/integration/components/assertion_helper.go @@ -18,7 +18,7 @@ func retryWaitTimes() []int { // give it more leeway compared to when we're running things locally. return []int{0, 1, 1, 1, 1, 1, 5, 10, 20, 40, 100, 200, 500, 1000, 2000, 4000} } else { - return []int{0, 1, 1, 1, 1, 1, 5, 10, 20, 40, 100} + return []int{0, 1, 1, 1, 1, 1, 5, 10, 20, 40, 100, 200} } } diff --git a/pkg/integration/components/actions.go b/pkg/integration/components/common.go similarity index 67% rename from pkg/integration/components/actions.go rename to pkg/integration/components/common.go index 5e37fc966..7be48e4bd 100644 --- a/pkg/integration/components/actions.go +++ b/pkg/integration/components/common.go @@ -1,12 +1,12 @@ package components // for running common actions -type Actions struct { +type Common struct { t *TestDriver } -func (self *Actions) ContinueMerge() { - self.t.Views().current().Press(self.t.keys.Universal.CreateRebaseOptionsMenu) +func (self *Common) ContinueMerge() { + self.t.GlobalPress(self.t.keys.Universal.CreateRebaseOptionsMenu) self.t.ExpectPopup().Menu(). Title(Equals("Rebase Options")). @@ -14,32 +14,32 @@ func (self *Actions) ContinueMerge() { Confirm() } -func (self *Actions) ContinueRebase() { +func (self *Common) ContinueRebase() { self.ContinueMerge() } -func (self *Actions) AcknowledgeConflicts() { +func (self *Common) AcknowledgeConflicts() { self.t.ExpectPopup().Confirmation(). Title(Equals("Auto-merge failed")). Content(Contains("Conflicts!")). Confirm() } -func (self *Actions) ContinueOnConflictsResolved() { +func (self *Common) ContinueOnConflictsResolved() { self.t.ExpectPopup().Confirmation(). Title(Equals("continue")). Content(Contains("all merge conflicts resolved. Continue?")). Confirm() } -func (self *Actions) ConfirmDiscardLines() { +func (self *Common) ConfirmDiscardLines() { self.t.ExpectPopup().Confirmation(). Title(Equals("Unstage lines")). Content(Contains("Are you sure you want to delete the selected lines")). Confirm() } -func (self *Actions) SelectPatchOption(matcher *Matcher) { +func (self *Common) SelectPatchOption(matcher *Matcher) { self.t.GlobalPress(self.t.keys.Universal.CreatePatchOptionsMenu) self.t.ExpectPopup().Menu().Title(Equals("Patch Options")).Select(matcher).Confirm() diff --git a/pkg/integration/components/menu_driver.go b/pkg/integration/components/menu_driver.go index 326435f52..4092879da 100644 --- a/pkg/integration/components/menu_driver.go +++ b/pkg/integration/components/menu_driver.go @@ -31,7 +31,7 @@ func (self *MenuDriver) Cancel() { } func (self *MenuDriver) Select(option *Matcher) *MenuDriver { - self.getViewDriver().NavigateToListItem(option) + self.getViewDriver().NavigateToLine(option) return self } diff --git a/pkg/integration/components/paths.go b/pkg/integration/components/paths.go index 43468f509..bacc96f81 100644 --- a/pkg/integration/components/paths.go +++ b/pkg/integration/components/paths.go @@ -3,9 +3,9 @@ package components import "path/filepath" // convenience struct for easily getting directories within our test directory. -// We have one test directory for each test, found in test/integration. +// We have one test directory for each test, found in test/results. type Paths struct { - // e.g. test/integration/test_name + // e.g. test/results/test_name root string } diff --git a/pkg/integration/components/prompt_driver.go b/pkg/integration/components/prompt_driver.go index 58051bc70..d21d6f95e 100644 --- a/pkg/integration/components/prompt_driver.go +++ b/pkg/integration/components/prompt_driver.go @@ -79,6 +79,6 @@ func (self *PromptDriver) ConfirmSuggestion(matcher *Matcher) { self.t.press(self.t.keys.Universal.TogglePanel) self.t.Views().Suggestions(). IsFocused(). - NavigateToListItem(matcher). + NavigateToLine(matcher). PressEnter() } diff --git a/pkg/integration/components/runner.go b/pkg/integration/components/runner.go index 394ac00df..43e4f9304 100644 --- a/pkg/integration/components/runner.go +++ b/pkg/integration/components/runner.go @@ -11,14 +11,16 @@ import ( "github.com/jesseduffield/lazygit/pkg/commands/oscommands" ) -// this is the integration runner for the new and improved integration interface - const ( TEST_NAME_ENV_VAR = "TEST_NAME" SANDBOX_ENV_VAR = "SANDBOX" GIT_CONFIG_GLOBAL_ENV_VAR = "GIT_CONFIG_GLOBAL" ) +// This function lets you run tests either from within `go test` or from a regular binary. +// The reason for having two separate ways of testing is that `go test` isn't great at +// showing what's actually happening during the test, but it's still good at running +// tests in telling you about their results. func RunTests( tests []*IntegrationTest, logf func(format string, formatArgs ...interface{}), @@ -34,7 +36,7 @@ func RunTests( return err } - testDir := filepath.Join(projectRootDir, "test", "integration_new") + testDir := filepath.Join(projectRootDir, "test", "results") if err := buildLazygit(); err != nil { return err diff --git a/pkg/integration/components/shell.go b/pkg/integration/components/shell.go index 2f2d4b719..3c5177949 100644 --- a/pkg/integration/components/shell.go +++ b/pkg/integration/components/shell.go @@ -38,6 +38,15 @@ func (self *Shell) RunCommand(cmdStr string) *Shell { return self } +// Help files are located at test/files from the root the lazygit repo. +// E.g. You may want to create a pre-commit hook file there, then call this +// function to copy it into your test repo. +func (self *Shell) CopyHelpFile(source string, destination string) *Shell { + self.RunCommand(fmt.Sprintf("cp ../../../../../files/%s %s", source, destination)) + + return self +} + func (self *Shell) runCommandWithOutput(cmdStr string) (string, error) { args := str.ToArgv(cmdStr) cmd := secureexec.Command(args[0], args[1:]...) @@ -190,13 +199,27 @@ func (self *Shell) SetConfig(key string, value string) *Shell { // creates a clone of the repo in a sibling directory and adds the clone // as a remote, then fetches it. func (self *Shell) CloneIntoRemote(name string) *Shell { - self.RunCommand(fmt.Sprintf("git clone --bare . ../%s", name)) + self.Clone(name) self.RunCommand(fmt.Sprintf("git remote add %s ../%s", name, name)) self.RunCommand(fmt.Sprintf("git fetch %s", name)) return self } +func (self *Shell) CloneIntoSubmodule(submoduleName string) *Shell { + self.Clone("other_repo") + self.RunCommand(fmt.Sprintf("git submodule add ../other_repo %s", submoduleName)) + + return self +} + +// clones repo into a sibling directory +func (self *Shell) Clone(repoName string) *Shell { + self.RunCommand(fmt.Sprintf("git clone --bare . ../%s", repoName)) + + return self +} + // e.g. branch: 'master', upstream: 'origin/master' func (self *Shell) SetBranchUpstream(branch string, upstream string) *Shell { self.RunCommand(fmt.Sprintf("git branch --set-upstream-to=%s %s", upstream, branch)) diff --git a/pkg/integration/components/test.go b/pkg/integration/components/test.go index 9291cf329..e1767f475 100644 --- a/pkg/integration/components/test.go +++ b/pkg/integration/components/test.go @@ -11,7 +11,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/utils" ) -// Test describes an integration tests that will be run against the lazygit gui. +// IntegrationTest describes an integration test that will be run against the lazygit gui. // our unit tests will use this description to avoid a panic caused by attempting // to get the test's name via it's file's path. diff --git a/pkg/integration/components/test_driver.go b/pkg/integration/components/test_driver.go index d645b7f0a..c67439b54 100644 --- a/pkg/integration/components/test_driver.go +++ b/pkg/integration/components/test_driver.go @@ -48,8 +48,8 @@ func (self *TestDriver) typeContent(content string) { } } -func (self *TestDriver) Actions() *Actions { - return &Actions{t: self} +func (self *TestDriver) Common() *Common { + return &Common{t: self} } // for when you want to allow lazygit to process something before continuing diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go index c40fc3368..4216b8130 100644 --- a/pkg/integration/components/test_test.go +++ b/pkg/integration/components/test_test.go @@ -11,6 +11,8 @@ import ( "github.com/stretchr/testify/assert" ) +// this file is for testing our test code (meta, I know) + type fakeGuiDriver struct { failureMessage string pressedKeys []string diff --git a/pkg/integration/components/viewDriver.go b/pkg/integration/components/viewDriver.go index 5060a4d1d..647a03851 100644 --- a/pkg/integration/components/viewDriver.go +++ b/pkg/integration/components/viewDriver.go @@ -63,6 +63,7 @@ func (self *ViewDriver) Title(expected *Matcher) *ViewDriver { // asserts that the view has lines matching the given matchers. One matcher must be passed for each line. // If you only care about the top n lines, use the TopLines method instead. +// If you only care about a subset of lines, use the ContainsLines method instead. func (self *ViewDriver) Lines(matchers ...*Matcher) *ViewDriver { self.validateMatchersPassed(matchers) self.LineCount(len(matchers)) @@ -81,6 +82,7 @@ func (self *ViewDriver) TopLines(matchers ...*Matcher) *ViewDriver { return self.assertLines(0, matchers...) } +// asserts that somewhere in the view there are consequetive lines matching the given matchers. func (self *ViewDriver) ContainsLines(matchers ...*Matcher) *ViewDriver { self.validateMatchersPassed(matchers) self.validateEnoughLines(matchers) @@ -131,7 +133,7 @@ func (self *ViewDriver) ContainsLines(matchers ...*Matcher) *ViewDriver { return self } -// asserts on the lines that are selected in the view. +// asserts on the lines that are selected in the view. Don't use the `IsSelected` matcher with this because it's redundant. func (self *ViewDriver) SelectedLines(matchers ...*Matcher) *ViewDriver { self.validateMatchersPassed(matchers) self.validateEnoughLines(matchers) @@ -373,7 +375,7 @@ func (self *ViewDriver) PressEscape() *ViewDriver { // 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 *ViewDriver) NavigateToListItem(matcher *Matcher) *ViewDriver { +func (self *ViewDriver) NavigateToLine(matcher *Matcher) *ViewDriver { self.IsFocused() view := self.getView() diff --git a/pkg/integration/components/views.go b/pkg/integration/components/views.go index ceac6e8fc..667fe9471 100644 --- a/pkg/integration/components/views.go +++ b/pkg/integration/components/views.go @@ -13,16 +13,6 @@ type Views struct { t *TestDriver } -// not exporting this because I want the test to always be explicit about what -// view it's dealing with. -func (self *Views) current() *ViewDriver { - return &ViewDriver{ - context: "current view", - getView: func() *gocui.View { return self.t.gui.CurrentContext().GetView() }, - t: self.t, - } -} - func (self *Views) Main() *ViewDriver { return &ViewDriver{ context: "main view", diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index ca06d5fa5..68009ca98 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -32,14 +32,14 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().Commits(). Focus(). SelectedLine(Contains("commit 10")). - NavigateToListItem(Contains("commit 09")). + NavigateToLine(Contains("commit 09")). Tap(func() { markCommitAsBad() t.Views().Information().Content(Contains("bisecting")) }). SelectedLine(Contains("<-- bad")). - NavigateToListItem(Contains("commit 02")). + NavigateToLine(Contains("commit 02")). Tap(markCommitAsGood). // lazygit will land us in the commit between our good and bad commits. SelectedLine(Contains("commit 05").Contains("<-- current")). diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index 211dca839..07b9037a3 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -35,7 +35,7 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ Content(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")). Confirm() - t.Actions().AcknowledgeConflicts() + t.Common().AcknowledgeConflicts() t.Views().Files(). IsFocused(). @@ -48,7 +48,7 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().Information().Content(Contains("rebasing")) - t.Actions().ContinueOnConflictsResolved() + t.Common().ContinueOnConflictsResolved() t.Views().Information().Content(DoesNotContain("rebasing")) diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index 04c2246ab..298636c59 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -43,7 +43,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().Information().Content(Contains("rebasing")) - t.Actions().AcknowledgeConflicts() + t.Common().AcknowledgeConflicts() t.Views().Files().IsFocused(). SelectedLine(MatchesRegexp("UU.*file")) @@ -75,7 +75,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ IsFocused(). PressPrimaryAction() - t.Actions().ContinueOnConflictsResolved() + t.Common().ContinueOnConflictsResolved() t.Views().Information().Content(DoesNotContain("rebasing")) diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go index 3e82de065..a0030c2f9 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -52,7 +52,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ Content(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")). Confirm() - t.Actions().AcknowledgeConflicts() + t.Common().AcknowledgeConflicts() t.Views().Files(). IsFocused(). @@ -65,7 +65,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). PressPrimaryAction() - t.Actions().ContinueOnConflictsResolved() + t.Common().ContinueOnConflictsResolved() t.Views().Files().IsEmpty() diff --git a/pkg/integration/tests/conflicts/resolve_externally.go b/pkg/integration/tests/conflicts/resolve_externally.go index 385e9ce4a..dec4ab7e2 100644 --- a/pkg/integration/tests/conflicts/resolve_externally.go +++ b/pkg/integration/tests/conflicts/resolve_externally.go @@ -25,7 +25,7 @@ var ResolveExternally = NewIntegrationTest(NewIntegrationTestArgs{ }). Press(keys.Universal.Refresh) - t.Actions().ContinueOnConflictsResolved() + t.Common().ContinueOnConflictsResolved() t.Views().Files(). IsEmpty() diff --git a/pkg/integration/tests/conflicts/resolve_multiple_files.go b/pkg/integration/tests/conflicts/resolve_multiple_files.go index 2be35148e..f32743bef 100644 --- a/pkg/integration/tests/conflicts/resolve_multiple_files.go +++ b/pkg/integration/tests/conflicts/resolve_multiple_files.go @@ -49,6 +49,6 @@ var ResolveMultipleFiles = NewIntegrationTest(NewIntegrationTestArgs{ ). PressPrimaryAction() - t.Actions().ContinueOnConflictsResolved() + t.Common().ContinueOnConflictsResolved() }, }) diff --git a/pkg/integration/tests/file/discard_changes.go b/pkg/integration/tests/file/discard_changes.go index 7a05f4466..2c5d2b2ea 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -99,7 +99,7 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ {status: "DU", label: "deleted-us.txt", menuTitle: "deleted-us.txt"}, }) - t.Actions().ContinueOnConflictsResolved() + t.Common().ContinueOnConflictsResolved() discardOneByOne([]statusFile{ {status: "MD", label: "change-delete.txt", menuTitle: "change-delete.txt"}, diff --git a/pkg/integration/tests/filter_by_path/select_file.go b/pkg/integration/tests/filter_by_path/select_file.go index 6722958dd..6c1243dc8 100644 --- a/pkg/integration/tests/filter_by_path/select_file.go +++ b/pkg/integration/tests/filter_by_path/select_file.go @@ -37,40 +37,3 @@ var SelectFile = NewIntegrationTest(NewIntegrationTestArgs{ postFilterTest(t) }, }) - -func commonSetup(shell *Shell) { - shell.CreateFileAndAdd("filterFile", "original filterFile content") - shell.CreateFileAndAdd("otherFile", "original otherFile content") - shell.Commit("both files") - - shell.UpdateFileAndAdd("otherFile", "new otherFile content") - shell.Commit("only otherFile") - - shell.UpdateFileAndAdd("filterFile", "new filterFile content") - shell.Commit("only filterFile") -} - -func postFilterTest(t *TestDriver) { - t.Views().Information().Content(Contains("filtering by 'filterFile'")) - - t.Views().Commits(). - IsFocused(). - Lines( - Contains(`only filterFile`).IsSelected(), - Contains(`both files`), - ). - SelectNextItem(). - PressEnter() - - // we only show the filtered file's changes in the main view - t.Views().Main(). - Content(Contains("filterFile").DoesNotContain("otherFile")) - - // when you click into the commit itself, you see all files from that commit - t.Views().CommitFiles(). - IsFocused(). - Lines( - Contains(`filterFile`), - Contains(`otherFile`), - ) -} diff --git a/pkg/integration/tests/filter_by_path/shared.go b/pkg/integration/tests/filter_by_path/shared.go new file mode 100644 index 000000000..93e5e0a3d --- /dev/null +++ b/pkg/integration/tests/filter_by_path/shared.go @@ -0,0 +1,42 @@ +package filter_by_path + +import ( + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +func commonSetup(shell *Shell) { + shell.CreateFileAndAdd("filterFile", "original filterFile content") + shell.CreateFileAndAdd("otherFile", "original otherFile content") + shell.Commit("both files") + + shell.UpdateFileAndAdd("otherFile", "new otherFile content") + shell.Commit("only otherFile") + + shell.UpdateFileAndAdd("filterFile", "new filterFile content") + shell.Commit("only filterFile") +} + +func postFilterTest(t *TestDriver) { + t.Views().Information().Content(Contains("filtering by 'filterFile'")) + + t.Views().Commits(). + IsFocused(). + Lines( + Contains(`only filterFile`).IsSelected(), + Contains(`both files`), + ). + SelectNextItem(). + PressEnter() + + // we only show the filtered file's changes in the main view + t.Views().Main(). + Content(Contains("filterFile").DoesNotContain("otherFile")) + + // when you click into the commit itself, you see all files from that commit + t.Views().CommitFiles(). + IsFocused(). + Lines( + Contains(`filterFile`), + Contains(`otherFile`), + ) +} diff --git a/pkg/integration/tests/interactive_rebase/amend_first_commit.go b/pkg/integration/tests/interactive_rebase/amend_first_commit.go index d03a880b9..483153e15 100644 --- a/pkg/integration/tests/interactive_rebase/amend_first_commit.go +++ b/pkg/integration/tests/interactive_rebase/amend_first_commit.go @@ -22,7 +22,7 @@ var AmendFirstCommit = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit 02"), Contains("commit 01"), ). - NavigateToListItem(Contains("commit 01")). + NavigateToLine(Contains("commit 01")). Press(keys.Commits.AmendToCommit). Tap(func() { t.ExpectPopup().Confirmation(). diff --git a/pkg/integration/tests/interactive_rebase/edit_first_commit.go b/pkg/integration/tests/interactive_rebase/edit_first_commit.go index def3b7fca..abf3f2be0 100644 --- a/pkg/integration/tests/interactive_rebase/edit_first_commit.go +++ b/pkg/integration/tests/interactive_rebase/edit_first_commit.go @@ -21,14 +21,14 @@ var EditFirstCommit = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit 02"), Contains("commit 01"), ). - NavigateToListItem(Contains("commit 01")). + NavigateToLine(Contains("commit 01")). Press(keys.Universal.Edit). Lines( Contains("commit 02"), MatchesRegexp("YOU ARE HERE.*commit 01").IsSelected(), ). Tap(func() { - t.Actions().ContinueRebase() + t.Common().ContinueRebase() }). Lines( Contains("commit 02"), diff --git a/pkg/integration/tests/interactive_rebase/fixup_first_commit.go b/pkg/integration/tests/interactive_rebase/fixup_first_commit.go index fe339f3e2..7f66c24de 100644 --- a/pkg/integration/tests/interactive_rebase/fixup_first_commit.go +++ b/pkg/integration/tests/interactive_rebase/fixup_first_commit.go @@ -21,7 +21,7 @@ var FixupFirstCommit = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit 02"), Contains("commit 01"), ). - NavigateToListItem(Contains("commit 01")). + NavigateToLine(Contains("commit 01")). Press(keys.Commits.MarkCommitAsFixup). Tap(func() { t.ExpectPopup().Alert(). diff --git a/pkg/integration/tests/interactive_rebase/fixup_second_commit.go b/pkg/integration/tests/interactive_rebase/fixup_second_commit.go index 007eba84f..8dc97b096 100644 --- a/pkg/integration/tests/interactive_rebase/fixup_second_commit.go +++ b/pkg/integration/tests/interactive_rebase/fixup_second_commit.go @@ -22,7 +22,7 @@ var FixupSecondCommit = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit 02"), Contains("commit 01"), ). - NavigateToListItem(Contains("commit 02")). + NavigateToLine(Contains("commit 02")). Press(keys.Commits.MarkCommitAsFixup). Tap(func() { t.ExpectPopup().Confirmation(). diff --git a/pkg/integration/tests/interactive_rebase/move_in_rebase.go b/pkg/integration/tests/interactive_rebase/move_in_rebase.go index daeedbf87..160a2c823 100644 --- a/pkg/integration/tests/interactive_rebase/move_in_rebase.go +++ b/pkg/integration/tests/interactive_rebase/move_in_rebase.go @@ -22,7 +22,7 @@ var MoveInRebase = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit 02"), Contains("commit 01"), ). - NavigateToListItem(Contains("commit 01")). + NavigateToLine(Contains("commit 01")). Press(keys.Universal.Edit). Lines( Contains("commit 04"), @@ -84,7 +84,7 @@ var MoveInRebase = NewIntegrationTest(NewIntegrationTestArgs{ Contains("YOU ARE HERE").Contains("commit 01"), ). Tap(func() { - t.Actions().ContinueRebase() + t.Common().ContinueRebase() }). Lines( Contains("commit 04"), diff --git a/pkg/integration/tests/interactive_rebase/rebase.go b/pkg/integration/tests/interactive_rebase/rebase.go index 3951d7826..95fd185cb 100644 --- a/pkg/integration/tests/interactive_rebase/rebase.go +++ b/pkg/integration/tests/interactive_rebase/rebase.go @@ -31,7 +31,7 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ Contains("first commit to edit"), Contains("initial commit"), ). - NavigateToListItem(Contains("first commit to edit")). + NavigateToLine(Contains("first commit to edit")). Press(keys.Universal.Edit). Lines( MatchesRegexp("pick.*commit to fixup"), @@ -82,7 +82,7 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ Contains("initial commit"), ). Tap(func() { - t.Actions().ContinueRebase() + t.Common().ContinueRebase() }). Lines( MatchesRegexp("fixup.*commit to fixup").IsSelected(), @@ -92,7 +92,7 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ Contains("initial commit"), ). Tap(func() { - t.Actions().ContinueRebase() + t.Common().ContinueRebase() }). Lines( Contains("second commit to edit").IsSelected(), diff --git a/pkg/integration/tests/interactive_rebase/reword_first_commit.go b/pkg/integration/tests/interactive_rebase/reword_first_commit.go index d4835fcd8..c85293cec 100644 --- a/pkg/integration/tests/interactive_rebase/reword_first_commit.go +++ b/pkg/integration/tests/interactive_rebase/reword_first_commit.go @@ -24,7 +24,7 @@ var RewordFirstCommit = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit 02"), Contains("commit 01"), ). - NavigateToListItem(Contains("commit 01")). + NavigateToLine(Contains("commit 01")). Press(keys.Commits.RenameCommit). Tap(func() { t.ExpectPopup().Prompt(). diff --git a/pkg/integration/tests/interactive_rebase/shared.go b/pkg/integration/tests/interactive_rebase/shared.go new file mode 100644 index 000000000..db45f42e3 --- /dev/null +++ b/pkg/integration/tests/interactive_rebase/shared.go @@ -0,0 +1,68 @@ +package interactive_rebase + +import ( + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +func handleConflictsFromSwap(t *TestDriver) { + t.Common().AcknowledgeConflicts() + + t.Views().Files(). + IsFocused(). + Lines( + Contains("UU myfile"), + ). + PressEnter() + + t.Views().MergeConflicts(). + IsFocused(). + TopLines( + Contains("<<<<<<< HEAD"), + Contains("one"), + Contains("======="), + Contains("three"), + Contains(">>>>>>>"), + ). + SelectNextItem(). + PressPrimaryAction() // pick "three" + + t.Common().ContinueOnConflictsResolved() + + t.Common().AcknowledgeConflicts() + + t.Views().Files(). + IsFocused(). + Lines( + Contains("UU myfile"), + ). + PressEnter() + + t.Views().MergeConflicts(). + IsFocused(). + TopLines( + Contains("<<<<<<< HEAD"), + Contains("three"), + Contains("======="), + Contains("two"), + Contains(">>>>>>>"), + ). + SelectNextItem(). + PressPrimaryAction() // pick "two" + + t.Common().ContinueOnConflictsResolved() + + t.Views().Commits(). + Focus(). + Lines( + Contains("commit two").IsSelected(), + Contains("commit three"), + Contains("commit one"), + ). + Tap(func() { + t.Views().Main().Content(Contains("-three").Contains("+two")) + }). + SelectNextItem(). + Tap(func() { + t.Views().Main().Content(Contains("-one").Contains("+three")) + }) +} diff --git a/pkg/integration/tests/interactive_rebase/squash_down_first_commit.go b/pkg/integration/tests/interactive_rebase/squash_down_first_commit.go index 0ec334a6c..7d6182081 100644 --- a/pkg/integration/tests/interactive_rebase/squash_down_first_commit.go +++ b/pkg/integration/tests/interactive_rebase/squash_down_first_commit.go @@ -21,7 +21,7 @@ var SquashDownFirstCommit = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit 02"), Contains("commit 01"), ). - NavigateToListItem(Contains("commit 01")). + NavigateToLine(Contains("commit 01")). Press(keys.Commits.SquashDown). Tap(func() { t.ExpectPopup().Alert(). diff --git a/pkg/integration/tests/interactive_rebase/squash_down_second_commit.go b/pkg/integration/tests/interactive_rebase/squash_down_second_commit.go index ffa54584f..385145743 100644 --- a/pkg/integration/tests/interactive_rebase/squash_down_second_commit.go +++ b/pkg/integration/tests/interactive_rebase/squash_down_second_commit.go @@ -22,7 +22,7 @@ var SquashDownSecondCommit = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit 02"), Contains("commit 01"), ). - NavigateToListItem(Contains("commit 02")). + NavigateToLine(Contains("commit 02")). Press(keys.Commits.SquashDown). Tap(func() { t.ExpectPopup().Confirmation(). diff --git a/pkg/integration/tests/interactive_rebase/squash_fixups_above_first_commit.go b/pkg/integration/tests/interactive_rebase/squash_fixups_above_first_commit.go index ece1e5fae..34d325726 100644 --- a/pkg/integration/tests/interactive_rebase/squash_fixups_above_first_commit.go +++ b/pkg/integration/tests/interactive_rebase/squash_fixups_above_first_commit.go @@ -22,7 +22,7 @@ var SquashFixupsAboveFirstCommit = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit 02"), Contains("commit 01"), ). - NavigateToListItem(Contains("commit 01")). + NavigateToLine(Contains("commit 01")). Press(keys.Commits.CreateFixupCommit). Tap(func() { t.ExpectPopup().Confirmation(). @@ -30,7 +30,7 @@ var SquashFixupsAboveFirstCommit = NewIntegrationTest(NewIntegrationTestArgs{ Content(Contains("Are you sure you want to create a fixup! commit for commit")). Confirm() }). - NavigateToListItem(Contains("commit 01")). + NavigateToLine(Contains("commit 01")). Press(keys.Commits.SquashAboveCommits). Tap(func() { t.ExpectPopup().Confirmation(). diff --git a/pkg/integration/tests/interactive_rebase/swap_in_rebase_with_conflict.go b/pkg/integration/tests/interactive_rebase/swap_in_rebase_with_conflict.go index 96b490a7f..8c109fb51 100644 --- a/pkg/integration/tests/interactive_rebase/swap_in_rebase_with_conflict.go +++ b/pkg/integration/tests/interactive_rebase/swap_in_rebase_with_conflict.go @@ -26,7 +26,7 @@ var SwapInRebaseWithConflict = NewIntegrationTest(NewIntegrationTestArgs{ Contains("commit two"), Contains("commit one"), ). - NavigateToListItem(Contains("commit one")). + NavigateToLine(Contains("commit one")). Press(keys.Universal.Edit). Lines( Contains("commit three"), @@ -41,72 +41,9 @@ var SwapInRebaseWithConflict = NewIntegrationTest(NewIntegrationTestArgs{ Contains("YOU ARE HERE").Contains("commit one"), ). Tap(func() { - t.Actions().ContinueRebase() + t.Common().ContinueRebase() }) handleConflictsFromSwap(t) }, }) - -func handleConflictsFromSwap(t *TestDriver) { - t.Actions().AcknowledgeConflicts() - - t.Views().Files(). - IsFocused(). - Lines( - Contains("UU myfile"), - ). - PressEnter() - - t.Views().MergeConflicts(). - IsFocused(). - TopLines( - Contains("<<<<<<< HEAD"), - Contains("one"), - Contains("======="), - Contains("three"), - Contains(">>>>>>>"), - ). - SelectNextItem(). - PressPrimaryAction() // pick "three" - - t.Actions().ContinueOnConflictsResolved() - - t.Actions().AcknowledgeConflicts() - - t.Views().Files(). - IsFocused(). - Lines( - Contains("UU myfile"), - ). - PressEnter() - - t.Views().MergeConflicts(). - IsFocused(). - TopLines( - Contains("<<<<<<< HEAD"), - Contains("three"), - Contains("======="), - Contains("two"), - Contains(">>>>>>>"), - ). - SelectNextItem(). - PressPrimaryAction() // pick "two" - - t.Actions().ContinueOnConflictsResolved() - - t.Views().Commits(). - Focus(). - Lines( - Contains("commit two").IsSelected(), - Contains("commit three"), - Contains("commit one"), - ). - Tap(func() { - t.Views().Main().Content(Contains("-three").Contains("+two")) - }). - SelectNextItem(). - Tap(func() { - t.Views().Main().Content(Contains("-one").Contains("+three")) - }) -} diff --git a/pkg/integration/tests/patch_building/apply.go b/pkg/integration/tests/patch_building/apply.go index 4fbc235c2..3dd598a26 100644 --- a/pkg/integration/tests/patch_building/apply.go +++ b/pkg/integration/tests/patch_building/apply.go @@ -50,7 +50,7 @@ var Apply = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().PatchBuildingSecondary().Content(Contains("second line")) - t.Actions().SelectPatchOption(MatchesRegexp(`apply patch$`)) + t.Common().SelectPatchOption(MatchesRegexp(`apply patch$`)) t.Views().Files(). Focus(). diff --git a/pkg/integration/tests/patch_building/apply_in_reverse.go b/pkg/integration/tests/patch_building/apply_in_reverse.go index ec7b94fbc..1c6f56c30 100644 --- a/pkg/integration/tests/patch_building/apply_in_reverse.go +++ b/pkg/integration/tests/patch_building/apply_in_reverse.go @@ -35,7 +35,7 @@ var ApplyInReverse = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().PatchBuildingSecondary().Content(Contains("+file1 content")) - t.Actions().SelectPatchOption(Contains("apply patch in reverse")) + t.Common().SelectPatchOption(Contains("apply patch in reverse")) t.Views().Files(). Focus(). diff --git a/pkg/integration/tests/patch_building/copy_patch_to_clipboard.go b/pkg/integration/tests/patch_building/copy_patch_to_clipboard.go index ad65f63e9..0dea2c36b 100644 --- a/pkg/integration/tests/patch_building/copy_patch_to_clipboard.go +++ b/pkg/integration/tests/patch_building/copy_patch_to_clipboard.go @@ -40,7 +40,7 @@ var CopyPatchToClipboard = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().Information().Content(Contains("building patch")) - t.Actions().SelectPatchOption(Contains("copy patch to clipboard")) + t.Common().SelectPatchOption(Contains("copy patch to clipboard")) t.ExpectToast(Contains("Patch copied to clipboard")) diff --git a/pkg/integration/tests/patch_building/move_to_index.go b/pkg/integration/tests/patch_building/move_to_index.go index 0ba8fcf43..2eea9f07b 100644 --- a/pkg/integration/tests/patch_building/move_to_index.go +++ b/pkg/integration/tests/patch_building/move_to_index.go @@ -35,7 +35,7 @@ var MoveToIndex = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().PatchBuildingSecondary().Content(Contains("+file1 content")) - t.Actions().SelectPatchOption(Contains("move patch out into index")) + t.Common().SelectPatchOption(Contains("move patch out into index")) t.Views().Files(). Lines( diff --git a/pkg/integration/tests/patch_building/move_to_index_partial.go b/pkg/integration/tests/patch_building/move_to_index_partial.go index 772c6ed23..ffe8f06ee 100644 --- a/pkg/integration/tests/patch_building/move_to_index_partial.go +++ b/pkg/integration/tests/patch_building/move_to_index_partial.go @@ -28,7 +28,7 @@ var MoveToIndexPartial = NewIntegrationTest(NewIntegrationTestArgs{ Contains("second commit"), Contains("first commit"), ). - NavigateToListItem(Contains("second commit")). + NavigateToLine(Contains("second commit")). PressEnter() t.Views().CommitFiles(). @@ -61,7 +61,7 @@ var MoveToIndexPartial = NewIntegrationTest(NewIntegrationTestArgs{ Contains(` third line`), ) - t.Actions().SelectPatchOption(Contains("move patch out into index")) + t.Common().SelectPatchOption(Contains("move patch out into index")) t.Views().Files(). Lines( diff --git a/pkg/integration/tests/patch_building/move_to_index_with_conflict.go b/pkg/integration/tests/patch_building/move_to_index_with_conflict.go index 6f9b961d0..bdeb321c4 100644 --- a/pkg/integration/tests/patch_building/move_to_index_with_conflict.go +++ b/pkg/integration/tests/patch_building/move_to_index_with_conflict.go @@ -40,9 +40,9 @@ var MoveToIndexWithConflict = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().Information().Content(Contains("building patch")) - t.Actions().SelectPatchOption(Contains("move patch out into index")) + t.Common().SelectPatchOption(Contains("move patch out into index")) - t.Actions().AcknowledgeConflicts() + t.Common().AcknowledgeConflicts() t.Views().Files(). IsFocused(). @@ -62,7 +62,7 @@ var MoveToIndexWithConflict = NewIntegrationTest(NewIntegrationTestArgs{ ). PressPrimaryAction() - t.Actions().ContinueOnConflictsResolved() + t.Common().ContinueOnConflictsResolved() t.ExpectPopup().Alert(). Title(Equals("Error")). diff --git a/pkg/integration/tests/patch_building/move_to_new_commit.go b/pkg/integration/tests/patch_building/move_to_new_commit.go index 3ef9f7df6..483a1ab53 100644 --- a/pkg/integration/tests/patch_building/move_to_new_commit.go +++ b/pkg/integration/tests/patch_building/move_to_new_commit.go @@ -40,7 +40,7 @@ var MoveToNewCommit = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().Information().Content(Contains("building patch")) - t.Actions().SelectPatchOption(Contains("move patch into new commit")) + t.Common().SelectPatchOption(Contains("move patch into new commit")) t.Views().CommitFiles(). IsFocused(). diff --git a/pkg/integration/tests/patch_building/remove_from_commit.go b/pkg/integration/tests/patch_building/remove_from_commit.go index 0d920c2a5..f2bc701a4 100644 --- a/pkg/integration/tests/patch_building/remove_from_commit.go +++ b/pkg/integration/tests/patch_building/remove_from_commit.go @@ -35,7 +35,7 @@ var RemoveFromCommit = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().PatchBuildingSecondary().Content(Contains("+file1 content")) - t.Actions().SelectPatchOption(Contains("remove patch from original commit")) + t.Common().SelectPatchOption(Contains("remove patch from original commit")) t.Views().Files().IsEmpty() diff --git a/pkg/integration/tests/patch_building/specific_selection.go b/pkg/integration/tests/patch_building/specific_selection.go index 1823f24f2..1f5f56bc1 100644 --- a/pkg/integration/tests/patch_building/specific_selection.go +++ b/pkg/integration/tests/patch_building/specific_selection.go @@ -43,7 +43,7 @@ var SpecificSelection = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().Secondary().Content(Contains("direct file content")) }). - NavigateToListItem(Contains("hunk-file")). + NavigateToLine(Contains("hunk-file")). PressEnter() t.Views().PatchBuilding(). @@ -92,7 +92,7 @@ var SpecificSelection = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().CommitFiles(). IsFocused(). - NavigateToListItem(Contains("line-file")). + NavigateToLine(Contains("line-file")). PressEnter() t.Views().PatchBuilding(). @@ -106,11 +106,11 @@ var SpecificSelection = NewIntegrationTest(NewIntegrationTestArgs{ Contains("+2a"), ). PressPrimaryAction(). - NavigateToListItem(Contains("+2c")). + NavigateToLine(Contains("+2c")). Press(keys.Main.ToggleDragSelect). - NavigateToListItem(Contains("+2e")). + NavigateToLine(Contains("+2e")). PressPrimaryAction(). - NavigateToListItem(Contains("+2g")). + NavigateToLine(Contains("+2g")). PressPrimaryAction(). Tap(func() { t.Views().Information().Content(Contains("building patch")) diff --git a/pkg/integration/tests/patch_building/start_new_patch.go b/pkg/integration/tests/patch_building/start_new_patch.go index d020a561c..53d870b12 100644 --- a/pkg/integration/tests/patch_building/start_new_patch.go +++ b/pkg/integration/tests/patch_building/start_new_patch.go @@ -41,7 +41,7 @@ var StartNewPatch = NewIntegrationTest(NewIntegrationTestArgs{ t.Views().Commits(). IsFocused(). - NavigateToListItem(Contains("first commit")). + NavigateToLine(Contains("first commit")). PressEnter() t.Views().CommitFiles(). diff --git a/pkg/integration/tests/staging/discard_all_changes.go b/pkg/integration/tests/staging/discard_all_changes.go index 48cd0b62d..ce9f22aae 100644 --- a/pkg/integration/tests/staging/discard_all_changes.go +++ b/pkg/integration/tests/staging/discard_all_changes.go @@ -33,13 +33,13 @@ var DiscardAllChanges = NewIntegrationTest(NewIntegrationTestArgs{ // discard the line Press(keys.Universal.Remove). Tap(func() { - t.Actions().ConfirmDiscardLines() + t.Common().ConfirmDiscardLines() }). SelectedLines(Contains("+four")). // discard the other line Press(keys.Universal.Remove). Tap(func() { - t.Actions().ConfirmDiscardLines() + t.Common().ConfirmDiscardLines() // because there are no more changes in file1 we switch to file2 t.Views().Files(). diff --git a/pkg/integration/tests/staging/stage_hunks.go b/pkg/integration/tests/staging/stage_hunks.go index c2f85661a..2dd07371c 100644 --- a/pkg/integration/tests/staging/stage_hunks.go +++ b/pkg/integration/tests/staging/stage_hunks.go @@ -139,7 +139,7 @@ var StageHunks = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Universal.Remove). Tap(func() { - t.Actions().ConfirmDiscardLines() + t.Common().ConfirmDiscardLines() }). Content(DoesNotContain("-3a").DoesNotContain("+3b")). SelectedLines( diff --git a/pkg/integration/tests/staging/stage_ranges.go b/pkg/integration/tests/staging/stage_ranges.go index ea886ccda..7458a5ea5 100644 --- a/pkg/integration/tests/staging/stage_ranges.go +++ b/pkg/integration/tests/staging/stage_ranges.go @@ -30,7 +30,7 @@ var StageRanges = NewIntegrationTest(NewIntegrationTestArgs{ Contains("+three"), ). Press(keys.Main.ToggleDragSelect). - NavigateToListItem(Contains("+five")). + NavigateToLine(Contains("+five")). SelectedLines( Contains("+three"), Contains("+four"), @@ -61,7 +61,7 @@ var StageRanges = NewIntegrationTest(NewIntegrationTestArgs{ Contains("+three"), ). Press(keys.Main.ToggleDragSelect). - NavigateToListItem(Contains("+five")). + NavigateToLine(Contains("+five")). SelectedLines( Contains("+three"), Contains("+four"), @@ -96,7 +96,7 @@ var StageRanges = NewIntegrationTest(NewIntegrationTestArgs{ ). Press(keys.Universal.Remove). Tap(func() { - t.Actions().ConfirmDiscardLines() + t.Common().ConfirmDiscardLines() }). ContainsLines( Contains("+three"), diff --git a/pkg/integration/tests/submodule/add.go b/pkg/integration/tests/submodule/add.go index e04141499..1fd79a781 100644 --- a/pkg/integration/tests/submodule/add.go +++ b/pkg/integration/tests/submodule/add.go @@ -12,7 +12,7 @@ var Add = NewIntegrationTest(NewIntegrationTestArgs{ SetupConfig: func(config *config.AppConfig) {}, SetupRepo: func(shell *Shell) { shell.EmptyCommit("first commit") - shell.RunCommand("git clone --bare . ../other_repo") + shell.Clone("other_repo") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Submodules().Focus(). diff --git a/pkg/integration/tests/submodule/enter.go b/pkg/integration/tests/submodule/enter.go index 8dbbb73b4..d877a4e29 100644 --- a/pkg/integration/tests/submodule/enter.go +++ b/pkg/integration/tests/submodule/enter.go @@ -20,8 +20,7 @@ var Enter = NewIntegrationTest(NewIntegrationTestArgs{ }, SetupRepo: func(shell *Shell) { shell.EmptyCommit("first commit") - shell.RunCommand("git clone --bare . ../other_repo") - shell.RunCommand("git submodule add ../other_repo my_submodule") + shell.CloneIntoSubmodule("my_submodule") shell.GitAddAll() shell.Commit("add submodule") }, diff --git a/pkg/integration/tests/submodule/remove.go b/pkg/integration/tests/submodule/remove.go index 0a8884e15..5888aa1cf 100644 --- a/pkg/integration/tests/submodule/remove.go +++ b/pkg/integration/tests/submodule/remove.go @@ -12,8 +12,7 @@ var Remove = NewIntegrationTest(NewIntegrationTestArgs{ SetupConfig: func(config *config.AppConfig) {}, SetupRepo: func(shell *Shell) { shell.EmptyCommit("first commit") - shell.RunCommand("git clone --bare . ../other_repo") - shell.RunCommand("git submodule add ../other_repo my_submodule") + shell.CloneIntoSubmodule("my_submodule") shell.GitAddAll() shell.Commit("add submodule") }, diff --git a/pkg/integration/tests/submodule/reset.go b/pkg/integration/tests/submodule/reset.go index 474780f1b..98147b044 100644 --- a/pkg/integration/tests/submodule/reset.go +++ b/pkg/integration/tests/submodule/reset.go @@ -20,8 +20,7 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ }, SetupRepo: func(shell *Shell) { shell.EmptyCommit("first commit") - shell.RunCommand("git clone --bare . ../other_repo") - shell.RunCommand("git submodule add ../other_repo my_submodule") + shell.CloneIntoSubmodule("my_submodule") shell.GitAddAll() shell.Commit("add submodule") }, diff --git a/pkg/integration/tests/sync/force_push_multiple_upstream.go b/pkg/integration/tests/sync/force_push_multiple_upstream.go index d8833c12f..c2b50c4fa 100644 --- a/pkg/integration/tests/sync/force_push_multiple_upstream.go +++ b/pkg/integration/tests/sync/force_push_multiple_upstream.go @@ -5,25 +5,6 @@ import ( . "github.com/jesseduffield/lazygit/pkg/integration/components" ) -func createTwoBranchesReadyToForcePush(shell *Shell) { - shell.EmptyCommit("one") - shell.EmptyCommit("two") - - shell.NewBranch("other_branch") - - shell.CloneIntoRemote("origin") - - shell.SetBranchUpstream("master", "origin/master") - shell.SetBranchUpstream("other_branch", "origin/other_branch") - - // remove the 'two' commit so that we have something to pull from the remote - shell.HardReset("HEAD^") - - shell.Checkout("master") - // doing the same for master - shell.HardReset("HEAD^") -} - var ForcePushMultipleUpstream = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Force push to only the upstream branch of the current branch because the user has push.default upstream", ExtraCmdArgs: "", diff --git a/pkg/integration/tests/sync/pull_merge_conflict.go b/pkg/integration/tests/sync/pull_merge_conflict.go index 447c11135..2b4247584 100644 --- a/pkg/integration/tests/sync/pull_merge_conflict.go +++ b/pkg/integration/tests/sync/pull_merge_conflict.go @@ -40,7 +40,7 @@ var PullMergeConflict = NewIntegrationTest(NewIntegrationTestArgs{ IsFocused(). Press(keys.Universal.Pull) - t.Actions().AcknowledgeConflicts() + t.Common().AcknowledgeConflicts() t.Views().Files(). IsFocused(). @@ -60,7 +60,7 @@ var PullMergeConflict = NewIntegrationTest(NewIntegrationTestArgs{ ). PressPrimaryAction() // choose 'content4' - t.Actions().ContinueOnConflictsResolved() + t.Common().ContinueOnConflictsResolved() t.Views().Status().Content(Contains("↑2 repo → master")) diff --git a/pkg/integration/tests/sync/pull_rebase_conflict.go b/pkg/integration/tests/sync/pull_rebase_conflict.go index 4ea419a74..ebe7b3fd9 100644 --- a/pkg/integration/tests/sync/pull_rebase_conflict.go +++ b/pkg/integration/tests/sync/pull_rebase_conflict.go @@ -40,7 +40,7 @@ var PullRebaseConflict = NewIntegrationTest(NewIntegrationTestArgs{ IsFocused(). Press(keys.Universal.Pull) - t.Actions().AcknowledgeConflicts() + t.Common().AcknowledgeConflicts() t.Views().Files(). IsFocused(). @@ -61,7 +61,7 @@ var PullRebaseConflict = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). PressPrimaryAction() // choose 'content4' - t.Actions().ContinueOnConflictsResolved() + t.Common().ContinueOnConflictsResolved() t.Views().Status().Content(Contains("↑1 repo → master")) diff --git a/pkg/integration/tests/sync/pull_rebase_interactive_conflict.go b/pkg/integration/tests/sync/pull_rebase_interactive_conflict.go index da45f70ed..37deb8a40 100644 --- a/pkg/integration/tests/sync/pull_rebase_interactive_conflict.go +++ b/pkg/integration/tests/sync/pull_rebase_interactive_conflict.go @@ -42,7 +42,7 @@ var PullRebaseInteractiveConflict = NewIntegrationTest(NewIntegrationTestArgs{ IsFocused(). Press(keys.Universal.Pull) - t.Actions().AcknowledgeConflicts() + t.Common().AcknowledgeConflicts() t.Views().Commits(). Lines( @@ -71,7 +71,7 @@ var PullRebaseInteractiveConflict = NewIntegrationTest(NewIntegrationTestArgs{ SelectNextItem(). PressPrimaryAction() // choose 'content4' - t.Actions().ContinueOnConflictsResolved() + t.Common().ContinueOnConflictsResolved() t.Views().Status().Content(Contains("↑2 repo → master")) diff --git a/pkg/integration/tests/sync/pull_rebase_interactive_conflict_drop.go b/pkg/integration/tests/sync/pull_rebase_interactive_conflict_drop.go index 580a2af5b..a51d0d4b6 100644 --- a/pkg/integration/tests/sync/pull_rebase_interactive_conflict_drop.go +++ b/pkg/integration/tests/sync/pull_rebase_interactive_conflict_drop.go @@ -42,7 +42,7 @@ var PullRebaseInteractiveConflictDrop = NewIntegrationTest(NewIntegrationTestArg IsFocused(). Press(keys.Universal.Pull) - t.Actions().AcknowledgeConflicts() + t.Common().AcknowledgeConflicts() t.Views().Commits(). Focus(). @@ -79,7 +79,7 @@ var PullRebaseInteractiveConflictDrop = NewIntegrationTest(NewIntegrationTestArg SelectNextItem(). PressPrimaryAction() // choose 'content4' - t.Actions().ContinueOnConflictsResolved() + t.Common().ContinueOnConflictsResolved() t.Views().Status().Content(Contains("↑1 repo → master")) diff --git a/pkg/integration/tests/sync/push.go b/pkg/integration/tests/sync/push.go index 9fa095697..92c0d0881 100644 --- a/pkg/integration/tests/sync/push.go +++ b/pkg/integration/tests/sync/push.go @@ -30,28 +30,3 @@ var Push = NewIntegrationTest(NewIntegrationTestArgs{ assertSuccessfullyPushed(t) }, }) - -func assertSuccessfullyPushed(t *TestDriver) { - t.Views().Status().Content(Contains("✓ repo → master")) - - t.Views().Remotes(). - Focus(). - Lines( - Contains("origin"), - ). - PressEnter() - - t.Views().RemoteBranches(). - IsFocused(). - Lines( - Contains("master"), - ). - PressEnter() - - t.Views().SubCommits(). - IsFocused(). - Lines( - Contains("two"), - Contains("one"), - ) -} diff --git a/pkg/integration/tests/sync/push_with_credential_prompt.go b/pkg/integration/tests/sync/push_with_credential_prompt.go index 8c5341716..ee45a03b0 100644 --- a/pkg/integration/tests/sync/push_with_credential_prompt.go +++ b/pkg/integration/tests/sync/push_with_credential_prompt.go @@ -23,8 +23,7 @@ var PushWithCredentialPrompt = NewIntegrationTest(NewIntegrationTestArgs{ // actually getting a password prompt is tricky: it requires SSH'ing into localhost under a newly created, restricted, user. // This is not easy to do in a cross-platform way, nor is it easy to do in a docker container. // If you can think of a way to do it, please let me know! - shell.RunCommand("cp ../../../../../hooks/pre-push .git/hooks/pre-push") - shell.RunCommand("chmod +x .git/hooks/pre-push") + shell.CopyHelpFile("pre-push", ".git/hooks/pre-push") }, Run: func(t *TestDriver, keys config.KeybindingConfig) { t.Views().Status().Content(Contains("↑1 repo → master")) diff --git a/pkg/integration/tests/sync/shared.go b/pkg/integration/tests/sync/shared.go new file mode 100644 index 000000000..8ea9a6c25 --- /dev/null +++ b/pkg/integration/tests/sync/shared.go @@ -0,0 +1,49 @@ +package sync + +import ( + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +func createTwoBranchesReadyToForcePush(shell *Shell) { + shell.EmptyCommit("one") + shell.EmptyCommit("two") + + shell.NewBranch("other_branch") + + shell.CloneIntoRemote("origin") + + shell.SetBranchUpstream("master", "origin/master") + shell.SetBranchUpstream("other_branch", "origin/other_branch") + + // remove the 'two' commit so that we have something to pull from the remote + shell.HardReset("HEAD^") + + shell.Checkout("master") + // doing the same for master + shell.HardReset("HEAD^") +} + +func assertSuccessfullyPushed(t *TestDriver) { + t.Views().Status().Content(Contains("✓ repo → master")) + + t.Views().Remotes(). + Focus(). + Lines( + Contains("origin"), + ). + PressEnter() + + t.Views().RemoteBranches(). + IsFocused(). + Lines( + Contains("master"), + ). + PressEnter() + + t.Views().SubCommits(). + IsFocused(). + Lines( + Contains("two"), + Contains("one"), + ) +} diff --git a/pkg/integration/tests/tests_gen.go b/pkg/integration/tests/test_list.go similarity index 100% rename from pkg/integration/tests/tests_gen.go rename to pkg/integration/tests/test_list.go diff --git a/pkg/integration/tests/tests_generator.go b/pkg/integration/tests/test_list_generator.go similarity index 95% rename from pkg/integration/tests/tests_generator.go rename to pkg/integration/tests/test_list_generator.go index ef702221e..294165cca 100644 --- a/pkg/integration/tests/tests_generator.go +++ b/pkg/integration/tests/test_list_generator.go @@ -1,7 +1,7 @@ //go:build ignore -// This file is invoked with `go generate ./...` and it generates the tests_gen.go file -// The tests_gen.go file is a list of all the integration tests. +// This file is invoked with `go generate ./...` and it generates the test_list.go file +// The test_list.go file is a list of all the integration tests. // It's annoying to have to manually add an entry in that file for each test you // create, so this generator is here to make the process easier. @@ -26,7 +26,7 @@ func main() { if err != nil { panic(err) } - if err := ioutil.WriteFile("tests_gen.go", formattedCode, 0o644); err != nil { + if err := ioutil.WriteFile("test_list.go", formattedCode, 0o644); err != nil { panic(err) } } diff --git a/pkg/integration/tests/tests.go b/pkg/integration/tests/tests.go index 4af3cb459..2134aa302 100644 --- a/pkg/integration/tests/tests.go +++ b/pkg/integration/tests/tests.go @@ -1,4 +1,4 @@ -//go:generate go run tests_generator.go +//go:generate go run test_list_generator.go package tests @@ -30,7 +30,7 @@ func GetTests() []*components.IntegrationTest { if err := filepath.Walk(filepath.Join(utils.GetLazyRootDirectory(), "pkg/integration/tests"), func(path string, info os.FileInfo, err error) error { if !info.IsDir() && strings.HasSuffix(path, ".go") { // ignoring non-test files - if filepath.Base(path) == "tests.go" || filepath.Base(path) == "tests_gen.go" || filepath.Base(path) == "tests_generator.go" { + if filepath.Base(path) == "tests.go" || filepath.Base(path) == "test_list.go" || filepath.Base(path) == "test_list_generator.go" { return nil } @@ -39,6 +39,11 @@ func GetTests() []*components.IntegrationTest { return nil } + // any file named shared.go will also be ignored, because those files are only used for shared helper functions + if filepath.Base(path) == "shared.go" { + return nil + } + nameFromPath := components.TestNameFromFilePath(path) if !testNamesSet.Includes(nameFromPath) { missingTestNames = append(missingTestNames, nameFromPath) @@ -51,13 +56,13 @@ func GetTests() []*components.IntegrationTest { } if len(missingTestNames) > 0 { - panic(fmt.Sprintf("The following tests are missing from the list of tests: %s. You need to add them to `pkg/integration/tests/tests_gen.go`. Use `go generate ./...` to regenerate the tests list.", strings.Join(missingTestNames, ", "))) + panic(fmt.Sprintf("The following tests are missing from the list of tests: %s. You need to add them to `pkg/integration/tests/test_list.go`. Use `go generate ./...` to regenerate the tests list.", strings.Join(missingTestNames, ", "))) } if testCount > len(tests) { - panic("you have not added all of the tests to the tests list in `pkg/integration/tests/tests_gen.go`. Use `go generate ./...` to regenerate the tests list.") + panic("you have not added all of the tests to the tests list in `pkg/integration/tests/test_list.go`. Use `go generate ./...` to regenerate the tests list.") } else if testCount < len(tests) { - panic("There are more tests in `pkg/integration/tests/tests_gen.go` than there are test files in the tests directory. Ensure that you only have one test per file and you haven't included the same test twice in the tests list. Use `go generate ./...` to regenerate the tests list.") + panic("There are more tests in `pkg/integration/tests/test_list.go` than there are test files in the tests directory. Ensure that you only have one test per file and you haven't included the same test twice in the tests list. Use `go generate ./...` to regenerate the tests list.") } return tests diff --git a/test/README.md b/test/README.md new file mode 100644 index 000000000..524429894 --- /dev/null +++ b/test/README.md @@ -0,0 +1,2 @@ +This directory contains some files used by out integration tests. The tests themselves live in [/pkg/integration/](/pkg/integration/). See [here](/pkg/integration/README.md) for more info + diff --git a/test/hooks/pre-push b/test/files/pre-push old mode 100644 new mode 100755 similarity index 100% rename from test/hooks/pre-push rename to test/files/pre-push diff --git a/test/global_git_config b/test/global_git_config index bfd11875c..f4f47c003 100644 --- a/test/global_git_config +++ b/test/global_git_config @@ -1,3 +1,5 @@ +# This is the global git config we use for all our integration tests + [user] name = CI email = CI@example.com