diff --git a/pkg/integration/README.md b/pkg/integration/README.md index 3c75792ed..96b7f0089 100644 --- a/pkg/integration/README.md +++ b/pkg/integration/README.md @@ -41,10 +41,28 @@ The run step has four arguments passed in: 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. -Use assertions to ensure that lazygit has processed all your keybindings so far. For example, if you press 'n' on a branch to create a new branch, assert that the confirmation view is now focused. +Use assertions to ensure that lazygit has processed all your keybindings so far. Each time you press a key, something should happen on the screen, so you should assert that that thing has happened. This means we won't get into trouble from keys being entered two quickly because at each stage we ensure the key has been processed. This also makes tests more readable because they help explain what we expect to be happening on-screen. For example: + +```go +input.Press(keys.Files.CommitChanges) +assert.InCommitMessagePanel() +``` 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 `input.PressKey(keys.Universal.Confirm)` in 100 places, it's better to have a method `input.Confirm()`. This is not to say that everything should be made into a method on the input struct: 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. For example: + +```go +// asserts that a prompt opens with the title 'Enter a file name', and then types 'my file' and confirms +input.Prompt(Equals("Enter a file name"), "my file") + +// asserts that a menu opens with the title: 'Choose file content', and then selects the option which contains 'bar' +input.Menu(Equals("Choose file content"), Contains("bar")) + +// asserts a confirmation appears with the title 'Are you sure?' and the content 'Are you REALLY sure' and then confirms +input.AcceptConfirmation(Equals("Are you sure?"), Equals("Are you REALLY sure?")) +``` + ## Running tests There are three ways to invoke a test: diff --git a/pkg/integration/components/assert.go b/pkg/integration/components/assert.go index ab7d079c8..95998b759 100644 --- a/pkg/integration/components/assert.go +++ b/pkg/integration/components/assert.go @@ -21,57 +21,44 @@ func NewAssert(gui integrationTypes.GuiDriver) *Assert { return &Assert{gui: gui} } -// for making assertions on string values -type matcher struct { - testFn func(string) (bool, string) - prefix string -} - -func (self *matcher) test(value string) (bool, string) { - ok, message := self.testFn(value) - if ok { - return true, "" - } - - if self.prefix != "" { - return false, self.prefix + " " + message - } - - return false, message -} - -func (self *matcher) context(prefix string) *matcher { - self.prefix = prefix - - return self -} - func Contains(target string) *matcher { - return &matcher{testFn: func(value string) (bool, string) { - return strings.Contains(value, target), fmt.Sprintf("Expected '%s' to be found in '%s'", target, value) - }} + return NewMatcher( + fmt.Sprintf("contains '%s'", target), + func(value string) (bool, string) { + return strings.Contains(value, target), fmt.Sprintf("Expected '%s' to be found in '%s'", target, value) + }, + ) } func NotContains(target string) *matcher { - return &matcher{testFn: func(value string) (bool, string) { - return !strings.Contains(value, target), fmt.Sprintf("Expected '%s' to NOT be found in '%s'", target, value) - }} + return NewMatcher( + fmt.Sprintf("does not contain '%s'", target), + func(value string) (bool, string) { + return !strings.Contains(value, target), fmt.Sprintf("Expected '%s' to NOT be found in '%s'", target, value) + }, + ) } -func MatchesRegexp(regexStr string) *matcher { - return &matcher{testFn: func(value string) (bool, string) { - matched, err := regexp.MatchString(regexStr, value) - if err != nil { - return false, fmt.Sprintf("Unexpected error parsing regular expression '%s': %s", regexStr, err.Error()) - } - return matched, fmt.Sprintf("Expected '%s' to match regular expression '%s'", value, regexStr) - }} +func MatchesRegexp(target string) *matcher { + return NewMatcher( + fmt.Sprintf("matches regular expression '%s'", target), + func(value string) (bool, string) { + matched, err := regexp.MatchString(target, value) + if err != nil { + return false, fmt.Sprintf("Unexpected error parsing regular expression '%s': %s", target, err.Error()) + } + return matched, fmt.Sprintf("Expected '%s' to match regular expression '%s'", value, target) + }, + ) } func Equals(target string) *matcher { - return &matcher{testFn: func(value string) (bool, string) { - return target == value, fmt.Sprintf("Expected '%s' to equal '%s'", value, target) - }} + return NewMatcher( + fmt.Sprintf("equals '%s'", target), + func(value string) (bool, string) { + return target == value, fmt.Sprintf("Expected '%s' to equal '%s'", value, target) + }, + ) } func (self *Assert) WorkingTreeFileCount(expectedCount int) { @@ -186,6 +173,13 @@ func (self *Assert) InAlert() { }) } +func (self *Assert) InCommitMessagePanel() { + self.assertWithRetries(func() (bool, string) { + currentView := self.gui.CurrentContext().GetView() + return currentView.Name() == "commitMessage", "Expected commit message panel to be focused" + }) +} + func (self *Assert) InMenu() { self.assertWithRetries(func() (bool, string) { return self.gui.CurrentContext().GetView().Name() == "menu", "Expected popup menu to be focused" diff --git a/pkg/integration/components/input.go b/pkg/integration/components/input.go index adc4df261..b6f2022c6 100644 --- a/pkg/integration/components/input.go +++ b/pkg/integration/components/input.go @@ -28,87 +28,81 @@ func NewInput(gui integrationTypes.GuiDriver, keys config.KeybindingConfig, asse // key is something like 'w' or ''. It's best not to pass a direct value, // but instead to go through the default user config to get a more meaningful key name -func (self *Input) PressKeys(keyStrs ...string) { +func (self *Input) Press(keyStrs ...string) { for _, keyStr := range keyStrs { - self.pressKey(keyStr) + self.press(keyStr) } } -func (self *Input) pressKey(keyStr string) { +func (self *Input) press(keyStr string) { self.Wait(self.pushKeyDelay) self.gui.PressKey(keyStr) } func (self *Input) SwitchToStatusWindow() { - self.pressKey(self.keys.Universal.JumpToBlock[0]) + self.press(self.keys.Universal.JumpToBlock[0]) self.assert.CurrentWindowName("status") } func (self *Input) SwitchToFilesWindow() { - self.pressKey(self.keys.Universal.JumpToBlock[1]) + self.press(self.keys.Universal.JumpToBlock[1]) self.assert.CurrentWindowName("files") } func (self *Input) SwitchToBranchesWindow() { - self.pressKey(self.keys.Universal.JumpToBlock[2]) + self.press(self.keys.Universal.JumpToBlock[2]) self.assert.CurrentWindowName("localBranches") } func (self *Input) SwitchToCommitsWindow() { - self.pressKey(self.keys.Universal.JumpToBlock[3]) + self.press(self.keys.Universal.JumpToBlock[3]) self.assert.CurrentWindowName("commits") } func (self *Input) SwitchToStashWindow() { - self.pressKey(self.keys.Universal.JumpToBlock[4]) + self.press(self.keys.Universal.JumpToBlock[4]) self.assert.CurrentWindowName("stash") } func (self *Input) Type(content string) { for _, char := range content { - self.pressKey(string(char)) + self.press(string(char)) } } // i.e. pressing enter func (self *Input) Confirm() { - self.pressKey(self.keys.Universal.Confirm) -} - -func (self *Input) ProceedWhenAsked(matcher *matcher) { - self.assert.InConfirm() - self.assert.CurrentViewContent(matcher) - self.Confirm() + self.press(self.keys.Universal.Confirm) } // i.e. same as Confirm func (self *Input) Enter() { - self.pressKey(self.keys.Universal.Confirm) + self.press(self.keys.Universal.Confirm) } // i.e. pressing escape func (self *Input) Cancel() { - self.pressKey(self.keys.Universal.Return) + self.press(self.keys.Universal.Return) } // i.e. pressing space func (self *Input) PrimaryAction() { - self.pressKey(self.keys.Universal.Select) + self.press(self.keys.Universal.Select) } // i.e. pressing down arrow func (self *Input) NextItem() { - self.pressKey(self.keys.Universal.NextItem) + self.press(self.keys.Universal.NextItem) } // i.e. pressing up arrow func (self *Input) PreviousItem() { - self.pressKey(self.keys.Universal.PrevItem) + self.press(self.keys.Universal.PrevItem) } func (self *Input) ContinueMerge() { - self.PressKeys(self.keys.Universal.CreateRebaseOptionsMenu) + self.Press(self.keys.Universal.CreateRebaseOptionsMenu) self.assert.SelectedLine(Contains("continue")) self.Confirm() } @@ -141,7 +135,7 @@ func (self *Input) Log(message string) { // 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 *Input) NavigateToListItemContainingText(text string) { +func (self *Input) NavigateToListItem(matcher *matcher) { self.assert.InListContext() currentContext := self.gui.CurrentContext().(types.IListContext) @@ -151,19 +145,20 @@ func (self *Input) NavigateToListItemContainingText(text string) { var matchIndex int self.assert.assertWithRetries(func() (bool, string) { - matchCount := 0 matchIndex = -1 + var matches []string // first we look for a duplicate on the current screen. We won't bother looking beyond that though. for i, line := range view.ViewBufferLines() { - if strings.Contains(line, text) { - matchCount++ + ok, _ := matcher.test(line) + if ok { + matches = append(matches, line) matchIndex = i } } - if matchCount > 1 { - return false, fmt.Sprintf("Found %d matches for %s, expected only a single match", matchCount, text) - } else if matchCount == 0 { - return false, fmt.Sprintf("Could not find item containing text: %s", text) + if len(matches) > 1 { + return false, fmt.Sprintf("Found %d matches for `%s`, expected only a single match. Lines:\n%s", len(matches), matcher.name, strings.Join(matches, "\n")) + } else if len(matches) == 0 { + return false, fmt.Sprintf("Could not find item matching: %s", matcher.name) } else { return true, "" } @@ -171,20 +166,67 @@ func (self *Input) NavigateToListItemContainingText(text string) { selectedLineIdx := view.SelectedLineIdx() if selectedLineIdx == matchIndex { - self.assert.SelectedLine(Contains(text)) + self.assert.SelectedLine(matcher) return } if selectedLineIdx < matchIndex { for i := selectedLineIdx; i < matchIndex; i++ { self.NextItem() } - self.assert.SelectedLine(Contains(text)) + self.assert.SelectedLine(matcher) return } else { for i := selectedLineIdx; i > matchIndex; i-- { self.PreviousItem() } - self.assert.SelectedLine(Contains(text)) + self.assert.SelectedLine(matcher) return } } + +func (self *Input) AcceptConfirmation(title *matcher, content *matcher) { + self.assert.InConfirm() + self.assert.CurrentViewTitle(title) + self.assert.CurrentViewContent(content) + self.Confirm() +} + +func (self *Input) DenyConfirmation(title *matcher, content *matcher) { + self.assert.InConfirm() + self.assert.CurrentViewTitle(title) + self.assert.CurrentViewContent(content) + self.Cancel() +} + +func (self *Input) Prompt(title *matcher, textToType string) { + self.assert.InPrompt() + self.assert.CurrentViewTitle(title) + self.Type(textToType) + self.Confirm() +} + +// type some text into a prompt, then switch to the suggestions panel and expect the first +// item to match the given matcher, then confirm that item. +func (self *Input) Typeahead(title *matcher, textToType string, expectedFirstOption *matcher) { + self.assert.InPrompt() + self.assert.CurrentViewTitle(title) + self.Type(textToType) + self.Press(self.keys.Universal.TogglePanel) + self.assert.CurrentViewName("suggestions") + self.assert.SelectedLine(expectedFirstOption) + self.Confirm() +} + +func (self *Input) Menu(title *matcher, optionToSelect *matcher) { + self.assert.InMenu() + self.assert.CurrentViewTitle(title) + self.NavigateToListItem(optionToSelect) + self.Confirm() +} + +func (self *Input) Alert(title *matcher, content *matcher) { + self.assert.InListContext() + self.assert.CurrentViewTitle(title) + self.assert.CurrentViewContent(content) + self.Confirm() +} diff --git a/pkg/integration/components/matcher.go b/pkg/integration/components/matcher.go new file mode 100644 index 000000000..02b10b714 --- /dev/null +++ b/pkg/integration/components/matcher.go @@ -0,0 +1,35 @@ +package components + +// for making assertions on string values +type matcher struct { + // e.g. "contains 'foo'" + name string + // returns a bool that says whether the test passed and if it returns false, it + // also returns a string of the error message + testFn func(string) (bool, string) + // this is printed when there's an error so that it's clear what the context of the assertion is + prefix string +} + +func NewMatcher(name string, testFn func(string) (bool, string)) *matcher { + return &matcher{name: name, testFn: testFn} +} + +func (self *matcher) test(value string) (bool, string) { + ok, message := self.testFn(value) + if ok { + return true, "" + } + + if self.prefix != "" { + return false, self.prefix + " " + message + } + + return false, message +} + +func (self *matcher) context(prefix string) *matcher { + self.prefix = prefix + + return self +} diff --git a/pkg/integration/components/runner.go b/pkg/integration/components/runner.go index 47677b3b9..85ea3f330 100644 --- a/pkg/integration/components/runner.go +++ b/pkg/integration/components/runner.go @@ -115,6 +115,10 @@ func prepareTestDir( } func buildLazygit() error { + // // TODO: remove this line! + // // skipping this because I'm not making changes to the app code atm. + // return nil + osCommand := oscommands.NewDummyOSCommand() return osCommand.Cmd.New(fmt.Sprintf( "go build -o %s pkg/integration/clients/injector/main.go", tempLazygitPath(), diff --git a/pkg/integration/components/test_test.go b/pkg/integration/components/test_test.go index 61466e2b4..dbab22883 100644 --- a/pkg/integration/components/test_test.go +++ b/pkg/integration/components/test_test.go @@ -64,8 +64,8 @@ func TestAssertionFailure(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.PressKeys("a") - input.PressKeys("b") + input.Press("a") + input.Press("b") assert.CommitCount(2) }, }) @@ -91,8 +91,8 @@ func TestSuccess(t *testing.T) { test := NewIntegrationTest(NewIntegrationTestArgs{ Description: unitTestDescription, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - input.PressKeys("a") - input.PressKeys("b") + input.Press("a") + input.Press("b") assert.CommitCount(0) }, }) diff --git a/pkg/integration/tests/bisect/basic.go b/pkg/integration/tests/bisect/basic.go index 0b81bbcb3..f40b4fe39 100644 --- a/pkg/integration/tests/bisect/basic.go +++ b/pkg/integration/tests/bisect/basic.go @@ -20,24 +20,14 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ assert *Assert, keys config.KeybindingConfig, ) { - viewBisectOptions := func() { - input.PressKeys(keys.Commits.ViewBisectOptions) - assert.InMenu() - } markCommitAsBad := func() { - viewBisectOptions() - assert.SelectedLine(Contains("bad")) - - input.Confirm() + input.Press(keys.Commits.ViewBisectOptions) + input.Menu(Equals("Bisect"), MatchesRegexp(`mark .* as bad`)) } markCommitAsGood := func() { - viewBisectOptions() - assert.SelectedLine(Contains("bad")) - input.NextItem() - assert.SelectedLine(Contains("good")) - - input.Confirm() + input.Press(keys.Commits.ViewBisectOptions) + input.Menu(Equals("Bisect"), MatchesRegexp(`mark .* as good`)) } assert.AtLeastOneCommit() @@ -46,7 +36,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ assert.SelectedLine(Contains("commit 10")) - input.NavigateToListItemContainingText("commit 09") + input.NavigateToListItem(Contains("commit 09")) markCommitAsBad() @@ -55,11 +45,11 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ assert.CurrentViewName("commits") assert.SelectedLine(Contains("<-- bad")) - input.NavigateToListItemContainingText("commit 02") + input.NavigateToListItem(Contains("commit 02")) markCommitAsGood() - // lazygit will land us in the comit between our good and bad commits. + // lazygit will land us in the commit between our good and bad commits. assert.CurrentViewName("commits") assert.SelectedLine(Contains("commit 05")) assert.SelectedLine(Contains("<-- current")) @@ -72,12 +62,8 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ markCommitAsGood() - assert.InAlert() - assert.CurrentViewContent(Contains("Bisect complete!")) // commit 5 is the culprit because we marked 4 as good and 5 as bad. - assert.CurrentViewContent(Contains("commit 05")) - assert.CurrentViewContent(Contains("Do you want to reset")) - input.Confirm() + input.Alert(Equals("Bisect complete"), MatchesRegexp("(?s)commit 05.*Do you want to reset")) assert.CurrentViewName("commits") assert.CurrentViewContent(Contains("commit 04")) diff --git a/pkg/integration/tests/bisect/from_other_branch.go b/pkg/integration/tests/bisect/from_other_branch.go index 52314518f..85829b741 100644 --- a/pkg/integration/tests/bisect/from_other_branch.go +++ b/pkg/integration/tests/bisect/from_other_branch.go @@ -24,20 +24,6 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ assert *Assert, keys config.KeybindingConfig, ) { - viewBisectOptions := func() { - input.PressKeys(keys.Commits.ViewBisectOptions) - assert.InMenu() - } - - markCommitAsGood := func() { - viewBisectOptions() - assert.SelectedLine(Contains("bad")) - input.NextItem() - assert.SelectedLine(Contains("good")) - - input.Confirm() - } - assert.ViewContent("information", Contains("bisecting")) assert.AtLeastOneCommit() @@ -51,13 +37,10 @@ var FromOtherBranch = NewIntegrationTest(NewIntegrationTestArgs{ assert.SelectedLine(Contains("<-- current")) assert.SelectedLine(Contains("commit 07")) - markCommitAsGood() + input.Press(keys.Commits.ViewBisectOptions) + input.Menu(Equals("Bisect"), MatchesRegexp(`mark .* as good`)) - assert.InAlert() - assert.CurrentViewContent(Contains("Bisect complete!")) - assert.CurrentViewContent(Contains("commit 08")) - assert.CurrentViewContent(Contains("Do you want to reset")) - input.Confirm() + input.Alert(Equals("Bisect complete"), MatchesRegexp(`(?s)commit 08.*Do you want to reset`)) assert.ViewContent("information", NotContains("bisecting")) diff --git a/pkg/integration/tests/branch/checkout_by_name.go b/pkg/integration/tests/branch/checkout_by_name.go index 956a2c36b..de5c0131c 100644 --- a/pkg/integration/tests/branch/checkout_by_name.go +++ b/pkg/integration/tests/branch/checkout_by_name.go @@ -24,14 +24,11 @@ var CheckoutByName = NewIntegrationTest(NewIntegrationTestArgs{ assert.SelectedLine(Contains("master")) input.NextItem() assert.SelectedLine(Contains("@")) - input.PressKeys(keys.Branches.CheckoutBranchByName) - assert.InPrompt() - assert.CurrentViewTitle(Equals("Branch name:")) - input.Type("new-branch") - input.Confirm() - assert.InAlert() - assert.CurrentViewContent(Equals("Branch not found. Create a new branch named new-branch?")) - input.Confirm() + input.Press(keys.Branches.CheckoutBranchByName) + + input.Prompt(Equals("Branch name:"), "new-branch") + + input.Alert(Equals("Branch not found"), Equals("Branch not found. Create a new branch named new-branch?")) assert.CurrentViewName("localBranches") assert.SelectedLine(Contains("new-branch")) diff --git a/pkg/integration/tests/branch/delete.go b/pkg/integration/tests/branch/delete.go index 148544563..524b8e365 100644 --- a/pkg/integration/tests/branch/delete.go +++ b/pkg/integration/tests/branch/delete.go @@ -21,18 +21,15 @@ var Delete = NewIntegrationTest(NewIntegrationTestArgs{ assert.CurrentViewName("localBranches") assert.SelectedLine(Contains("branch-two")) - input.PressKeys(keys.Universal.Remove) - assert.InAlert() - assert.CurrentViewContent(Contains("You cannot delete the checked out branch!")) - - input.Confirm() + input.Press(keys.Universal.Remove) + input.Alert(Equals("Error"), Contains("You cannot delete the checked out branch!")) input.NextItem() assert.SelectedLine(Contains("branch-one")) - input.PressKeys(keys.Universal.Remove) - assert.InConfirm() - assert.CurrentViewContent(Contains("Are you sure you want to delete the branch 'branch-one'?")) - input.Confirm() + + input.Press(keys.Universal.Remove) + input.AcceptConfirmation(Equals("Delete Branch"), Contains("Are you sure you want to delete the branch 'branch-one'?")) + assert.CurrentViewName("localBranches") assert.SelectedLine(Contains("master")) assert.CurrentViewContent(NotContains("branch-one")) diff --git a/pkg/integration/tests/branch/rebase.go b/pkg/integration/tests/branch/rebase.go index a398b0993..665efe7d6 100644 --- a/pkg/integration/tests/branch/rebase.go +++ b/pkg/integration/tests/branch/rebase.go @@ -21,30 +21,26 @@ var Rebase = NewIntegrationTest(NewIntegrationTestArgs{ assert.SelectedLine(Contains("first-change-branch")) input.NextItem() assert.SelectedLine(Contains("second-change-branch")) - input.PressKeys(keys.Branches.RebaseBranch) + input.Press(keys.Branches.RebaseBranch) - assert.InConfirm() - assert.CurrentViewContent(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")) - input.Confirm() + input.AcceptConfirmation(Equals("Rebasing"), Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")) - assert.InConfirm() - assert.CurrentViewContent(Contains("Conflicts!")) - input.Confirm() + input.AcceptConfirmation(Equals("Auto-merge failed"), Contains("Conflicts!")) assert.CurrentViewName("files") assert.SelectedLine(Contains("file")) // not using Confirm() convenience method because I suspect we might change this // keybinding to something more bespoke - input.PressKeys(keys.Universal.Confirm) + input.Press(keys.Universal.Confirm) assert.CurrentViewName("mergeConflicts") input.PrimaryAction() assert.ViewContent("information", Contains("rebasing")) - assert.InConfirm() - assert.CurrentViewContent(Contains("all merge conflicts resolved. Continue?")) - input.Confirm() + + input.AcceptConfirmation(Equals("continue"), Contains("all merge conflicts resolved. Continue?")) + assert.ViewContent("information", NotContains("rebasing")) // this proves we actually have integrated the changes from second-change-branch diff --git a/pkg/integration/tests/branch/rebase_and_drop.go b/pkg/integration/tests/branch/rebase_and_drop.go index 2269f0292..bb5b53855 100644 --- a/pkg/integration/tests/branch/rebase_and_drop.go +++ b/pkg/integration/tests/branch/rebase_and_drop.go @@ -24,17 +24,13 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ assert.SelectedLine(Contains("first-change-branch")) input.NextItem() assert.SelectedLine(Contains("second-change-branch")) - input.PressKeys(keys.Branches.RebaseBranch) + input.Press(keys.Branches.RebaseBranch) - assert.InConfirm() - assert.CurrentViewContent(Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")) - input.Confirm() + input.AcceptConfirmation(Equals("Rebasing"), Contains("Are you sure you want to rebase 'first-change-branch' on top of 'second-change-branch'?")) assert.ViewContent("information", Contains("rebasing")) - assert.InConfirm() - assert.CurrentViewContent(Contains("Conflicts!")) - input.Confirm() + input.AcceptConfirmation(Equals("Auto-merge failed"), Contains("Conflicts!")) assert.CurrentViewName("files") assert.SelectedLine(Contains("file")) @@ -42,22 +38,22 @@ var RebaseAndDrop = NewIntegrationTest(NewIntegrationTestArgs{ input.SwitchToCommitsWindow() assert.SelectedLine(Contains("pick")) // this means it's a rebasing commit input.NextItem() - input.PressKeys(keys.Universal.Remove) + input.Press(keys.Universal.Remove) + // this is the commit name assert.SelectedLine(Contains("to remove")) + // the commit has been marked to drop once we continue the rebase. assert.SelectedLine(Contains("drop")) input.SwitchToFilesWindow() // not using Confirm() convenience method because I suspect we might change this // keybinding to something more bespoke - input.PressKeys(keys.Universal.Confirm) + input.Press(keys.Universal.Confirm) assert.CurrentViewName("mergeConflicts") input.PrimaryAction() - assert.InConfirm() - assert.CurrentViewContent(Contains("all merge conflicts resolved. Continue?")) - input.Confirm() + input.AcceptConfirmation(Equals("continue"), Contains("all merge conflicts resolved. Continue?")) assert.ViewContent("information", NotContains("rebasing")) diff --git a/pkg/integration/tests/branch/reset.go b/pkg/integration/tests/branch/reset.go index 605b7e76c..d4cadb49f 100644 --- a/pkg/integration/tests/branch/reset.go +++ b/pkg/integration/tests/branch/reset.go @@ -28,17 +28,9 @@ var Reset = NewIntegrationTest(NewIntegrationTestArgs{ input.NextItem() assert.SelectedLine(Contains("other-branch")) - input.PressKeys(keys.Commits.ViewResetOptions) - assert.InMenu() - assert.CurrentViewTitle(Contains("reset to other-branch")) + input.Press(keys.Commits.ViewResetOptions) - assert.SelectedLine(Contains("soft reset")) - input.NextItem() - assert.SelectedLine(Contains("mixed reset")) - input.NextItem() - assert.SelectedLine(Contains("hard reset")) - - input.Confirm() + input.Menu(Contains("reset to other-branch"), Contains("hard reset")) // ensure that we've returned from the menu before continuing assert.CurrentViewName("localBranches") diff --git a/pkg/integration/tests/branch/suggestions.go b/pkg/integration/tests/branch/suggestions.go index 346c471d0..98cc3cf47 100644 --- a/pkg/integration/tests/branch/suggestions.go +++ b/pkg/integration/tests/branch/suggestions.go @@ -24,18 +24,11 @@ var Suggestions = NewIntegrationTest(NewIntegrationTestArgs{ input.SwitchToBranchesWindow() assert.CurrentViewName("localBranches") - input.PressKeys(keys.Branches.CheckoutBranchByName) - assert.CurrentViewName("confirmation") - - input.Type("branch-to") - - input.PressKeys(keys.Universal.TogglePanel) - assert.CurrentViewName("suggestions") + input.Press(keys.Branches.CheckoutBranchByName) // we expect the first suggestion to be the branch we want because it most // closely matches what we typed in - assert.SelectedLine(Contains("branch-to-checkout")) - input.Confirm() + input.Typeahead(Equals("Branch name:"), "branch-to", Contains("branch-to-checkout")) assert.CurrentBranchName("branch-to-checkout") }, diff --git a/pkg/integration/tests/cherry_pick/cherry_pick.go b/pkg/integration/tests/cherry_pick/cherry_pick.go index 7cbf6a70a..444cf35e4 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick.go @@ -35,23 +35,21 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ assert.CurrentViewName("subCommits") assert.SelectedLine(Contains("four")) - input.PressKeys(keys.Commits.CherryPickCopy) + input.Press(keys.Commits.CherryPickCopy) assert.ViewContent("information", Contains("1 commit copied")) input.NextItem() assert.SelectedLine(Contains("three")) - input.PressKeys(keys.Commits.CherryPickCopy) + input.Press(keys.Commits.CherryPickCopy) assert.ViewContent("information", Contains("2 commits copied")) input.SwitchToCommitsWindow() assert.CurrentViewName("commits") assert.SelectedLine(Contains("two")) - input.PressKeys(keys.Commits.PasteCommits) - assert.InAlert() - assert.CurrentViewContent(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")) + input.Press(keys.Commits.PasteCommits) + input.Alert(Equals("Cherry-Pick"), Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")) - input.Confirm() assert.CurrentViewName("commits") assert.SelectedLine(Contains("four")) input.NextItem() @@ -60,7 +58,7 @@ var CherryPick = NewIntegrationTest(NewIntegrationTestArgs{ assert.SelectedLine(Contains("two")) assert.ViewContent("information", Contains("2 commits copied")) - input.PressKeys(keys.Universal.Return) + input.Press(keys.Universal.Return) assert.ViewContent("information", NotContains("commits copied")) }, }) diff --git a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go index 99005ad8e..377e21e76 100644 --- a/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go +++ b/pkg/integration/tests/cherry_pick/cherry_pick_conflicts.go @@ -26,42 +26,36 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ assert.CurrentViewName("subCommits") assert.SelectedLine(Contains("second-change-branch unrelated change")) - input.PressKeys(keys.Commits.CherryPickCopy) + input.Press(keys.Commits.CherryPickCopy) assert.ViewContent("information", Contains("1 commit copied")) input.NextItem() assert.SelectedLine(Contains("second change")) - input.PressKeys(keys.Commits.CherryPickCopy) + input.Press(keys.Commits.CherryPickCopy) assert.ViewContent("information", Contains("2 commits copied")) input.SwitchToCommitsWindow() assert.CurrentViewName("commits") assert.SelectedLine(Contains("first change")) - input.PressKeys(keys.Commits.PasteCommits) - assert.InAlert() - assert.CurrentViewContent(Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")) + input.Press(keys.Commits.PasteCommits) + input.Alert(Equals("Cherry-Pick"), Contains("Are you sure you want to cherry-pick the copied commits onto this branch?")) - input.Confirm() - - assert.CurrentViewContent(Contains("Conflicts!")) - input.Confirm() + input.AcceptConfirmation(Equals("Auto-merge failed"), Contains("Conflicts!")) assert.CurrentViewName("files") assert.SelectedLine(Contains("file")) // not using Confirm() convenience method because I suspect we might change this // keybinding to something more bespoke - input.PressKeys(keys.Universal.Confirm) + input.Press(keys.Universal.Confirm) assert.CurrentViewName("mergeConflicts") // picking 'Second change' input.NextItem() input.PrimaryAction() - assert.InConfirm() - assert.CurrentViewContent(Contains("all merge conflicts resolved. Continue?")) - input.Confirm() + input.AcceptConfirmation(Equals("continue"), Contains("all merge conflicts resolved. Continue?")) assert.CurrentViewName("files") assert.WorkingTreeFileCount(0) @@ -81,7 +75,7 @@ var CherryPickConflicts = NewIntegrationTest(NewIntegrationTestArgs{ assert.SelectedLine(Contains("first change")) assert.ViewContent("information", Contains("2 commits copied")) - input.PressKeys(keys.Universal.Return) + input.Press(keys.Universal.Return) assert.ViewContent("information", NotContains("commits copied")) }, }) diff --git a/pkg/integration/tests/commit/commit.go b/pkg/integration/tests/commit/commit.go index 1b7c42793..a20b0df34 100644 --- a/pkg/integration/tests/commit/commit.go +++ b/pkg/integration/tests/commit/commit.go @@ -20,8 +20,9 @@ var Commit = NewIntegrationTest(NewIntegrationTestArgs{ input.PrimaryAction() input.NextItem() input.PrimaryAction() - input.PressKeys(keys.Files.CommitChanges) + input.Press(keys.Files.CommitChanges) + assert.InCommitMessagePanel() commitMessage := "my commit message" input.Type(commitMessage) input.Confirm() diff --git a/pkg/integration/tests/commit/commit_multiline.go b/pkg/integration/tests/commit/commit_multiline.go index 15f26d15d..51e060ec3 100644 --- a/pkg/integration/tests/commit/commit_multiline.go +++ b/pkg/integration/tests/commit/commit_multiline.go @@ -17,11 +17,12 @@ var CommitMultiline = NewIntegrationTest(NewIntegrationTestArgs{ assert.CommitCount(0) input.PrimaryAction() - input.PressKeys(keys.Files.CommitChanges) + input.Press(keys.Files.CommitChanges) + assert.InCommitMessagePanel() input.Type("first line") - input.PressKeys(keys.Universal.AppendNewline) - input.PressKeys(keys.Universal.AppendNewline) + input.Press(keys.Universal.AppendNewline) + input.Press(keys.Universal.AppendNewline) input.Type("third line") input.Confirm() diff --git a/pkg/integration/tests/commit/new_branch.go b/pkg/integration/tests/commit/new_branch.go index 6cf77e89f..3557acbcf 100644 --- a/pkg/integration/tests/commit/new_branch.go +++ b/pkg/integration/tests/commit/new_branch.go @@ -23,13 +23,10 @@ var NewBranch = NewIntegrationTest(NewIntegrationTestArgs{ assert.CurrentViewName("commits") input.NextItem() - input.PressKeys(keys.Universal.New) - - assert.CurrentViewName("confirmation") + input.Press(keys.Universal.New) branchName := "my-branch-name" - input.Type(branchName) - input.Confirm() + input.Prompt(Contains("New Branch Name"), branchName) assert.CommitCount(2) assert.HeadCommitMessage(Contains("commit 2")) diff --git a/pkg/integration/tests/commit/revert.go b/pkg/integration/tests/commit/revert.go index c0fccbb60..448501763 100644 --- a/pkg/integration/tests/commit/revert.go +++ b/pkg/integration/tests/commit/revert.go @@ -20,18 +20,13 @@ var Revert = NewIntegrationTest(NewIntegrationTestArgs{ input.SwitchToCommitsWindow() - input.PressKeys(keys.Commits.RevertCommit) - assert.InConfirm() - assert.CurrentViewTitle(Equals("Revert commit")) - assert.CurrentViewContent(MatchesRegexp("Are you sure you want to revert \\w+?")) - input.Confirm() + input.Press(keys.Commits.RevertCommit) + input.AcceptConfirmation(Equals("Revert commit"), MatchesRegexp(`Are you sure you want to revert \w+?`)) assert.CommitCount(2) assert.HeadCommitMessage(Contains("Revert \"first commit\"")) input.PreviousItem() assert.MainViewContent(Contains("-myfile content")) assert.FileSystemPathNotPresent("myfile") - - input.Wait(10) }, }) diff --git a/pkg/integration/tests/commit/staged.go b/pkg/integration/tests/commit/staged.go index 2ed52d011..acce2c76a 100644 --- a/pkg/integration/tests/commit/staged.go +++ b/pkg/integration/tests/commit/staged.go @@ -18,11 +18,28 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { assert.CommitCount(0) + assert.CurrentViewName("files") + assert.SelectedLine(Contains("myfile")) + // stage the file input.PrimaryAction() - input.Confirm() - input.PrimaryAction() - input.PressKeys(keys.Files.CommitChanges) + input.Enter() + assert.CurrentViewName("stagingSecondary") + // we start with both lines having been staged + assert.ViewContent("stagingSecondary", Contains("+myfile content")) + assert.ViewContent("stagingSecondary", Contains("+with a second line")) + assert.ViewContent("staging", NotContains("+myfile content")) + assert.ViewContent("staging", NotContains("+with a second line")) + // unstage the selected line + input.PrimaryAction() + + // the line should have been moved to the main view + assert.ViewContent("stagingSecondary", NotContains("+myfile content")) + assert.ViewContent("stagingSecondary", Contains("+with a second line")) + assert.ViewContent("staging", Contains("+myfile content")) + assert.ViewContent("staging", NotContains("+with a second line")) + + input.Press(keys.Files.CommitChanges) commitMessage := "my commit message" input.Type(commitMessage) input.Confirm() @@ -30,5 +47,7 @@ var Staged = NewIntegrationTest(NewIntegrationTestArgs{ assert.CommitCount(1) assert.HeadCommitMessage(Equals(commitMessage)) assert.CurrentWindowName("stagingSecondary") + + // TODO: assert that the staging panel has been refreshed (it currently does not get correctly refreshed) }, }) diff --git a/pkg/integration/tests/commit/staged_without_hooks.go b/pkg/integration/tests/commit/staged_without_hooks.go index 5d8e400b9..bb0cba3c5 100644 --- a/pkg/integration/tests/commit/staged_without_hooks.go +++ b/pkg/integration/tests/commit/staged_without_hooks.go @@ -18,17 +18,38 @@ var StagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { assert.CommitCount(0) + // stage the file + assert.CurrentViewName("files") + assert.SelectedLine(Contains("myfile")) input.PrimaryAction() - input.Confirm() - input.PrimaryAction() - input.PressKeys(keys.Files.CommitChangesWithoutHook) + input.Enter() + assert.CurrentViewName("stagingSecondary") + // we start with both lines having been staged + assert.ViewContent("stagingSecondary", Contains("+myfile content")) + assert.ViewContent("stagingSecondary", Contains("+with a second line")) + assert.ViewContent("staging", NotContains("+myfile content")) + assert.ViewContent("staging", NotContains("+with a second line")) - commitMessage := "my commit message" + // unstage the selected line + input.PrimaryAction() + + // the line should have been moved to the main view + assert.ViewContent("stagingSecondary", NotContains("+myfile content")) + assert.ViewContent("stagingSecondary", Contains("+with a second line")) + assert.ViewContent("staging", Contains("+myfile content")) + assert.ViewContent("staging", NotContains("+with a second line")) + + input.Press(keys.Files.CommitChangesWithoutHook) + assert.InCommitMessagePanel() + assert.CurrentViewContent(Contains("WIP")) + commitMessage := ": my commit message" input.Type(commitMessage) input.Confirm() assert.CommitCount(1) assert.HeadCommitMessage(Equals("WIP" + commitMessage)) - assert.CurrentWindowName("stagingSecondary") + assert.CurrentViewName("stagingSecondary") + + // TODO: assert that the staging panel has been refreshed (it currently does not get correctly refreshed) }, }) diff --git a/pkg/integration/tests/commit/unstaged.go b/pkg/integration/tests/commit/unstaged.go index 50700fd4e..92be9615b 100644 --- a/pkg/integration/tests/commit/unstaged.go +++ b/pkg/integration/tests/commit/unstaged.go @@ -5,6 +5,8 @@ import ( . "github.com/jesseduffield/lazygit/pkg/integration/components" ) +// TODO: find out why we can't use assert.SelectedLine() on the staging/stagingSecondary views. + var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ Description: "Staging a couple files, going in the unstaged files menu, staging a line and committing", ExtraCmdArgs: "", @@ -18,10 +20,18 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { assert.CommitCount(0) - input.Confirm() + assert.CurrentViewName("files") + assert.SelectedLine(Contains("myfile")) + input.Enter() + assert.CurrentViewName("staging") + assert.ViewContent("stagingSecondary", NotContains("+myfile content")) + // stage the first line input.PrimaryAction() - input.PressKeys(keys.Files.CommitChanges) + assert.ViewContent("staging", NotContains("+myfile content")) + assert.ViewContent("stagingSecondary", Contains("+myfile content")) + input.Press(keys.Files.CommitChanges) + assert.InCommitMessagePanel() commitMessage := "my commit message" input.Type(commitMessage) input.Confirm() @@ -29,5 +39,7 @@ var Unstaged = NewIntegrationTest(NewIntegrationTestArgs{ assert.CommitCount(1) assert.HeadCommitMessage(Equals(commitMessage)) assert.CurrentWindowName("staging") + + // TODO: assert that the staging panel has been refreshed (it currently does not get correctly refreshed) }, }) diff --git a/pkg/integration/tests/commit/unstaged_without_hooks.go b/pkg/integration/tests/commit/unstaged_without_hooks.go deleted file mode 100644 index e2b5123a5..000000000 --- a/pkg/integration/tests/commit/unstaged_without_hooks.go +++ /dev/null @@ -1,33 +0,0 @@ -package commit - -import ( - "github.com/jesseduffield/lazygit/pkg/config" - . "github.com/jesseduffield/lazygit/pkg/integration/components" -) - -var UnstagedWithoutHooks = NewIntegrationTest(NewIntegrationTestArgs{ - Description: "Staging a couple files, going in the unstaged files menu, staging a line and committing without pre-commit hooks", - ExtraCmdArgs: "", - Skip: false, - SetupConfig: func(config *config.AppConfig) {}, - SetupRepo: func(shell *Shell) { - shell. - CreateFile("myfile", "myfile content\nwith a second line"). - CreateFile("myfile2", "myfile2 content") - }, - Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { - assert.CommitCount(0) - - input.Confirm() - input.PrimaryAction() - input.PressKeys(keys.Files.CommitChangesWithoutHook) - - commitMessage := "my commit message" - input.Type(commitMessage) - input.Confirm() - - assert.CommitCount(1) - assert.HeadCommitMessage(Equals("WIP" + commitMessage)) - assert.CurrentWindowName("staging") - }, -}) diff --git a/pkg/integration/tests/custom_commands/basic.go b/pkg/integration/tests/custom_commands/basic.go index 13dffb513..a97bdef4a 100644 --- a/pkg/integration/tests/custom_commands/basic.go +++ b/pkg/integration/tests/custom_commands/basic.go @@ -29,7 +29,7 @@ var Basic = NewIntegrationTest(NewIntegrationTestArgs{ ) { assert.WorkingTreeFileCount(0) - input.PressKeys("a") + input.Press("a") assert.WorkingTreeFileCount(1) assert.SelectedLine(Contains("myfile")) }, diff --git a/pkg/integration/tests/custom_commands/form_prompts.go b/pkg/integration/tests/custom_commands/form_prompts.go index 34970c21b..e0502fbae 100644 --- a/pkg/integration/tests/custom_commands/form_prompts.go +++ b/pkg/integration/tests/custom_commands/form_prompts.go @@ -63,23 +63,13 @@ var FormPrompts = NewIntegrationTest(NewIntegrationTestArgs{ ) { assert.WorkingTreeFileCount(0) - input.PressKeys("a") + input.Press("a") - assert.InPrompt() - assert.CurrentViewTitle(Equals("Enter a file name")) - input.Type("my file") - input.Confirm() + input.Prompt(Equals("Enter a file name"), "my file") - assert.InMenu() - assert.CurrentViewTitle(Equals("Choose file content")) - assert.SelectedLine(Contains("foo")) - input.NextItem() - assert.SelectedLine(Contains("bar")) - input.Confirm() + input.Menu(Equals("Choose file content"), Contains("bar")) - assert.InConfirm() - assert.CurrentViewTitle(Equals("Are you sure?")) - input.Confirm() + input.AcceptConfirmation(Equals("Are you sure?"), Equals("Are you REALLY sure you want to make this file? Up to you buddy.")) assert.WorkingTreeFileCount(1) assert.SelectedLine(Contains("my file")) diff --git a/pkg/integration/tests/custom_commands/menu_from_command.go b/pkg/integration/tests/custom_commands/menu_from_command.go index dd5d8324a..5d8fee71a 100644 --- a/pkg/integration/tests/custom_commands/menu_from_command.go +++ b/pkg/integration/tests/custom_commands/menu_from_command.go @@ -51,19 +51,11 @@ var MenuFromCommand = NewIntegrationTest(NewIntegrationTestArgs{ assert.WorkingTreeFileCount(0) input.SwitchToBranchesWindow() - input.PressKeys("a") + input.Press("a") - assert.InMenu() - assert.CurrentViewTitle(Equals("Choose commit message")) - assert.SelectedLine(Equals("baz")) - input.NextItem() - assert.SelectedLine(Equals("bar")) - input.Confirm() + input.Menu(Equals("Choose commit message"), Contains("bar")) - assert.InPrompt() - assert.CurrentViewTitle(Equals("Description")) - input.Type(" my branch") - input.Confirm() + input.Prompt(Equals("Description"), " my branch") input.SwitchToFilesWindow() diff --git a/pkg/integration/tests/custom_commands/menu_from_commands_output.go b/pkg/integration/tests/custom_commands/menu_from_commands_output.go index 8224f507b..1a7860ebb 100644 --- a/pkg/integration/tests/custom_commands/menu_from_commands_output.go +++ b/pkg/integration/tests/custom_commands/menu_from_commands_output.go @@ -47,22 +47,19 @@ var MenuFromCommandsOutput = NewIntegrationTest(NewIntegrationTestArgs{ assert *Assert, keys config.KeybindingConfig, ) { + assert.CurrentBranchName("feature/bar") + assert.WorkingTreeFileCount(0) input.SwitchToBranchesWindow() - input.PressKeys("a") + input.Press("a") assert.InPrompt() assert.CurrentViewTitle(Equals("Which git command do you want to run?")) assert.SelectedLine(Equals("branch")) input.Confirm() - assert.InMenu() - assert.CurrentViewTitle(Equals("Branch:")) - input.NextItem() - input.NextItem() - assert.SelectedLine(Equals("master")) - input.Confirm() + input.Menu(Equals("Branch:"), Equals("master")) assert.CurrentBranchName("master") }, diff --git a/pkg/integration/tests/custom_commands/multiple_prompts.go b/pkg/integration/tests/custom_commands/multiple_prompts.go index 4b520933e..5e6ebb6a2 100644 --- a/pkg/integration/tests/custom_commands/multiple_prompts.go +++ b/pkg/integration/tests/custom_commands/multiple_prompts.go @@ -61,23 +61,13 @@ var MultiplePrompts = NewIntegrationTest(NewIntegrationTestArgs{ ) { assert.WorkingTreeFileCount(0) - input.PressKeys("a") + input.Press("a") - assert.InPrompt() - assert.CurrentViewTitle(Equals("Enter a file name")) - input.Type("myfile") - input.Confirm() + input.Prompt(Equals("Enter a file name"), "myfile") - assert.InMenu() - assert.CurrentViewTitle(Equals("Choose file content")) - assert.SelectedLine(Contains("foo")) - input.NextItem() - assert.SelectedLine(Contains("bar")) - input.Confirm() + input.Menu(Equals("Choose file content"), Contains("bar")) - assert.InConfirm() - assert.CurrentViewTitle(Equals("Are you sure?")) - input.Confirm() + input.AcceptConfirmation(Equals("Are you sure?"), Equals("Are you REALLY sure you want to make this file? Up to you buddy.")) assert.WorkingTreeFileCount(1) assert.SelectedLine(Contains("myfile")) diff --git a/pkg/integration/tests/diff/diff.go b/pkg/integration/tests/diff/diff.go index bbb93335d..3e87c934b 100644 --- a/pkg/integration/tests/diff/diff.go +++ b/pkg/integration/tests/diff/diff.go @@ -26,11 +26,8 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ assert.CurrentViewName("localBranches") assert.SelectedLine(Contains("branch-a")) - input.PressKeys(keys.Universal.DiffingMenu) - assert.InMenu() - assert.CurrentViewTitle(Equals("Diffing")) - assert.SelectedLine(Contains("diff branch-a")) - input.Confirm() + input.Press(keys.Universal.DiffingMenu) + input.Menu(Equals("Diffing"), Contains(`diff branch-a`)) assert.CurrentViewName("localBranches") @@ -48,14 +45,12 @@ var Diff = NewIntegrationTest(NewIntegrationTestArgs{ assert.SelectedLine(Contains("file1")) assert.MainViewContent(Contains("+second line")) - input.PressKeys(keys.Universal.Return) - input.PressKeys(keys.Universal.Return) + input.Press(keys.Universal.Return) + input.Press(keys.Universal.Return) assert.CurrentViewName("localBranches") - input.PressKeys(keys.Universal.DiffingMenu) - assert.InMenu() - input.NavigateToListItemContainingText("reverse diff direction") - input.Confirm() + input.Press(keys.Universal.DiffingMenu) + input.Menu(Equals("Diffing"), Contains("reverse diff direction")) assert.ViewContent("information", Contains("showing output for: git diff branch-a branch-b -R")) assert.MainViewContent(Contains("-second line")) }, diff --git a/pkg/integration/tests/diff/diff_and_apply_patch.go b/pkg/integration/tests/diff/diff_and_apply_patch.go index 5efd795e2..a965fffd5 100644 --- a/pkg/integration/tests/diff/diff_and_apply_patch.go +++ b/pkg/integration/tests/diff/diff_and_apply_patch.go @@ -26,11 +26,9 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ assert.CurrentViewName("localBranches") assert.SelectedLine(Contains("branch-a")) - input.PressKeys(keys.Universal.DiffingMenu) - assert.InMenu() - assert.CurrentViewTitle(Equals("Diffing")) - assert.SelectedLine(Contains("diff branch-a")) - input.Confirm() + input.Press(keys.Universal.DiffingMenu) + + input.Menu(Equals("Diffing"), Equals("diff branch-a")) assert.CurrentViewName("localBranches") @@ -51,20 +49,14 @@ var DiffAndApplyPatch = NewIntegrationTest(NewIntegrationTestArgs{ // add the file to the patch input.PrimaryAction() - input.PressKeys(keys.Universal.DiffingMenu) - assert.InMenu() - assert.CurrentViewTitle(Equals("Diffing")) - input.NavigateToListItemContainingText("exit diff mode") - input.Confirm() + input.Press(keys.Universal.DiffingMenu) + input.Menu(Equals("Diffing"), Contains("exit diff mode")) assert.ViewContent("information", NotContains("building patch")) - input.PressKeys(keys.Universal.CreatePatchOptionsMenu) - assert.InMenu() - assert.CurrentViewTitle(Equals("Patch Options")) - // including the keybinding 'a' here to distinguish the menu item from the 'apply patch in reverse' item - input.NavigateToListItemContainingText("a apply patch") - input.Confirm() + input.Press(keys.Universal.CreatePatchOptionsMenu) + // adding the regex '$' here to distinguish the menu item from the 'apply patch in reverse' item + input.Menu(Equals("Patch Options"), MatchesRegexp("apply patch$")) input.SwitchToFilesWindow() diff --git a/pkg/integration/tests/diff/diff_commits.go b/pkg/integration/tests/diff/diff_commits.go index 7425d7592..2a2802ec8 100644 --- a/pkg/integration/tests/diff/diff_commits.go +++ b/pkg/integration/tests/diff/diff_commits.go @@ -24,11 +24,9 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ assert.SelectedLine(Contains("third commit")) - input.PressKeys(keys.Universal.DiffingMenu) - assert.InMenu() - assert.CurrentViewTitle(Equals("Diffing")) - assert.SelectedLine(Contains("diff")) - input.Confirm() + input.Press(keys.Universal.DiffingMenu) + input.Menu(Equals("Diffing"), MatchesRegexp(`diff \w+`)) + assert.NotInPopup() assert.ViewContent("information", Contains("showing output for: git diff")) @@ -40,10 +38,9 @@ var DiffCommits = NewIntegrationTest(NewIntegrationTestArgs{ assert.MainViewContent(Contains("-second line\n-third line")) - input.PressKeys(keys.Universal.DiffingMenu) - assert.InMenu() - input.NavigateToListItemContainingText("reverse diff direction") - input.Confirm() + input.Press(keys.Universal.DiffingMenu) + input.Menu(Equals("Diffing"), Contains("reverse diff direction")) + assert.NotInPopup() assert.MainViewContent(Contains("+second line\n+third line")) diff --git a/pkg/integration/tests/file/discard_changes.go b/pkg/integration/tests/file/discard_changes.go index ad931a26b..87e39e96b 100644 --- a/pkg/integration/tests/file/discard_changes.go +++ b/pkg/integration/tests/file/discard_changes.go @@ -75,47 +75,47 @@ var DiscardChanges = NewIntegrationTest(NewIntegrationTestArgs{ assert.CommitCount(3) type statusFile struct { - status string - path string + status string + label string + menuTitle string } discardOneByOne := func(files []statusFile) { for _, file := range files { - assert.SelectedLine(Contains(file.status + " " + file.path)) - input.PressKeys(keys.Universal.Remove) - assert.InMenu() - assert.CurrentViewContent(Contains("discard all changes")) - input.Confirm() + assert.SelectedLine(Contains(file.status + " " + file.label)) + input.Press(keys.Universal.Remove) + input.Menu(Equals(file.menuTitle), Contains("discard all changes")) } } discardOneByOne([]statusFile{ - {"UA", "added-them-changed-us.txt"}, - {"AA", "both-added.txt"}, - {"DD", "both-deleted.txt"}, - {"UU", "both-modded.txt"}, - {"AU", "changed-them-added-us.txt"}, - {"UD", "deleted-them.txt"}, - {"DU", "deleted-us.txt"}, + {status: "UA", label: "added-them-changed-us.txt", menuTitle: "added-them-changed-us.txt"}, + {status: "AA", label: "both-added.txt", menuTitle: "both-added.txt"}, + {status: "DD", label: "both-deleted.txt", menuTitle: "both-deleted.txt"}, + {status: "UU", label: "both-modded.txt", menuTitle: "both-modded.txt"}, + {status: "AU", label: "changed-them-added-us.txt", menuTitle: "changed-them-added-us.txt"}, + {status: "UD", label: "deleted-them.txt", menuTitle: "deleted-them.txt"}, + {status: "DU", label: "deleted-us.txt", menuTitle: "deleted-us.txt"}, }) assert.InConfirm() assert.CurrentViewTitle(Contains("continue")) assert.CurrentViewContent(Contains("all merge conflicts resolved. Continue?")) - input.PressKeys(keys.Universal.Return) + input.Press(keys.Universal.Return) discardOneByOne([]statusFile{ - {"MD", "change-delete.txt"}, - {"D ", "delete-change.txt"}, - {"D ", "deleted-staged.txt"}, - {" D", "deleted.txt"}, - {"MM", "double-modded.txt"}, - {"M ", "modded-staged.txt"}, - {" M", "modded.txt"}, - {"R ", "renamed.txt → renamed2.txt"}, - {"AM", "added-changed.txt"}, - {"A ", "new-staged.txt"}, - {"??", "new.txt"}, + {status: "MD", label: "change-delete.txt", menuTitle: "change-delete.txt"}, + {status: "D ", label: "delete-change.txt", menuTitle: "delete-change.txt"}, + {status: "D ", label: "deleted-staged.txt", menuTitle: "deleted-staged.txt"}, + {status: " D", label: "deleted.txt", menuTitle: "deleted.txt"}, + {status: "MM", label: "double-modded.txt", menuTitle: "double-modded.txt"}, + {status: "M ", label: "modded-staged.txt", menuTitle: "modded-staged.txt"}, + {status: " M", label: "modded.txt", menuTitle: "modded.txt"}, + // the menu title only includes the new file + {status: "R ", label: "renamed.txt → renamed2.txt", menuTitle: "renamed2.txt"}, + {status: "AM", label: "added-changed.txt", menuTitle: "added-changed.txt"}, + {status: "A ", label: "new-staged.txt", menuTitle: "new-staged.txt"}, + {status: "??", label: "new.txt", menuTitle: "new.txt"}, }) assert.WorkingTreeFileCount(0) diff --git a/pkg/integration/tests/interactive_rebase/amend_merge.go b/pkg/integration/tests/interactive_rebase/amend_merge.go index c71bb1c9d..92f9f26a6 100644 --- a/pkg/integration/tests/interactive_rebase/amend_merge.go +++ b/pkg/integration/tests/interactive_rebase/amend_merge.go @@ -36,8 +36,8 @@ var AmendMerge = NewIntegrationTest(NewIntegrationTestArgs{ mergeCommitMessage := "Merge branch 'feature-branch' into development-branch" assert.HeadCommitMessage(Contains(mergeCommitMessage)) - input.PressKeys(keys.Commits.AmendToCommit) - input.ProceedWhenAsked(Contains("Are you sure you want to amend this commit with your staged files?")) + input.Press(keys.Commits.AmendToCommit) + input.AcceptConfirmation(Equals("Amend Commit"), Contains("Are you sure you want to amend this commit with your staged files?")) // assuring we haven't added a brand new commit assert.CommitCount(3) diff --git a/pkg/integration/tests/interactive_rebase/one.go b/pkg/integration/tests/interactive_rebase/one.go index 4a8e697d9..d516087ff 100644 --- a/pkg/integration/tests/interactive_rebase/one.go +++ b/pkg/integration/tests/interactive_rebase/one.go @@ -18,20 +18,20 @@ var One = NewIntegrationTest(NewIntegrationTestArgs{ input.SwitchToCommitsWindow() assert.CurrentViewName("commits") - input.NavigateToListItemContainingText("commit 02") - input.PressKeys(keys.Universal.Edit) + input.NavigateToListItem(Contains("commit 02")) + input.Press(keys.Universal.Edit) assert.SelectedLine(Contains("YOU ARE HERE")) input.PreviousItem() - input.PressKeys(keys.Commits.MarkCommitAsFixup) + input.Press(keys.Commits.MarkCommitAsFixup) assert.SelectedLine(Contains("fixup")) input.PreviousItem() - input.PressKeys(keys.Universal.Remove) + input.Press(keys.Universal.Remove) assert.SelectedLine(Contains("drop")) input.PreviousItem() - input.PressKeys(keys.Commits.SquashDown) + input.Press(keys.Commits.SquashDown) assert.SelectedLine(Contains("squash")) input.ContinueRebase() diff --git a/pkg/integration/tests/misc/confirm_on_quit.go b/pkg/integration/tests/misc/confirm_on_quit.go index 134c2cab5..183f7dd0b 100644 --- a/pkg/integration/tests/misc/confirm_on_quit.go +++ b/pkg/integration/tests/misc/confirm_on_quit.go @@ -11,15 +11,12 @@ var ConfirmOnQuit = NewIntegrationTest(NewIntegrationTestArgs{ Skip: false, SetupConfig: func(config *config.AppConfig) { config.UserConfig.ConfirmOnQuit = true - config.UserConfig.Gui.Theme.ActiveBorderColor = []string{"red"} }, SetupRepo: func(shell *Shell) {}, Run: func(shell *Shell, input *Input, assert *Assert, keys config.KeybindingConfig) { assert.CommitCount(0) - input.PressKeys(keys.Universal.Quit) - assert.InConfirm() - assert.CurrentViewContent(Contains("Are you sure you want to quit?")) - input.Confirm() + input.Press(keys.Universal.Quit) + input.AcceptConfirmation(Equals(""), Contains("Are you sure you want to quit?")) }, }) diff --git a/pkg/integration/tests/stash/rename.go b/pkg/integration/tests/stash/rename.go index 3589c5a76..c325822e6 100644 --- a/pkg/integration/tests/stash/rename.go +++ b/pkg/integration/tests/stash/rename.go @@ -25,12 +25,9 @@ var Rename = NewIntegrationTest(NewIntegrationTestArgs{ assert.SelectedLine(Equals("On master: bar")) input.NextItem() assert.SelectedLine(Equals("On master: foo")) - input.PressKeys(keys.Stash.RenameStash) - assert.InPrompt() - assert.CurrentViewTitle(Equals("Rename stash: stash@{1}")) + input.Press(keys.Stash.RenameStash) - input.Type(" baz") - input.Confirm() + input.Prompt(Equals("Rename stash: stash@{1}"), " baz") assert.SelectedLine(Equals("On master: foo baz")) }, diff --git a/pkg/integration/tests/stash/stash.go b/pkg/integration/tests/stash/stash.go index 766469a70..23ff7e99d 100644 --- a/pkg/integration/tests/stash/stash.go +++ b/pkg/integration/tests/stash/stash.go @@ -19,15 +19,12 @@ var Stash = NewIntegrationTest(NewIntegrationTestArgs{ assert.StashCount(0) assert.WorkingTreeFileCount(1) - input.PressKeys(keys.Files.ViewStashOptions) - assert.InMenu() + input.Press(keys.Files.ViewStashOptions) - input.PressKeys("a") - assert.InPrompt() - assert.CurrentViewTitle(Equals("Stash changes")) + input.Menu(Equals("Stash options"), MatchesRegexp("stash all changes$")) + + input.Prompt(Equals("Stash changes"), "my stashed file") - input.Type("my stashed file") - input.Confirm() assert.StashCount(1) assert.WorkingTreeFileCount(0) }, diff --git a/pkg/integration/tests/stash/stash_including_untracked_files.go b/pkg/integration/tests/stash/stash_including_untracked_files.go index 998910f40..d193600df 100644 --- a/pkg/integration/tests/stash/stash_including_untracked_files.go +++ b/pkg/integration/tests/stash/stash_including_untracked_files.go @@ -20,15 +20,12 @@ var StashIncludingUntrackedFiles = NewIntegrationTest(NewIntegrationTestArgs{ assert.StashCount(0) assert.WorkingTreeFileCount(2) - input.PressKeys(keys.Files.ViewStashOptions) - assert.InMenu() + input.Press(keys.Files.ViewStashOptions) - input.PressKeys("U") - assert.InPrompt() - assert.CurrentViewTitle(Equals("Stash changes")) + input.Menu(Equals("Stash options"), Contains("stash all changes including untracked files")) + + input.Prompt(Equals("Stash changes"), "my stashed file") - input.Type("my stashed file") - input.Confirm() assert.StashCount(1) assert.WorkingTreeFileCount(0) }, diff --git a/pkg/integration/tests/tests.go b/pkg/integration/tests/tests.go index 6f7476657..d63b1aa50 100644 --- a/pkg/integration/tests/tests.go +++ b/pkg/integration/tests/tests.go @@ -45,7 +45,6 @@ var tests = []*components.IntegrationTest{ commit.Staged, commit.Unstaged, commit.StagedWithoutHooks, - commit.UnstagedWithoutHooks, custom_commands.Basic, custom_commands.FormPrompts, custom_commands.MenuFromCommand,