diff options
Diffstat (limited to 'pkg/integration')
63 files changed, 1329 insertions, 63 deletions
diff --git a/pkg/integration/clients/go_test.go b/pkg/integration/clients/go_test.go index 6984e0deb..af4bbf5f8 100644 --- a/pkg/integration/clients/go_test.go +++ b/pkg/integration/clients/go_test.go @@ -45,12 +45,6 @@ func TestIntegration(t *testing.T) { return } - // not running demoes right now. Arguably we should, but we'd need to - // strip away any artificial lag they use. - if test.IsDemo() { - return - } - t.Run(test.Name(), func(t *testing.T) { t.Parallel() err := f() diff --git a/pkg/integration/components/prompt_driver.go b/pkg/integration/components/prompt_driver.go index 023c2f438..a19c29aa4 100644 --- a/pkg/integration/components/prompt_driver.go +++ b/pkg/integration/components/prompt_driver.go @@ -82,3 +82,21 @@ func (self *PromptDriver) ConfirmSuggestion(matcher *TextMatcher) { NavigateToLine(matcher). PressEnter() } + +func (self *PromptDriver) DeleteSuggestion(matcher *TextMatcher) *PromptDriver { + self.t.press(self.t.keys.Universal.TogglePanel) + self.t.Views().Suggestions(). + IsFocused(). + NavigateToLine(matcher) + self.t.press(self.t.keys.Universal.Remove) + return self +} + +func (self *PromptDriver) EditSuggestion(matcher *TextMatcher) *PromptDriver { + self.t.press(self.t.keys.Universal.TogglePanel) + self.t.Views().Suggestions(). + IsFocused(). + NavigateToLine(matcher) + self.t.press(self.t.keys.Universal.Edit) + return self +} diff --git a/pkg/integration/components/runner.go b/pkg/integration/components/runner.go index c148dc141..f123182cf 100644 --- a/pkg/integration/components/runner.go +++ b/pkg/integration/components/runner.go @@ -48,8 +48,6 @@ func RunTests(args RunTestArgs) error { } for _, test := range args.Tests { - test := test - args.TestWrapper(test, func() error { //nolint: thelper paths := NewPaths( filepath.Join(testDir, test.Name()), diff --git a/pkg/integration/components/shell.go b/pkg/integration/components/shell.go index e3df61a50..a8caff77d 100644 --- a/pkg/integration/components/shell.go +++ b/pkg/integration/components/shell.go @@ -195,6 +195,10 @@ func (self *Shell) CreateAnnotatedTag(name string, message string, ref string) * } func (self *Shell) PushBranch(upstream, branch string) *Shell { + return self.RunCommand([]string{"git", "push", upstream, branch}) +} + +func (self *Shell) PushBranchAndSetUpstream(upstream, branch string) *Shell { return self.RunCommand([]string{"git", "push", "--set-upstream", upstream, branch}) } diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go index 047ee507c..ea1c79124 100644 --- a/pkg/integration/components/test_test.go +++ b/pkg/integration/components/test_test.go @@ -84,6 +84,8 @@ func (self *fakeGuiDriver) NextToast() *string { func (self *fakeGuiDriver) CheckAllToastsAcknowledged() {} +func (self *fakeGuiDriver) Headless() bool { return false } + func TestManualFailure(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, diff --git a/pkg/integration/components/view_driver.go b/pkg/integration/components/view_driver.go index 8d9b336d6..b6f917603 100644 --- a/pkg/integration/components/view_driver.go +++ b/pkg/integration/components/view_driver.go @@ -263,8 +263,8 @@ func (self *ViewDriver) assertLines(offset int, matchers ...*TextMatcher) *ViewD return false, fmt.Sprintf( "Unexpected selection in view '%s'. Expected %s to be selected but got %s.\nExpected selected lines:\n---\n%s\n---\n\nActual selected lines:\n---\n%s\n---\n", view.Name(), - formatLineRange(startIdx, endIdx), formatLineRange(expectedStartIdx, expectedEndIdx), + formatLineRange(startIdx, endIdx), strings.Join(expectedSelectedLines, "\n"), strings.Join(lines, "\n"), ) @@ -565,7 +565,7 @@ func (self *ViewDriver) IsVisible() *ViewDriver { 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.getView().Visible, fmt.Sprintf("%s: Expected view to be invisible, but it was not", self.context) }) return self @@ -601,7 +601,9 @@ func (self *ViewDriver) SetCaptionPrefix(prefix string) *ViewDriver { } func (self *ViewDriver) Wait(milliseconds int) *ViewDriver { - self.t.Wait(milliseconds) + if !self.t.gui.Headless() { + self.t.Wait(milliseconds) + } return self } diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index 0b6adfac4..f81eb0609 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -15,9 +15,9 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ CloneIntoRemote("origin"). EmptyCommit("blah"). NewBranch("branch-one"). - PushBranch("origin", "branch-one"). + PushBranchAndSetUpstream("origin", "branch-one"). NewBranch("branch-two"). - PushBranch("origin", "branch-two"). + PushBranchAndSetUpstream("origin", "branch-two"). EmptyCommit("deletion blocker"). NewBranch("branch-three") }, diff --git a/pkg/integration/tests/branch/delete_remote_branch_with_credential_prompt.go b/pkg/integration/tests/branch/delete_remote_branch_with_credential_prompt.go index f145eceaa..6e3f52028 100644 --- a/pkg/integration/tests/branch/delete_remote_branch_with_credential_prompt.go +++ b/pkg/integration/tests/branch/delete_remote_branch_with_credential_prompt.go @@ -18,7 +18,7 @@ var DeleteRemoteBranchWithCredentialPrompt = NewIntegrationTest(NewIntegrationTe shell.NewBranch("mybranch") - shell.PushBranch("origin", "mybranch") + shell.PushBranchAndSetUpstream("origin", "mybranch") // 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. @@ -44,7 +44,7 @@ var DeleteRemoteBranchWithCredentialPrompt = NewIntegrationTest(NewIntegrationTe Confirm() } - t.Views().Status().Content(Contains("✓ repo → mybranch")) + t.Views().Status().Content(Equals("✓ repo → mybranch")) deleteBranch() @@ -66,7 +66,7 @@ var DeleteRemoteBranchWithCredentialPrompt = NewIntegrationTest(NewIntegrationTe Content(Contains("incorrect username/password")). Confirm() - t.Views().Status().Content(Contains("✓ repo → mybranch")) + t.Views().Status().Content(Equals("✓ repo → mybranch")) // try again with correct password deleteBranch() @@ -81,7 +81,7 @@ var DeleteRemoteBranchWithCredentialPrompt = NewIntegrationTest(NewIntegrationTe Type("password"). Confirm() - t.Views().Status().Content(Contains("repo → mybranch").DoesNotContain("✓")) + t.Views().Status().Content(Equals("(upstream gone) repo → mybranch")) t.Views().Branches().TopLines(Contains("mybranch (upstream gone)")) }, }) diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index 66a235107..c7dc028af 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -31,7 +31,7 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'first-change-branch' onto 'second-change-branch'")). + Title(Equals("Rebase 'first-change-branch'")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_abort_on_conflict.go b/pkg/integration/tests/branch/rebase_abort_on_conflict.go index 4eba77627..47f59d3d1 100644 --- a/pkg/integration/tests/branch/rebase_abort_on_conflict.go +++ b/pkg/integration/tests/branch/rebase_abort_on_conflict.go @@ -31,7 +31,7 @@ var RebaseAbortOnConflict = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'first-change-branch' onto 'second-change-branch'")). + Title(Equals("Rebase 'first-change-branch'")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index 4c6712f23..60ef19e6a 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -37,7 +37,7 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'first-change-branch' onto 'second-change-branch'")). + Title(Equals("Rebase 'first-change-branch'")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_cancel_on_conflict.go b/pkg/integration/tests/branch/rebase_cancel_on_conflict.go index 23b7661b2..03923c81d 100644 --- a/pkg/integration/tests/branch/rebase_cancel_on_conflict.go +++ b/pkg/integration/tests/branch/rebase_cancel_on_conflict.go @@ -31,7 +31,7 @@ var RebaseCancelOnConflict = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'first-change-branch' onto 'second-change-branch'")). + Title(Equals("Rebase 'first-change-branch'")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_copied_branch.go b/pkg/integration/tests/branch/rebase_copied_branch.go new file mode 100644 index 000000000..bc9fcb4a6 --- /dev/null +++ b/pkg/integration/tests/branch/rebase_copied_branch.go @@ -0,0 +1,68 @@ +package branch + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var RebaseCopiedBranch = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Make a copy of a branch, rebase it, check that the original branch is unaffected", + ExtraCmdArgs: []string{}, + Skip: false, + GitVersion: AtLeast("2.38.0"), + SetupConfig: func(config *config.AppConfig) { + config.AppState.GitLogShowGraph = "never" + }, + SetupRepo: func(shell *Shell) { + shell. + EmptyCommit("master 1"). + EmptyCommit("master 2"). + NewBranchFrom("branch1", "master^"). + EmptyCommit("branch 1"). + EmptyCommit("branch 2"). + NewBranch("branch2") + + shell.SetConfig("rebase.updateRefs", "true") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits().Lines( + Contains("CI * branch 2"), + Contains("CI branch 1"), + Contains("CI master 1"), + ) + + t.Views().Branches(). + Focus(). + Lines( + Contains("branch2").IsSelected(), + Contains("branch1"), + Contains("master"), + ). + NavigateToLine(Contains("master")). + Press(keys.Branches.RebaseBranch). + Tap(func() { + t.ExpectPopup().Menu(). + Title(Equals("Rebase 'branch2'")). + Select(Contains("Simple rebase")). + Confirm() + }) + + t.Views().Commits().Lines( + Contains("CI branch 2"), + Contains("CI branch 1"), + Contains("CI master 2"), + Contains("CI master 1"), + ) + + t.Views().Branches(). + Focus(). + NavigateToLine(Contains("branch1")). + PressPrimaryAction() + + t.Views().Commits().Lines( + Contains("CI branch 2"), + Contains("CI branch 1"), + Contains("CI master 1"), + ) + }, +}) diff --git a/pkg/integration/tests/branch/rebase_does_not_autosquash.go b/pkg/integration/tests/branch/rebase_does_not_autosquash.go index 66ad870c4..523682410 100644 --- a/pkg/integration/tests/branch/rebase_does_not_autosquash.go +++ b/pkg/integration/tests/branch/rebase_does_not_autosquash.go @@ -40,7 +40,7 @@ var RebaseDoesNotAutosquash = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'my-branch' onto 'master'")). + Title(Equals("Rebase 'my-branch'")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_from_marked_base.go b/pkg/integration/tests/branch/rebase_from_marked_base.go index c2ee307e3..c26dce9a3 100644 --- a/pkg/integration/tests/branch/rebase_from_marked_base.go +++ b/pkg/integration/tests/branch/rebase_from_marked_base.go @@ -61,7 +61,7 @@ var RebaseFromMarkedBase = NewIntegrationTest(NewIntegrationTestArgs{ Press(keys.Branches.RebaseBranch) t.ExpectPopup().Menu(). - Title(Equals("Rebase 'active-branch' from marked base onto 'target-branch'")). + Title(Equals("Rebase 'active-branch' from marked base")). Select(Contains("Simple rebase")). Confirm() diff --git a/pkg/integration/tests/branch/rebase_onto_base_branch.go b/pkg/integration/tests/branch/rebase_onto_base_branch.go new file mode 100644 index 000000000..3944f4fe6 --- /dev/null +++ b/pkg/integration/tests/branch/rebase_onto_base_branch.go @@ -0,0 +1,53 @@ +package branch + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var RebaseOntoBaseBranch = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Rebase the current branch onto its base branch", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(config *config.AppConfig) { + config.UserConfig.Gui.ShowDivergenceFromBaseBranch = "arrowAndNumber" + }, + SetupRepo: func(shell *Shell) { + shell. + EmptyCommit("master 1"). + EmptyCommit("master 2"). + EmptyCommit("master 3"). + NewBranchFrom("feature", "master^"). + EmptyCommit("feature 1"). + EmptyCommit("feature 2") + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits().Lines( + Contains("feature 2"), + Contains("feature 1"), + Contains("master 2"), + Contains("master 1"), + ) + + t.Views().Branches(). + Focus(). + Lines( + Contains("feature ↓1").IsSelected(), + Contains("master"), + ). + Press(keys.Branches.RebaseBranch) + + t.ExpectPopup().Menu(). + Title(Equals("Rebase 'feature'")). + Select(Contains("Rebase onto base branch (master)")). + Confirm() + + t.Views().Commits().Lines( + Contains("feature 2"), + Contains("feature 1"), + Contains("master 3"), + Contains("master 2"), + Contains("master 1"), + ) + }, +}) diff --git a/pkg/integration/tests/branch/rebase_to_upstream.go b/pkg/integration/tests/branch/rebase_to_upstream.go index 5c9e0f388..f8b2d6fd1 100644 --- a/pkg/integration/tests/branch/rebase_to_upstream.go +++ b/pkg/integration/tests/branch/rebase_to_upstream.go @@ -15,7 +15,7 @@ var RebaseToUpstream = NewIntegrationTest(NewIntegrationTestArgs{ CloneIntoRemote("origin"). EmptyCommit("ensure-master"). EmptyCommit("to-be-added"). // <- this will only exist remotely - PushBranch("origin", "master"). + PushBranchAndSetUpstream("origin", "master"). HardReset("HEAD~1"). NewBranchFrom("base-branch", "master"). EmptyCommit("base-branch-commit"). @@ -67,7 +67,7 @@ var RebaseToUpstream = NewIntegrationTest(NewIntegrationTestArgs{ Select(Contains("Rebase checked-out branch onto origin/master...")). Confirm() t.ExpectPopup().Menu(). - Title(Equals("Rebase 'target' onto 'origin/master'")). + Title(Eq |